基于51单片机的红绿灯实现(使用普中科技开发板)
C语言基础比较薄弱,红绿灯的倒计时和切换上,用了三个if()嵌套,总感觉应该有更好的方案,如果你恰巧知道,请教教我,在此谢过。以下是程序部分:
//红绿灯设计:利用定时器实现LED灯亮灭,数码管倒计时结束后切换led灯
//P2口控制led灯,38译码器选择数码管,P0口控制数码管显示
//定时器初始化设置,定时器溢出一次为10ms,设置一个变量a=99,a从99-->0,正好100次,也就是1s。
#include"reg52.h"
typedef unsigned int uint; //对数据类型进行声明定义
typedef unsigned char uchar;
sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;
sbit LED0=P2^7; //红灯
sbit LED1=P2^6; //绿灯
sbit LED2=P2^5; //黄灯
uchar code smgduan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//显示0~F的值
uchar DisplayData[2]; //创建一个数组,用于存放倒计时的十位和个位
uchar a=99,flag=0,sec=15; //a:100次等于1秒(配合定时器使用),flag:对应三种灯 sec:倒计时
//延时函数
void delay(uchar i)
{
while(i--);
}
//数码管显示,这里只需要使用两个数码管
//通过138译码器选择对应的数码管
void Digdisplay()
{
uchar i;
for(i=0;i<=1;i++)
{
switch(i)
{
case(0):
LSA=0;LSB=0;LSC=0;break;
case(1):
LSA=1;LSB=0;LSC=0;break;
}
P0=DisplayData[i]; //将当前的时间传递给P0,并显示出来
delay(100);
P0=0x00; //消隐
}
}
//将当前的时间和smgduan[]内已保存的16进制值对应,接着会通过Digdisplay()显示
void Datapros()
{
DisplayData[0]=smgduan[sec%10];
DisplayData[1]=smgduan[sec/10];
}
//定时器初始化
void TimerInit()
{
TMOD=0x01; //选择定时器0
TH0=0Xd8; //10毫秒
TL0=0Xf0;
EA=1;
ET0=1;
TR0=1;
}
void red() //红灯倒计时
{
if(flag==0) //flag初始值为0,从红灯开始亮(红-->绿-->黄)
{
LED2=1; //黄灯灭
LED0=0; //红亮
if(a==0) //a=0,一秒过去,倒计时sec-1
{
a=99; //重置a,开始下一秒
sec--; //倒计时sec-1
if(sec==0) //sec=0,红灯结束,绿灯开始
{
flag=1; //绿灯的flag
sec=15; //给绿灯定时
}
}
}
}
void green() //绿灯
{
if(flag==1)
{
LED0=1;
LED1=0;
if(a==0)
{
a=99;
sec--;
if(sec==0)
{
flag=3;
sec=3;
}
}
}
}
void yellow() //黄灯
{
if(flag==3)
{
LED2=0;
LED1=1;
if(a==0)
{
a=99;
sec--;
if(sec==0)
{
flag=0;
sec=15;
}
}
}
}
void Timer() interrupt 1 //中断
{
TH0=0Xd8; //10毫秒
TL0=0Xf0;
a--; //a的初始值为100,TH0和TL0溢出一次,a-1,a=0时,正好一秒
red();
green();
yellow();
}
void main()
{
TimerInit();
while(1)
{
Datapros();
Digdisplay();
}
}