新闻  |   论坛  |   博客  |   在线研讨会
AVR笔记13:SPI实验(数码管显示INT0次数)(GCC)
mayer | 2009-09-01 19:08:47    阅读:2244   发布文章

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

 

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

一、程序结构
程序结构

下载 (6.74 KB)
2009-8-11 10:38



二、仿真效果
点击看大图

下载 (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.  
  25. uchar IntCnt = 0; //记录中断次数
  26. uchar disp[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};
  27.  
  28. ISR(INT0_vect)
  29. {
  30. IntCnt++;
  31. }
  32.  
  33. /*-----------------------------------------------------------------
  34. 函数名称: void InitDevices(void)
  35. 函数功能: 初始化各种信息
  36. 参 数:
  37. 返 回 值: 无
  38. -----------------------------------------------------------------*/
  39. void InitDevices(void)
  40. {
  41. cli(); //关全部中断
  42. SPIMasterInit(); //SPI初始化为主机
  43.  
  44. MCUCR = 0x02; //中断0,下降沿触发
  45. GICR = 0x40; //开中断0,
  46. sei(); //开中断
  47. }
  48.  
  49. int main(void)
  50. {
  51. uchar temp;
  52. port_init();
  53. InitDevices();
  54. while (1)
  55. {
  56. if( IntCnt > 9) //显示十位和百位
  57. {
  58. if( IntCnt > 99) //三位显示情况
  59. {
  60. DDRB = 0xff;
  61. PORTB = 0xff; //关显示
  62. temp = IntCnt / 100; //取百位
  63. SPI595Out(disp[temp]);
  64. PORTB = 0xfb; //将百位显示在右数第3个数码管上
  65. _delay_ms(1); //显示1ms,此时间决定百位十位显示频率
  66. PORTB = 0xff; //关显示
  67. temp = IntCnt%100/10; //取十位
  68. SPI595Out(disp[temp]);
  69. PORTB = 0xfd; //将十位显示在右数第2个数码管上
  70. _delay_ms(1); //显示1ms,此时间决定十位个位显示频率
  71. PORTB = 0xff; //关显示
  72. temp = IntCnt%10; //取个位
  73. SPI595Out(disp[temp]);
  74. PORTB = 0xfe; //在右数第1个数码管上显示个位
  75. }
  76. else //两位显示情况
  77. {
  78. DDRB = 0xff;
  79. PORTB = 0xff; //关显示
  80. temp = IntCnt/10; //取十位
  81. SPI595Out(disp[temp]);
  82. PORTB = 0xfd; //将十位显示在右数第2个数码管上
  83. _delay_ms(1); //显示时1ms,此时间决定十位个位显示频率
  84. PORTB = 0xff; //关显示
  85. temp = IntCnt%10; //取个位
  86. SPI595Out(disp[temp]);
  87. PORTB = 0xfe; //在右数第1个数码管上显示个位
  88. }
  89. }
  90. else //一位显示情况
  91. {
  92. DDRB = 0xff;
  93. PORTB = 0xfe; //只有一位数码管点亮
  94. SPI595Out(disp[IntCnt]);
  95. }
  96. _delay_ms(1);
  97. }
  98. }

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.  
  50. void port_init(void)
  51. {
  52. DDRA = 0x00; //方向输入
  53. PORTA = 0xFF; //打开上拉
  54. DDRB = 0xFF; //方向输出
  55. PORTB = 0xF0; //电平设置,MISO输出高电平,关闭595移位寄存器的数据清零功能
  56. DDRC = 0x00;
  57. PORTC = 0xFF;
  58. DDRD = 0xFF;
  59. PORTD = 0xFF;
  60. }

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

*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。

参与讨论
登录后参与讨论
推荐文章
最近访客