东西绿南北红20秒,东西黄南北红10秒完成后切换,紧急情况倒计时10秒,红灯全亮,数码管显示倒计时
清单:DC005一个,220Ω电阻12个,3mmLED12个,最小系统配件一套,外加紧急按键一个
仿真原理图如下(51单片机程序 原理图 pcb文件 proteus仿真工程文件可到本帖附件中下载)
仿真文件+原理图pcb下载:
含紧急模式交通灯.zip
(1.04 MB, 售价: 5 E币)
单片机c源码:
- #include <reg52.h>
- sbit WARNING_KEY=P3^2; //紧急按钮
- sbit NUM_SELECT_SW=P3^6; //数码管十位片选
- sbit NUM_SELECT_GW=P3^7; //数码管个位片选
- //这里说一下我遇到的一个问题,就是在仿真上的代码中绿灯和黄灯的位定义和板子上是相反的即黄灯被当成了绿灯绿灯被当成了黄灯,然而第一块板的时候和仿真同样的代码却是能正常情况运行的
- sbit LED_RED_DX=P2^0; //东西方向红灯
- sbit LED_GRE_DX=P2^2; //东西方向绿灯
- sbit LED_YEL_DX=P2^1; //东西方向黄灯
- sbit LED_RED_NB=P2^4; //南北方向红灯
- sbit LED_GRE_NB=P2^6; //南北方向绿灯
- sbit LED_YEL_NB=P2^5; //南北方向黄灯
- #define NUM_PORT P0 //定义数码管数据端口
- code unsigned char NumCodeTable[]={
- 0x3,0xcf,0x2a,0x4a,0xc6,0x52,0x12,0xcb,0x2,0x42};//定义共阳数码管段码
- unsigned char SecondCount=60; //全局变量,每秒递减,归零重置60
- unsigned char WarningCount=0; //全局变量,每秒递减,紧急状态过后重置10秒
- //***************函数功能:秒累计****************************//
- static void TimerOnSecond(void)
- {
-
- if(WarningCount>0)//当紧急模式计数没到零还会继续自减
- {
- WarningCount--;
- return;
- }
- if(0==SecondCount)//当自减到零,重新变为60再继续自减,反之还没减到零就继续一直自减直到为零
- {
- SecondCount=60;
- }else{
- SecondCount--;
- }
- return;
- }
- //************数码管显示倒计时用的显示函数**************************//
- static void NumDisplay(void)
- {
- unsigned char DelayCount=0;//技计数延时变量
- unsigned char mSec;//用来存放需要数码管显示的数字
- if(WarningCount>0)
- {
- mSec=WarningCount;
- }else{
- if(SecondCount>=30)
- {
- mSec=SecondCount-30;
- }else{
- mSec=SecondCount;
- }
- }
- NUM_SELECT_SW=1;//开
- NUM_PORT=NumCodeTable[mSec/10];//十位
- DelayCount=100;//计数延时
- while(DelayCount--);
- NUM_SELECT_SW=0;//关
- NUM_SELECT_GW=1;//开
- NUM_PORT=NumCodeTable[mSec%10];//个位
- DelayCount=100;
- while(DelayCount--);
- NUM_SELECT_GW=0;//关
-
- return;
- }
- //***********函数功能:交通灯状态切换************************//
- static void LightCheck(void)//东西放行30秒,南北放行三十秒为一个周期,共60秒
- {
- //前30秒周期,也就是东西方向通行周期
-
- if(SecondCount>39) //60s周期的前20秒,因为倒计时所以是60-40 也就是东西方向绿灯亮
- {
- LED_RED_DX=1; //东西方向红灯关闭
- LED_YEL_DX=1; //东西方向黄灯关闭
- LED_GRE_DX=0; //东西方向绿灯开启
- }
-
- if((SecondCount<40)&&(SecondCount>29)) //60s周期的第21-30秒,也就是东西方向黄灯亮
- {
- LED_RED_DX=1; //东西方向红灯关闭
- LED_YEL_DX=0; //东西方向黄灯开启
- LED_GRE_DX=1; //东西方向绿灯关闭
- }
- if(SecondCount>29) //整个60s周期前30秒的南北方向只有红灯开启
- {
- LED_RED_NB=0; //南北方向红灯开启
- LED_YEL_NB=1; //南北方向黄灯关闭
- LED_GRE_NB=1; //南北方向绿灯关闭
- }
- //后30秒周期,也就是南北方向通行周期
- if((SecondCount<30)&&(SecondCount>9))
- {
- LED_RED_NB=1; //南北方向红灯关闭
- LED_YEL_NB=1; //南北方向黄灯关闭
- LED_GRE_NB=0; //南北方向绿灯开启
- }
- if((SecondCount<10)&&(SecondCount>=0))
- {
- LED_RED_NB=1; //南北方向红灯关闭
- LED_YEL_NB=0; //南北方向黄灯开启
- LED_GRE_NB=1; //南北方向绿灯关闭
- }
- if(SecondCount<30) //整个60s周期后30秒的东西方向只有红灯开启
- {
- LED_RED_DX=0; //东西方向红灯开启
- LED_YEL_DX=1; //东西方向黄灯关闭
- LED_GRE_DX=1; //东西方向绿灯关闭
- }
- }
- //****************函数功能:处理紧急模式**********************//
- static void WarningCheck(void)
- {
- LED_RED_DX=0; //东西方向红灯开启
- LED_YEL_DX=1; //东西方向黄灯关闭
- LED_GRE_DX=1; //东西方向绿灯关闭
- LED_RED_NB=0; //南北方向红灯开启
- LED_YEL_NB=1; //南北方向黄灯关闭
- LED_GRE_NB=1; //南北方向绿灯关闭
- return;
- }
- //******************外部中断0中断服务函数***************************//
- void INT_0(void) interrupt 0 //外部中断0,紧急情况按钮
- {
- while(!WARNING_KEY); //等待按钮释放
- WarningCount=10; //预制10秒紧急计时
- }
- //***************定时器T0的中断服务函数***************************//
- void TIMER0(void) interrupt 1 //定时器0中断处理
- {
- static unsigned int ms2sec;//该变量表示中断次数
- if(ms2sec<4000) //250μm*4000=1S,每次中断只有25微秒,但可以通过4000次计数达到1秒
- {
- ms2sec++;//自加,中断计数
- }
- else{
- ms2sec=0;//中断够4000次清零
- TimerOnSecond();
- }
- }
- //***************函数功能:对系统进行初始化*************************//
- void SystemInit(void)
- {
- //关闭所有灯
- LED_RED_DX=1;
- LED_YEL_DX=1;
- LED_GRE_DX=1;
- LED_RED_NB=1;
- LED_YEL_NB=1;
- LED_GRE_NB=1;
- PCON=0x00;//控制寄存器
- TMOD=0x22;//用T0的工作模式2,八位自动重装定时,比较省心
- //TL0逸出后会自动把TH0初值装进TL0,因此只需在初始对TH0,TL0赋值,中断程序就不用再对TH0,TL0赋值了
- TH0=0x06;//高八位赋值
- TL0=0x06;//低八位赋值
- ET0=1;//定时器中断0开关闭合
- TR0=1;//启动定时器
- EX0=1;//开外部中断0
- EA=1;//总中断允许
- }
- void main(void)
- {
- SystemInit();//先初始化一下系统
- while(1)//再来个死循环
- {
- NumDisplay(); //处理数码管显示
- if(WarningCount>0) //判断紧急状态倒计时完成没有
- {
- WarningCheck(); //没有处理完紧急状态就继续调用紧急处理
- }else{
- LightCheck(); //反之按照正常的状态处理
- }
- }
- }
复制代码
【必读】版权免责声明
1、本主题所有言论和内容纯属会员个人意见,与本论坛立场无关。2、本站对所发内容真实性、客观性、可用性不做任何保证也不负任何责任,网友之间仅出于学习目的进行交流。3、对提供的数字内容不拥有任何权利,其版权归原著者拥有。请勿将该数字内容进行商业交易、转载等行为,该内容只为学习所提供,使用后发生的一切问题与本站无关。 4、本网站不保证本站提供的下载资源的准确性、安全性和完整性;同时本网站也不承担用户因使用这些下载资源对自己和他人造成任何形式的损失或伤害。 5、本网站所有软件和资料均为网友推荐收集整理而来,仅供学习用途使用,请务必下载后两小时内删除,禁止商用。6、如有侵犯你版权的,请及时联系我们(电子邮箱1370723259@qq.com)指出,本站将立即改正。
|