介绍
单片机型号: 普中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;
}
}
}
运行结果
原文地址:http://www.cnblogs.com/richer-lin/p/16853631.html
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,请务用于商业用途!
3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!
7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员!
8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载
声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性