新闻  |   论坛  |   博客  |   在线研讨会
AVR笔记4:按键扫描+8种LED亮灭模式控制(GCC)
mayer | 2009-09-01 19:39:42    阅读:3328   发布文章

AVR笔记4:按键扫描+8种LED亮灭模式控制(GCC)

 

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

一、程序结构
程序结构

下载 (11.59 KB)
2009-7-23 20:48


二、仿真效果
点击看大图

下载 (173.51 KB)
2009-7-23 20:48



三、程序源码
1、main.c

  1. /*******************************************************************************
  2. Platform : AVR mega16学习板(www.iccavr.com)
  3. Project : 实验四:按键扫描+8种LED亮灭模式控制GCC
  4. Clock F : 3.6864M
  5. Software : WinAVR-20071221+Proteus7.4
  6. Author : 林夕依然
  7. Version : 08.11.22
  8. Updata : 09.02.25 模块化
  9. 09.04.30 增加proteus仿真模型,修改key_scan.c检测程序,仿真通过
  10. 09.07.21 WinAVR-20071221环境下编译通过
  11. comments :
  12. 1、以学习板八个LED灯和八个按键为硬件电路,JP7短路块需装上
  13. 2、AVR单片机端口寄存器的使用及理解
  14. 3、练习程序模块化,结构化的书写
  15. 4、端口电平检测程序的编写方法
  16. 5、8种LED点亮模式由对应的KEY键选择,同时按下多个键时,LED点亮模式不会循环进行,
  17. 详见仿真。原因为:尽管key_scan.c采用循环判断方式,但采用了状态处理程序
  18. 6、增加状态处理,防止运行选定LED模式序时按下其他按键
  19. 7、使用GCC delay.h头文件中延时函数,更换io头文件
  20. Problem :
  21. 1、ICC中DelayMs()函数在GCC中不可用,不知何因。
  22. *******************************************************************************/
  23. #include <avr/io.h>
  24. #include "port_init.h"
  25. #include "key_scan.h"
  26.  
  27. int main(void)
  28. {
  29. port_init();
  30. while (1)
  31. {
  32. key_scan();
  33. }
  34. //MCUCR=0x40; //空闲模式,CPU占用100%
  35. //MCUCR=0x50; //ADC噪声抑制模式,CPU占用100%
  36. //MCUCR=0x60; //掉电模式,CPU占用80%
  37. //MCUCR=0x70; //省电模式,CPU占用4%
  38. //MCUCR=0xE0; //Standby模式,CPU占用80%
  39. MCUCR=0xF0; //扩展Standby模式,CPU占用4%
  40. asm("sleep"); //CPU休眠指令
  41. }

2、key_scan.c

  1. #include <avr/io.h>
  2. #include "key_scan.h"
  3. #include "led.h"
  4.  
  5. /***键盘扫描函数***/
  6. void key_scan(void)
  7. {
  8. int l,m,n,o,p,q,r,s,i;
  9.  
  10. if((PINA&(1<<PA0))==0) //模式1:顺序点亮
  11. {
  12. PORTB=0XFF;
  13. for(l=0;l<5;l++)
  14. {
  15. for (i = 0; i < 8; i++) //顺序单个点亮LED
  16. LED_01(i);
  17. for (i = 6; i > 0; i--) //逆序单个点亮LED
  18. LED_01(i);
  19. }
  20. LED_off();//关闭LED
  21. while(PINA!=0XFF); //状态处理,防止运行此程序时按下其他按键
  22. }
  23.  
  24. if((PINA&(1<<PA1))==0) //模式2:顺序单个间隔点亮
  25. {
  26. PORTB=0XFF;
  27. for(m=0;m<5;m++)
  28. {
  29. for (i = 0; i < 8; i += 2) //顺序间隔点亮LED
  30. LED_01(i);
  31. for (i = 7; i > 0; i -= 2) //逆序间隔点亮LED
  32. LED_01(i);
  33. }
  34. LED_off();//关闭LED
  35. while(PINA!=0XFF); //状态处理,防止运行此程序时按下其他按键
  36. }
  37.  
  38. if((PINA&(1<<PA2))==0) //模式3:间隔点亮
  39. {
  40. PORTB=0XFF;
  41. for(n=0;n<5;n++)
  42. {
  43. for (i = 2; i < 8; i++) //间隔顺序同时点亮
  44. LED_02(i);
  45. for (i = 6; i > 2; i--) //间隔逆序同时点亮
  46. LED_02(i);
  47. }
  48. LED_off();//关闭LED
  49. while(PINA!=0XFF); //状态处理,防止运行此程序时按下其他按键
  50. }
  51.  
  52. if((PINA&(1<<PA3))==0) //模式4:相临点亮
  53. {
  54. PORTB=0XFF;
  55. for(o=0;o<5;o++)
  56. {
  57. for (i = 1; i < 8; i++) //相临顺序同时点亮
  58. LED_03(i);
  59. for (i = 6; i > 1; i--) //相临逆序同时点亮
  60. LED_03(i);
  61. }
  62. LED_off();//关闭LED
  63. while(PINA!=0XFF); //状态处理,防止运行此程序时按下其他按键
  64. }
  65.  
  66. if((PINA&(1<<PA4))==0) //模式5:发散聚集点亮
  67. {
  68. PORTB=0XFF;
  69. for(p=0;p<5;p++)
  70. {
  71. for(i=0;i<4;i++) //发散点亮
  72. LED_04(i);
  73. for(i=2;i>0;i--) //聚集点亮
  74. LED_04(i);
  75. }
  76. LED_off();//关闭LED
  77. while(PINA!=0XFF); //状态处理,防止运行此程序时按下其他按键
  78. }
  79.  
  80. if((PINA&(1<<PA5))==0) //模式6:四四点亮
  81. {
  82. PORTB=0XFF;
  83. for(q=0;q<5;q++)
  84. {
  85. for(i=0;i<4;i++) //四四顺序点亮
  86. LED_05(i);
  87. for(i=2;i>0;i--) //四四逆序点亮
  88. LED_05(i);
  89. }
  90. LED_off();//关闭LED
  91. while(PINA!=0XFF); //状态处理,防止运行此程序时按下其他按键
  92. }
  93.  
  94. if((PINA&(1<<PA6))==0) //模式7:四四点亮
  95. {
  96. PORTB=0XFF;
  97. for(r=0;r<5;r++)
  98. {
  99. for(i=0;i<2;i++) //四四顺序点亮
  100. LED_06(i);
  101. }
  102. LED_off();//关闭LED
  103. while(PINA!=0XFF); //状态处理,防止运行此程序时按下其他按键
  104. }
  105.  
  106. if((PINA&(1<<PA7))==0) //模式8:全部点亮熄灭
  107. {
  108. PORTB=0XFF;
  109. for(s=0;s<5;s++)
  110. {
  111. LED_on();
  112. LED_off();
  113. }
  114. LED_off();//关闭LED
  115. while(PINA!=0XFF); //状态处理,防止运行此程序时按下其他按键
  116. }
  117. }

