实验四 交通灯控制系统
功能要求:
AT89S52 内部有 T0 、 T1 两个定时 / 计数器,可以工作在 定 时方式、也可以 工 作在计数方式 。 定时工 作 方式 , 是对 CPU 内部的机器 周 期进行计数 , 当寄存器 THi 、 TLi 加 1 计数满 , 发 生溢出,表示时 间 到;计数工作方 式 时,是对外部事 件进行计数 , 由 于 每 2 个机器周期 , 才能检测到 一 个 外部事件 , 因此 , 被检测的 外部事件的变化 率 最高变化频率为 f osc /12MHz 。 AT89S52 内部的 T0 、 T1 两 个 定 时 / 计数器均有 4 种 工 作 方 式 ,在 4 种工作方式中,方式 1 的定时时 间 最长, 若 =12MHz, 则最大定时时间为 65536μs 。 实验要求设计一 个 交通灯控制系统 , 利用 AT89S52 控制 6 个 LED 发 光 二 极 管 来模拟交通灯的 控 制。 硬件接线为 P3.0 接启动按 钮 , P1 口接 6 个 LED 发光二极管,用来模拟 2 组 交通信号灯,具 体 接线参见实验线 路 图。控制时序图 如 下:参考程序如下:
#include
#define D P0//数码管段选
#define T P1//LED灯
sbit K=P3^0;//P3.0接启动按钮
sbit x=P3^3;
sbit y=P3^6;
sbit L1=P3^4;//数码管位选1
sbit L2=P3^5;//数码管位选2
sbit b=P3^7;//P3.7接蜂鸣器
sbit RED1=P1^0;//P1.0接第一个红灯
sbit YELLOW1=P1^1;//P1.1接第一个黄灯
sbit GREEN1=P1^2;//P1.2接第一个绿灯
sbit RED0=P1^4;//P1.4接第二个红灯
sbit YELLOW0=P1^5;//P1.5接第二个黄灯
sbit GREEN0=P1^6;//P1.6接第二个绿灯
unsigned char C[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//数码管显示0~9共阳极的段码表
unsigned char Data[2];
unsigned char Time=0, Second=0; //用来存放定时时间
unsigned char state=0;
void Display();//动态显示函数
void Timer(void);//声明全局函数
void main(void)//主函数
{
Second=0;
b=0;//屏蔽蜂鸣器
Timer();
while(1)
{
while(state==0)
{
T=0xFF;
if(K==0)//按键按下
{
Second=0;
state=1;
}
}
while(state==1)
{
if(Second==26)
{Second=0;}
if(Second<10)
{
Data[0]=C[(10-Second)%100/10];
Data[1]=C[(10-Second)%10];
Display();
T=0xFF;
GREEN1=0;
RED0=0;
}
else if(Second<13)
{
Data[0]=C[(13-Second)%100/10];
Data[1]=C[(13-Second)%10];
Display();
T=0xFF; //将所有的灯熄灭
YELLOW1=0;
RED0=0;
}
else if(Second<23)
{
Data[0]=C[(23-Second)%100/10];
Data[1]=C[(23-Second)%10];
Display();
T=0xFF; //将所有的灯熄灭
RED1=0;
GREEN0=0;
}
else
{
Data[0]=C[(26-Second)%100/10];
Data[1]=C[(26-Second)%10];
Display();
T=0xFF; //将所有的灯熄灭
YELLOW0=0;
RED1=0;
}
if(K==1)//按键弹起
state=0;
}
}
}
void Display()//使用数码管显示
{
int j;
x=0;y=0;//屏蔽第一位和第四位
L1=1;
D=Data[0];//发送段码
j=100; //扫描间隔时间设定
while(j--);
D=0xff;//消隐
L1=0;
L2=1;
D=Data[1];//发送段码
j=100;//扫描间隔时间设定
while(j--);
D=0xff;//消隐
L2=0;
}
void Timer(void)//配置定时器
{
TMOD=0x01;//定时器0选择工作方式1
TH0=0xb1;//设置初始值,定时20ms
TL0=0xe0;
EA=1;//打开总中断
ET0=1;//打开定时器0中断
TR0=1;//启动定时器0
}
void Timer0() interrupt 1//定时器0中断函数
{
TH0=0xb1;//设置初始值 定时时间=(65536-X)×1μs
TL0=0xe0;
Time++;
if(Time==50)//循环50次
{
Second++;
Time=0;
}
}
实验结果: