使用51单片机制作十字路口交通信号灯控制系统
最编程
2024-07-28 09:33:07
...
介绍
单片机型号: 普中89C51
结合按键和LED,设计十字路口交通灯系统。绿灯和红灯10s,黄灯3s,绿灯最后闪烁3s,按键可让红灯提前结束。
设计步骤
-
选用开发板上两组三颗led分别作为红灯、黄灯、绿灯,列出交通灯亮灭所有状态
-
配置定时器0,定时 1ms产生一次中断,在中断函数中累计次数切换交通灯状态
-
配置外部中断0,按键触发并消抖,在中断函数中让交通灯状态提前过渡。
交通灯状态
共六种:
南北方向绿灯,东西方向红灯
南北方向绿灯闪烁,东西方向红灯
南北方向黄灯,东西方向红灯
南北方向红灯,东西方向绿灯
南北方向红灯,东西方向绿灯闪烁
南北方向红灯,东西方向黄灯
本实验南北方向使用D1-D3,东西方向使用D6-D8
流程图
代码
/*
Author: Richer
*/
#include "reg52.h"
typedef unsigned int u16; //对系统默认数据类型进行重定义
typedef unsigned char u8;
sbit KEY3=P3^2;
//定义十字交通灯控制脚
sbit LED_NS_R=P2^0; //南北方向
sbit LED_NS_Y=P2^1;
sbit LED_NS_G=P2^2;
sbit LED_EW_R=P2^5; //东西方向
sbit LED_EW_Y=P2^6;
sbit LED_EW_G=P2^7;
//使用宏定义十字交通灯六种状态
#define STATE_NS_G 0 //南北方向绿灯
#define STATE_NS_G_E 1 //南北方向绿灯闪烁
#define STATE_NS_Y 2 //南北方向黄灯
#define STATE_EW_G 3 //东西方向绿灯
#define STATE_EW_G_E 4 //东西方向绿灯闪烁
#define STATE_EW_Y 5 //东西方向黄灯
//南北绿灯时长,东西绿灯时长,绿灯闪烁时长,黄灯时长(单位:秒)
u8 NS_G_TIME=10, EW_G_TIME=10, G_E_TIME=3, Y_TIME=3;
u8 state; //当前状态
u16 i; //计数(ms)
void delay_ms(u16 ms)
{
u16 i,j;
for(i=ms;i>0;i--)
for(j=110;j>0;j--);
}
void time0_init(void) //定时器 0 中断配置函数
{
TMOD|=0X01;
TH0=0XFC; //定时 1ms
TL0=0X18;
ET0=1;
EA=1;
TR0=1;
}
void exti0_init(void) //外部中断 0 配置函数
{
IT0=1; //下降沿
EX0=1;
EA=1;
}
void led() //交通灯状态显示
{
switch(state)
{
case STATE_NS_G: LED_NS_R=1;LED_NS_Y=1;LED_NS_G=0;LED_EW_R=0;LED_EW_Y=1;LED_EW_G=1;break;
case STATE_NS_G_E: LED_NS_R=1;LED_NS_Y=1;LED_NS_G=~LED_NS_G;LED_EW_R=0;LED_EW_Y=1;LED_EW_G=1;delay_ms(100);break;
case STATE_NS_Y: LED_NS_R=1;LED_NS_Y=0;LED_NS_G=1;LED_EW_R=0;LED_EW_Y=1;LED_EW_G=1;break;
case STATE_EW_G: LED_NS_R=0;LED_NS_Y=1;LED_NS_G=1;LED_EW_R=1;LED_EW_Y=1;LED_EW_G=0;break;
case STATE_EW_G_E: LED_NS_R=0;LED_NS_Y=1;LED_NS_G=1;LED_EW_R=1;LED_EW_Y=1;LED_EW_G=~LED_EW_G;delay_ms(100);break;
case STATE_EW_Y: LED_NS_R=0;LED_NS_Y=1;LED_NS_G=1;LED_EW_R=1;LED_EW_Y=0;LED_EW_G=1;break;
}
}
void main() //主函数
{
time0_init();
exti0_init();
state=STATE_NS_G; //初始化交通灯状态
while(1)
{
led();
}
}
void time0() interrupt 1 //定时器 0 中断函数
{
TH0=0XFC; //定时 1ms
TL0=0X18;
i++;
if(i==NS_G_TIME*1000-G_E_TIME*1000) state=STATE_NS_G_E;
else if(i==NS_G_TIME*1000) state=STATE_NS_Y;
else if(i==NS_G_TIME*1000+Y_TIME*1000) state=STATE_EW_G;
else if(i==NS_G_TIME*1000+Y_TIME*1000+EW_G_TIME*1000-G_E_TIME*1000) state=STATE_EW_G_E;
else if(i==NS_G_TIME*1000+Y_TIME*1000+EW_G_TIME*1000) state=STATE_EW_Y;
else if(i==NS_G_TIME*1000+Y_TIME*1000+EW_G_TIME*1000+Y_TIME*1000) {state=STATE_NS_G;i=0;}
}
void exti0() interrupt 0 //外部中断 0 中断函数
{
delay_10us(1000); //消抖
if(KEY3==0) //再次判断 K3 键是否按下
{
switch(state)
{
case STATE_NS_G: i=NS_G_TIME*1000-G_E_TIME*1000-1;break;
case STATE_EW_G: i=NS_G_TIME*1000+Y_TIME*1000+EW_G_TIME*1000-G_E_TIME*1000-1;break;
default:break;
}
}
}