(一)51单片机之红绿灯
1.首先贴上proteus的仿真图:
2.代码分为四个部分,中断初始化、数码管显示、红绿黄灯时间切换、红绿黄灯状态显示:
(1)中断初始化:
定时器工作方式采用定时器0工作方式1,50ms定时器触发一次,贴上代码如下:
g=0,x=0; //显示计时初始化
TMOD=0X01; //定时器0工作方式1
TH0=(65536-50000)/256; //(65536-50000)/256; //撞入晶振为12的初值,定50ms为50000
TL0=(65536-50000)%256; //(65536-50000)%256; //记满后向THO进一位
EA=1; //开总中断
ET0=1; //开定时器0中断
TR0=1; //定时器0运行
(2)数码管显示:
采用共阳极数码管显示,首先先定义0~9的数码管数字显示的数组如下:
uchar code duan[10]={0xc0,0xf9,0xa4,0xb0,0x99,
0x92,0x82,0xf8,0x80,0x90}; //0-9共阳
数码管位选选取P2^0、P2^1两个引脚,段选采用整个P0口,接仿真时记得接上拉电阻:
void display() //数码管显示
{
ji(); //红绿黄灯时间切换函数
//个位
P2=0x01; //端口位置16进制
P0=duan[g];
delay(1);
P0=0Xff; //使P0端口电位置0
//十位
P2=0x02;
P0=duan[x];
delay(1);
P0=0Xff;
}
(3)红绿黄灯时间切换:
if(flag_yellow==1&&t==5) //黄灯闪烁必须放这里
{
led_yellow =~ led_yellow;
}
if(t==20) //一秒时间到
{
t=0;
q++;
num=max_num- q%max_num; //实现倒计时
if(num==max_num &&flag_red==1)
{
TR0=0;
q=1;
num=20;
flag_green=1;
flag_red=0;
max_num=21; //绿灯20秒
TR0=1;
}
if(num==21 &&flag_green==1)
{
TR0=0;
q=1;
num=5;
flag_yellow=1;
flag_green=0;
max_num=6; //黄灯5秒
TR0=1;
}
if(num==6 &&flag_yellow==1)
{
TR0=0;
q=0;
num=25;
flag_red=1;
flag_yellow=0;
max_num=25; //
TR0=1;
}
}
x=num/10;
g=num%10;
//个和十用秒计时
这里每隔1秒进来判断一次,红绿黄灯计时时间因为循环要一直接执行下去,所以必须首尾相连,互相清除标志和赋值,防止判断错误,程序计混乱,最后的g和x分别代表的是计时时间的个位和十位,利用g和x的计算,去调用相对应时间数码管显示的数组的地址,从而达到对应显示的目的。
(4)红绿黄灯状态显示:
其中黄灯显示在第三个部分中
if(flag_red==1)
{
led_yellow=1;
led_red=0;
}
else if(flag_green==1)
{
led_red=1;
led_green=0;
}
else if(flag_yellow==1)
{
led_green=1;
}