返回列表 回复 发帖 免费斗地主赢30元充值卡

[林夕依然] 实验4:按键扫描+8种LED亮灭模式控制(ICC)

相关搜索: 例程
一、程序结构
硬件结构.jpg
2009-7-24 10:31


二、仿真效果
实验4.jpg
2009-4-30 17:54


三、程序源码
1、main.c
  1. /*******************************************************************************
  2. Platform : AVR mega16学习板(www.iccavr.com)
  3. Project : 实验四:按键扫描+8种LED亮灭模式控制
  4. Clock F : 3.6864M
  5. Software : ICCAVR7.14C
  6. Author : 林夕依然
  7. Version : 08.11.22
  8. Updata : 09.02.25 模块化
  9. 09.04.30 增加proteus仿真模型,修改key_scan.c检测程序,仿真通过
  10. comments :
  11. 1、以学习板八个LED灯和八个按键为硬件电路,JP7短路块需装上
  12. 2、AVR单片机端口寄存器的使用及理解
  13. 3、练习程序模块化,结构化的书写
  14. 4、端口电平检测程序的编写方法
  15. 5、8种LED点亮模式由对应的KEY键选择,同时按下多个键时,LED点亮模式不会循环进行,
  16. 详见仿真。原因为:尽管key_scan.c采用循环判断方式,但采用了状态处理程序
  17. 6、增加状态处理,防止运行选定LED模式序时按下其他按键
  18. Problem :
  19. 1、当前模式运行时切换其他模式时必须先复位,否则不能实现切换,考虑自动切换实现方法
  20. 解决方法:更改key_scan.c检测程序,使用for循环,不用while(1)无限循环。
  21. *******************************************************************************/
  22. #include <iom16v.h>
  23. #include <macros.h>

  24. void main()
  25. {
  26. port_init();
  27. while (1)
  28. {
  29. key_scan();
  30. }
  31. //MCUCR=0x40; //空闲模式,CPU占用100%
  32. //MCUCR=0x50; //ADC噪声抑制模式,CPU占用100%
  33. //MCUCR=0x60; //掉电模式,CPU占用80%
  34. //MCUCR=0x70; //省电模式,CPU占用4%
  35. //MCUCR=0xE0; //Standby模式,CPU占用80%
  36. MCUCR=0xF0; //扩展Standby模式,CPU占用4%
  37. asm("sleep"); //CPU休眠指令
  38. }
复制代码


