原创 AVR笔记13:SPI实验(数码管显示INT0次数)(GCC)

2009-9-1 16:33 3578 5 5 分类: MCU/ 嵌入式

》》点此进入    http://bbs.armavr.com/   ARM-AVR嵌入式开发论坛


一、程序结构
attachimg.gif 程序结构


下载 (6.74 KB)

2009-8-11 10:38



二、仿真效果
attachimg.gif 点击看大图


下载 (213.81 KB)

2009-8-11 10:38



三、程序源码
1、main.c





  1. /*******************************************************************************

  2. Platform: AVR mega16学习板(www.iccavr.com)

  3. Project : 实验十三:SPI实验(数码管显示INT0次数)(GCC)

  4. Clock F : 3.6864M

  5. Software: WinAVR-20090313+Proteus7.4

  6. Author : 林夕依然

  7. Version : 08.12.10

  8. Updata : 09.03.10 模块化

  9. 09.05.04 增加proteus仿真模型,仿真未通过,详见仿真模型。

  10. 09.07.24 WinAVR-20090313调试通过

  11. comments:

  12. 1、以学习板4位数码管和INT0键为硬件电路

  13. 2、练习SPI的配置和使用

  14. 3、学习74HC595八位移位寄存器芯片的使用

  15. 4、理解数据显示取位方式(个,十,百位的算法)

  16. 5、进行此实验请插上JP1的所有8个短路块,JP6(SPI_EN)短路块。

  17. 6、参考:...mcu\ICCAVR学习板\旧版例程\M16学习板实验程序\5-中断实验

  18. *******************************************************************************/

  19. #include <avr/io.h>

  20. #include <util/delay.h>

  21. #include <avr/interrupt.h>

  22. #include "spi.h"

  23. #define uchar unsigned char



  24. uchar IntCnt = 0; //记录中断次数

  25. uchar disp[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};



  26. ISR(INT0_vect)

  27. {

  28. IntCnt++;

  29. }



  30. /*-----------------------------------------------------------------

  31. 函数名称: void InitDevices(void)

  32. 函数功能: 初始化各种信息

  33. 参 数:

  34. 返 回 值: 无

  35. -----------------------------------------------------------------*/

  36. void InitDevices(void)

  37. {

  38. cli(); //关全部中断

  39. SPIMasterInit(); //SPI初始化为主机



  40. MCUCR = 0x02; //中断0,下降沿触发

  41. GICR = 0x40; //开中断0,

  42. sei(); //开中断

  43. }



  44. int main(void)

  45. {

  46. uchar temp;

  47. port_init();

  48. InitDevices();

  49. while (1)

  50. {

  51. if( IntCnt > 9) //显示十位和百位

  52. {

  53. if( IntCnt > 99) //三位显示情况

  54. {

  55. DDRB = 0xff;

  56. PORTB = 0xff; //关显示

  57. temp = IntCnt / 100; //取百位

  58. SPI595Out(disp[temp]);

  59. PORTB = 0xfb; //将百位显示在右数第3个数码管上

  60. _delay_ms(1); //显示1ms,此时间决定百位十位显示频率

  61. PORTB = 0xff; //关显示

  62. temp = IntCnt%100/10; //取十位

  63. SPI595Out(disp[temp]);

  64. PORTB = 0xfd; //将十位显示在右数第2个数码管上

  65. _delay_ms(1); //显示1ms,此时间决定十位个位显示频率

  66. PORTB = 0xff; //关显示

  67. temp = IntCnt%10; //取个位

  68. SPI595Out(disp[temp]);

  69. PORTB = 0xfe; //在右数第1个数码管上显示个位

  70. }

  71. else //两位显示情况

  72. {

  73. DDRB = 0xff;

  74. PORTB = 0xff; //关显示

  75. temp = IntCnt/10; //取十位

  76. SPI595Out(disp[temp]);

  77. PORTB = 0xfd; //将十位显示在右数第2个数码管上

  78. _delay_ms(1); //显示时1ms,此时间决定十位个位显示频率

  79. PORTB = 0xff; //关显示

  80. temp = IntCnt%10; //取个位

  81. SPI595Out(disp[temp]);

  82. PORTB = 0xfe; //在右数第1个数码管上显示个位

  83. }

  84. }

  85. else //一位显示情况

  86. {

  87. DDRB = 0xff;

  88. PORTB = 0xfe; //只有一位数码管点亮

  89. SPI595Out(disp[IntCnt]);

  90. }

  91. _delay_ms(1);

  92. }

  93. }