3、led.c

  1. /*******************************
  2. Platform : AVR mega16学习板(www.iccavr.com)
  3. function :功能函数集
  4. Clock F : 3.6864M
  5. Software : WinAVR-20071221
  6. Author : 林夕依然
  7. Version : 09.07.20
  8. comments :
  9. ********************************/
  10. #include <avr/io.h>
  11. #include <util/delay.h>
  12. #include "led.h"
  13.  
  14. void LED_on(void) //打开所有LED
  15. {
  16. PORTB =0X00;
  17. _delay_ms(100);
  18. }
  19.  
  20. void LED_off(void) //关闭所有LED
  21. {
  22. PORTB = 0xFF;
  23. _delay_ms(100);
  24. }
  25.  
  26. void LED_01(int i) //LED亮灭控制
  27. {
  28. PORTB = ~_BV(i); //输出低电平
  29. _delay_ms(100); //调用延时程序
  30. }
  31.  
  32. void LED_02(int i) //间隔点亮
  33. {
  34. PORTB=~(_BV(i)|_BV(i-2));
  35. _delay_ms(100);
  36. }
  37.  
  38. void LED_03(int i) //相临点亮
  39. {
  40. PORTB=~(_BV(i)|_BV(i-1)); //~后内容需用括号括起来
  41. _delay_ms(100);
  42. }
  43.  
  44. void LED_04(int i) //发散聚集点亮
  45. {
  46. switch(i)
  47. {
  48. case 0:PORTB=0xE7;_delay_ms(100);break; //延时100ms
  49. case 1:PORTB=0xDB;_delay_ms(100);break;
  50. case 2:PORTB=0xBD;_delay_ms(100);break;
  51. case 3:PORTB=0x7E;_delay_ms(100);break;
  52. default:break;
  53. }
  54. }
  55.  
  56. void LED_05(int i) //00,0F,F0,FF方式显示
  57. {
  58. switch(i)
  59. {
  60. case 0:PORTB=0x00;_delay_ms(100);break; //延时100ms
  61. case 1:PORTB=0x0F;_delay_ms(100);break;
  62. case 2:PORTB=0xF0;_delay_ms(100);break;
  63. case 3:PORTB=0xFF;_delay_ms(100);break;
  64. default:break;
  65. }
  66. }
  67.  
  68. void LED_06(int i)
  69. {
  70. switch(i)
  71. {
  72. case 0:PORTB=0XAA;_delay_ms(100);break;
  73. case 1:PORTB=0X55;_delay_ms(100);break;
  74. }
  75. }

4、port_init.c

  1. #include <avr/io.h>
  2. #include "port_init.h"
  3.  
  4. /***端口初始化函数***/
  5. void port_init(void)
  6. {
  7. DDRA =0X00; //端口上拉输入
  8. PORTA=0XFF;
  9. DDRB =0xFF; //端口输出
  10. PORTB=0xFF; //输出高电平,LED熄灭
  11. DDRC =0X00;
  12. PORTC=0XFF;
  13. DDRD =0X00;
  14. PORTD=0XFF;
  15. }

5、key_scan.h

  1. void key_scan(void);

6、led.h

  1. void LED_on(void);
  2. void LED_off(void);
  3. void LED_01(int i);
  4. void LED_02(int i);
  5. void LED_03(int i);
  6. void LED_04(int i);
  7. void LED_05(int i);
  8. void LED_06(int i);

7、port_init.h

  1. void port_init(void);

四、完整项目文件下载
http://bbs.armavr.com/thread-796-1-2.html

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

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