2、key_scan.c
  1. #include <iom16v.h>
  2. #include <macros.h>
  3. /***键盘扫描函数***/
  4. void key_scan()
  5. {   
  6.     int l,m,n,o,p,q,r,s,i;

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

3、led.c
  1. /*******************************
  2. Platform : AVR mega16学习板(www.iccavr.com)
  3. function :功能函数集
  4. Clock F : 3.6864M
  5. Software : ICCAVR7.14C
  6. Author : 林夕依然
  7. Version : 09.02.25
  8. comments :
  9. ********************************/
  10. #include <iom16v.h>
  11. #include <macros.h>
  12. void LED_on() //打开所有LED
  13. {
  14. PORTB =0X00;
  15. DelayMs(100);
  16. }

  17. void LED_off() //关闭所有LED
  18. {
  19. PORTB = 0xFF;
  20. DelayMs(100);
  21. }
  22. void LED_01(int i) //LED亮灭控制
  23. {
  24. PORTB = ~BIT(i); //输出低电平
  25. DelayMs(100); //调用延时程序
  26. }

  27. void LED_02(int i) //间隔点亮
  28. {
  29. PORTB=~(BIT(i)|BIT(i-2));
  30. DelayMs(100);
  31. }

  32. void LED_03(int i) //相临点亮
  33. {
  34. PORTB=~(BIT(i)|BIT(i-1)); //~后内容需用括号括起来
  35. DelayMs(100);
  36. }

  37. void LED_04(int i) //发散聚集点亮
  38. {
  39. switch(i)
  40. {
  41. case 0:PORTB=0xE7;DelayMs(100);break; //延时100ms
  42. case 1:PORTB=0xDB;DelayMs(100);break;
  43. case 2:PORTB=0xBD;DelayMs(100);break;
  44. case 3:PORTB=0x7E;DelayMs(100);break;
  45. default:break;
  46. }
  47. }

  48. void LED_05(int i) //00,0F,F0,FF方式显示
  49. {
  50. switch(i)
  51. {
  52. case 0:PORTB=0x00;DelayMs(100);break; //延时100ms
  53. case 1:PORTB=0x0F;DelayMs(100);break;
  54. case 2:PORTB=0xF0;DelayMs(100);break;
  55. case 3:PORTB=0xFF;DelayMs(100);break;
  56. default:break;
  57. }
  58. }

  59. void LED_06(int i)
  60. {
  61. switch(i)
  62. {
  63. case 0:PORTB=0XAA;DelayMs(100);break;
  64. case 1:PORTB=0X55;DelayMs(100);break;
  65. }
  66. }
复制代码
4、port_init.c
  1. #include <iom16v.h>
  2. #include <macros.h>
  3. /***端口初始化函数***/
  4. void port_init()
  5. {
  6. DDRA =0X00; //端口上拉输入
  7. PORTA=0XFF;
  8. DDRB =0xFF; //端口输出
  9. PORTB=0xFF; //输出高电平,LED熄灭
  10. DDRC =0X00;
  11. PORTC=0XFF;
  12. DDRD =0X00;
  13. PORTD=0XFF;
  14. }
复制代码
5、delay.c
  1. /*******************************
  2. Platform : AVR mega16学习板(www.iccavr.com)
  3. function :延时函数
  4. Clock F : 3.6864M
  5. Software : ICCAVR7.14C
  6. Author : 林夕依然
  7. Version : 09.02.25
  8. comments :
  9. 1、两种方式实现延时
  10. ********************************/
  11. /*---------------------------------------------------------------------------------
  12. 延时程序计算方法
  13. 计数个数j = 延时时间/6*晶振频率 - 1
  14. ---------------------------------------------------------------------------------*/
  15. #define uchar unsigned char
  16. #define uint unsigned int

  17. //方式一:
  18. void Delay()
  19. {
  20. uchar a, b, c;
  21. for (a = 1; a; a++)
  22. for (b = 1; b; b++)
  23. for (c = 0; c<10; c++) //循环次数=255*255*10
  24. ;
  25. }

  26. //方式二:1ms延时,准确性较Delay();高
  27. void DelayMs(uint i)
  28. {
  29. while(i--)
  30. {
  31. uint j;
  32. for(j=1;j<=613;j++)
  33. ;
  34. }
  35. }
复制代码
四、完整项目文件下载
实验4完整项目文件及proteus模型.rar (69.33 KB)
面对人生,既要有当机立断的决心,更要有永不后悔的气魄!
****************************************************************
期待你和论坛一起成长、进步!

面对人生,既要有当机立断的决心,更要有永不后悔的气魄!

面对人生,既要有当机立断的决心,更要有永不后悔的气魄!
看看 正在学这个呢 哈哈
看看 正在学这个呢 哈哈
提示: 作者被禁止或删除 内容自动屏蔽
看看 正在学
不错。谢谢楼主提供
学习中……  支持!顶起来
正有用,学习中!!
好资料,谢谢楼主分享
Forge ahead! Never retreat!
呵呵,看看了,谢谢
好资料,谢谢楼主分享
看看 正在学这个呢 哈哈
真是好东东,谢谢 1# linxiyiran
楼主太强了 佩服向你学习
看看 正在学这个呢 哈哈
看看 正在学这个呢 哈哈
实验4:按键扫描+8种LED亮灭模式控制(ICC)
非常感谢!!!!!
学习中!!!!!!!!!!!!
返回列表
Datasheet