2、spi.c





  1. #include <avr/io.h>

  2. #define uchar unsigned char

  3. /*-----------------------------------------------------------------

  4. 函数名称: void SPIMasterInit(void)

  5. 函数功能: SPI初始化为主机

  6. 参 数:

  7. 返 回 值: 无

  8. -----------------------------------------------------------------*/

  9. void SPIMasterInit(void)

  10. {

  11. // MOSI,MISO,SCK等都需要设计的数据方向定义

  12. DDRB |= (1<<PB5) | (1<<PB7); // 设置MOSI 和SCK 为输出,其他为输入 M16

  13. // DDRB |= (1<<PB2) | (1<<PB3); // 设置MOSI 和SCK 为输出,其他为输入 M64

  14. // SPI控制寄存器

  15. // SPIE SPE DORD MSTR CPOL CPHA SPR1 SPR0

  16. // SPIE 中断使能 SPE SPI使能 DORD 数据次序 1为LSB首先发送,0为MSB首先发送

  17. // MSTR 主从选择 1为主,0为从MSTR置位时选择主机模式,否则为从机.如果MSTR为"1",

  18. // SS配置为输入,但被拉低,则MSTR 被清零,寄存器SPSR 的SPIF 置位.用户必须重新设置

  19. // MSTR 进入主机模式。

  20. // CPOL: 时钟极性见ATMEGA16L(中文)P130

  21. // CPHA: 时钟相位

  22. // SPR1, SPR0: SPI 时钟速率选择1 与0 SPR1 和SPR0 对从机没有影响。

  23. // 使能SPI 主机模式,设置时钟速率为fck/128 */

  24. SPCR = (1<<SPE) | (1<<MSTR) | (1<<SPR1) | (1<<SPR0);

  25. }

  26. /*-----------------------------------------------------------------

  27. 函数名称: void SPIMasterTransmit(unsigned char i)

  28. 函数功能: SPI数据发送

  29. 参 数:

  30. 返 回 值: 无

  31. -----------------------------------------------------------------*/

  32. void SPIMasterTransmit(uchar TranData)

  33. {

  34. SPDR = TranData; // 启动数据传输

  35. while (!(SPSR & (1<<SPIF))); // 等待传输结束

  36. }

  37. /*-----------------------------------------------------------------

  38. 函数名称: void SPI595Out(unsigned char i)

  39. 函数功能: 通过74HC595输出数据

  40. 参 数:

  41. 返 回 值: 无

  42. -----------------------------------------------------------------*/

  43. void SPI595Out(uchar i)

  44. {

  45. PORTB&=~(1<<4); //等待数据传输,595存储寄存器数据不变

  46. SPIMasterTransmit(i); //传输数据

  47. PORTB|=(1<<4); //595移位寄存器的数据进入数据存储寄存器,并在数码管上显示

  48. }



  49. void port_init(void)

  50. {

  51. DDRA = 0x00; //方向输入

  52. PORTA = 0xFF; //打开上拉

  53. DDRB = 0xFF; //方向输出

  54. PORTB = 0xF0; //电平设置,MISO输出高电平,关闭595移位寄存器的数据清零功能

  55. DDRC = 0x00;

  56. PORTC = 0xFF;

  57. DDRD = 0xFF;

  58. PORTD = 0xFF;

  59. }

3、spi.h





  1. #define uchar unsigned char

  2. void SPIMasterInit(void);

  3. void SPIMasterTransmit(uchar TranData);

  4. void SPI595Out(uchar i);

  5. void port_init(void);

四、完整项目文件下载


http://bbs.armavr.com/thread-915-1-3.html

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
5
关闭 站长推荐上一条 /3 下一条