一、程序结构
二、仿真效果
三、程序源码
1、main.c- /*******************************************************************************
- Platform : AVR mega16学习板(www.iccavr.com)
- Project : 实验四:按键扫描+8种LED亮灭模式控制
- Clock F : 3.6864M
- Software : ICCAVR7.14C
- Author : 林夕依然
- Version : 08.11.22
- Updata : 09.02.25 模块化
- 09.04.30 增加proteus仿真模型,修改key_scan.c检测程序,仿真通过
- comments :
- 1、以学习板八个LED灯和八个按键为硬件电路,JP7短路块需装上
- 2、AVR单片机端口寄存器的使用及理解
- 3、练习程序模块化,结构化的书写
- 4、端口电平检测程序的编写方法
- 5、8种LED点亮模式由对应的KEY键选择,同时按下多个键时,LED点亮模式不会循环进行,
- 详见仿真。原因为:尽管key_scan.c采用循环判断方式,但采用了状态处理程序
- 6、增加状态处理,防止运行选定LED模式序时按下其他按键
- Problem :
- 1、当前模式运行时切换其他模式时必须先复位,否则不能实现切换,考虑自动切换实现方法
- 解决方法:更改key_scan.c检测程序,使用for循环,不用while(1)无限循环。
- *******************************************************************************/
- #include <iom16v.h>
- #include <macros.h>
- void main()
- {
- port_init();
- while (1)
- {
- key_scan();
- }
- //MCUCR=0x40; //空闲模式,CPU占用100%
- //MCUCR=0x50; //ADC噪声抑制模式,CPU占用100%
- //MCUCR=0x60; //掉电模式,CPU占用80%
- //MCUCR=0x70; //省电模式,CPU占用4%
- //MCUCR=0xE0; //Standby模式,CPU占用80%
- MCUCR=0xF0; //扩展Standby模式,CPU占用4%
- asm("sleep"); //CPU休眠指令
- }
复制代码
2、key_scan.c
3、led.c- /*******************************
- Platform : AVR mega16学习板(www.iccavr.com)
- function :功能函数集
- Clock F : 3.6864M
- Software : ICCAVR7.14C
- Author : 林夕依然
- Version : 09.02.25
- comments :
- ********************************/
- #include <iom16v.h>
- #include <macros.h>
- void LED_on() //打开所有LED
- {
- PORTB =0X00;
- DelayMs(100);
- }
- void LED_off() //关闭所有LED
- {
- PORTB = 0xFF;
- DelayMs(100);
- }
- void LED_01(int i) //LED亮灭控制
- {
- PORTB = ~BIT(i); //输出低电平
- DelayMs(100); //调用延时程序
- }
- void LED_02(int i) //间隔点亮
- {
- PORTB=~(BIT(i)|BIT(i-2));
- DelayMs(100);
- }
- void LED_03(int i) //相临点亮
- {
- PORTB=~(BIT(i)|BIT(i-1)); //~后内容需用括号括起来
- DelayMs(100);
- }
- void LED_04(int i) //发散聚集点亮
- {
- switch(i)
- {
- case 0:PORTB=0xE7;DelayMs(100);break; //延时100ms
- case 1:PORTB=0xDB;DelayMs(100);break;
- case 2:PORTB=0xBD;DelayMs(100);break;
- case 3:PORTB=0x7E;DelayMs(100);break;
- default:break;
- }
- }
- void LED_05(int i) //00,0F,F0,FF方式显示
- {
- switch(i)
- {
- case 0:PORTB=0x00;DelayMs(100);break; //延时100ms
- case 1:PORTB=0x0F;DelayMs(100);break;
- case 2:PORTB=0xF0;DelayMs(100);break;
- case 3:PORTB=0xFF;DelayMs(100);break;
- default:break;
- }
- }
- void LED_06(int i)
- {
- switch(i)
- {
- case 0:PORTB=0XAA;DelayMs(100);break;
- case 1:PORTB=0X55;DelayMs(100);break;
- }
- }
复制代码 4、port_init.c- #include <iom16v.h>
- #include <macros.h>
- /***端口初始化函数***/
- void port_init()
- {
- DDRA =0X00; //端口上拉输入
- PORTA=0XFF;
- DDRB =0xFF; //端口输出
- PORTB=0xFF; //输出高电平,LED熄灭
- DDRC =0X00;
- PORTC=0XFF;
- DDRD =0X00;
- PORTD=0XFF;
- }
复制代码 5、delay.c- /*******************************
- Platform : AVR mega16学习板(www.iccavr.com)
- function :延时函数
- Clock F : 3.6864M
- Software : ICCAVR7.14C
- Author : 林夕依然
- Version : 09.02.25
- comments :
- 1、两种方式实现延时
- ********************************/
- /*---------------------------------------------------------------------------------
- 延时程序计算方法
- 计数个数j = 延时时间/6*晶振频率 - 1
- ---------------------------------------------------------------------------------*/
- #define uchar unsigned char
- #define uint unsigned int
- //方式一:
- void Delay()
- {
- uchar a, b, c;
- for (a = 1; a; a++)
- for (b = 1; b; b++)
- for (c = 0; c<10; c++) //循环次数=255*255*10
- ;
- }
- //方式二:1ms延时,准确性较Delay();高
- void DelayMs(uint i)
- {
- while(i--)
- {
- uint j;
- for(j=1;j<=613;j++)
- ;
- }
- }
复制代码 四、完整项目文件下载
实验4完整项目文件及proteus模型.rar (69.33 KB)
|