概要
用一个按键控制8个LED灯的闪烁,每次在按键按下四次后8个LED每隔0.5秒闪烁十次(4个LED亮4个LED灭),然后全部熄灭。下一次再按下四次按键后,LED再闪烁十次,如此重复。按键控制和0.5秒间隔控制,请用定时计数器中断方式进行,可不考虑按键抖动,时钟频率为12MHz。
请用PROTEUS绘制原理图,编写程序,给出程序和运行截图。
代码
提示:这里可以添加技术名词解释
#include <REGX52.H>
#include <intrins.h>
#define u8 unsigned char //定义字符类型
#define u16 unsigned int
#define led P2 //定义IO口P2为led
#define led_out 0xAA
u8 x = led_out;
u8 state = 0;
bit flag = 0;
void Delay(u16 xms)
{
unsigned char i, j;
while(xms--)
{
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
}
}
void init()//初始化,即打开各中断开关
{
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x01; //设置定时器模式
TH0=0xFC; //定时器0装初值
TL0=0x18; //同上
IT0=1;//外部中断0为跳变沿触发方式
EA=1;//开总中断
EX0=1;//打开外部中断0
TR0=1;//打开定时器0运行开关
IP=0x01;//设置int0优先级为高,与PX0=1;等效
}
void int0() interrupt 0 //外部中断0的执行程序。
{
switch(state)
{
case 0: if(!P3^2){ flag = 0; state = 2;}else{flag = 0; state = 0;} break;
case 1: if(!P3^2){ flag = 0; state = 2;}else{flag = 0; state = 1;} break;
case 2: if(!P3^2){ flag = 0; state = 3;}else{flag = 0; state = 2;} break;
case 3: if(!P3^2){ flag = 0; state = 4;ET0=1;x = led_out;}else{flag = 0; state = 3;} break;
//状态3打开定时器中断 led灯初始化
case 4: if(!P3^2){ flag = 1; state = 1;}else{flag = 0; state = 4;} break;
//状态4,标志位拉高
}
}
void t0() interrupt 1 //定时器
{
static unsigned int T0Count1,T0Count2;
TH0=0xFC; //定时器0装初值
TL0=0x18; //同上
T0Count1++; //记录定时器经过的时间
T0Count2++;
if(T0Count1 >= 500) //每0.5S闪烁一次
{
x = _crol_(x,1); //每0.5S位移一次,实现0.5S闪烁1次
T0Count1 = 0;
}else
{
x = x;
}
if(T0Count2 >= 10000) //5S闪烁10次
{
x = 0xff; //熄灭LED灯
T0Count2 = 0;
ET0 = 0; //关闭中断
}
}
void main()//主函数
{
init(); //初始化
while(1)
{
if(flag) //标志信号位高电平时,点亮led灯
{
led = x;
}
else
led = 0xff;
}
}
PROTEUS仿真
提示:这里可以添加技术细节
例如:
小结
小作业