接上篇万年历,这篇博客也是记录我的实训内容,我们实训有万年历和交通灯。好了不说闲话,上正文。
不知道为何突然发现说原创审核不过,完全手写的,也不知道为何,哭
注:在评论有附本人交通灯的图噢,不过我还是建议各位先自己画。噢还要注意图里芯片,双击.hex的路径,可能链接是带本人的,大家要自己编译换成自己的.hex文件路径
交通灯
- 一、实验内容
- 二、电路仿真图
- 三、代码
- 四、效果图
- 1.状态1
- 2.状态2
- 3.按键
- 五、最后
一、实验内容
模拟简单交通灯工作情况:
1、当单片机开始工作后,东西和南北各方向分别采用2个数码管显示倒计时间(倒计时时间可自行设定,这里我设的总共50s)。
状态1(前25s):初始状态为东西方向为绿灯、南北方向为红灯,红灯时间为25秒,绿灯时间20s-t(t是指蓝灯的时间,是自己设置的,比如我蓝灯如果设置的是10s那么绿灯的时间就是10s),绿灯之后为ts蓝灯结束后为5s的黄灯,总共25s时间,之后变为状态2。
南北:红25s
东西:绿20-ts——蓝ts——黄5s
状态2(后25s):南北方向为绿灯、东西方向为红灯,红灯时间为25s,绿灯还是20s-t,上文讲的同样,绿灯结束变蓝灯ts,蓝灯结束后为黄灯5s,总计25s,之后又重返状态1,以此循环
东西:红25s
南北:绿20-ts——蓝ts——黄5s
2、设置三个紧急按键,特殊情况时按下紧急按键人为设置亮灯时间,分别为南北禁行东西通行、东西禁行南北通行、全部禁行。
二、电路仿真图
这里用的是isis画,代码用keil4编译
https://download.csdn.net/download/kushe123/19286087?spm=1001.2014.3001.5503,本人仿真图连接,记得换仿真图AT89C51芯片中的.hex文件。
图中所用的器件(这里用的都是共阳LED,CA)
三、代码
#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int
uchar shuzi[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //共阳无小数点
//P0控制LED灯是否亮
sbit ew_red=P0^0; //东西红灯,低电平亮
sbit ew_yellow=P0^1;
sbit ew_green=P0^2;
sbit sn_red=P0^3;
sbit sn_yellow=P0^4;
sbit sn_green=P0^5;
sbit ew_led=P0^6;
sbit sn_led=P0^7;
//p2口控制段码
sbit P2_0=P0^0;
sbit P2_1=P2^1;
sbit P2_2=P2^2;
sbit P2_3=P2^3;
sbit P2_4=P2^4;
sbit P2_5=P2^5;
sbit P2_6=P2^6;
sbit P2_7=P2^7;
//控制数码管位码
sbit P1_0=P1^0; //p1_0,p1_1控制东西灯位码
sbit P1_1=P1^1;
sbit P1_2=P1^2; //p1_2,p1_3控制南北灯位码
sbit P1_3=P1^3;
sbit P1_4=P1^4; //p1_4,p1_5控制左转数码管位码
sbit P1_5=P1^5;
//按键
sbit left_add=P3^0;
sbit left_reduce=P3^1;
sbit P3_2=P3^2; //东西通行按键
sbit P3_3=P3^3; //南北通行按键
sbit P3_4=P3^4; //全部禁止按键
sbit sn_reduce=P3^5;
sbit ew_reduce=P3^6;
//定义变量
int left;
int leftadd=0;
int leftreduce=0;
int ewadd=0;
int ewreduce=0;
int snadd=0;
int snreduce=0;
int s=0,n=0;void time(void) interrupt 1 //中断,产生1s
{TH0=(65536-50000)/256; //0.05s=50msTL0=(65536-50000)%256;n++;if(n==20){n=0;s++;}if(s==50)s=0;
}
void sn_letf() //东西红灯南北(绿灯,左转灯)
{sn_led=0;ew_led=1;ew_red=0;ew_yellow=1;ew_green=1;sn_red=1;sn_yellow=1;sn_green=1;
}
void ew_letf() //东西(绿灯,左转灯)南北红灯
{sn_led=1;ew_led=0;ew_red=1;ew_yellow=1;ew_green=1; //低电平亮sn_red=0;sn_yellow=1;sn_green=1;
}
void ew_allow() //东西绿灯南北红灯
{sn_led=1;ew_led=1;ew_red=1;ew_yellow=1;ew_green=0; //低电平亮sn_red=0;sn_yellow=1;sn_green=1;
}
void ew_wait() //东西黄灯南北红灯
{sn_led=1;ew_led=1;ew_red=1;ew_yellow=0;ew_green=1;sn_red=0;sn_yellow=1;sn_green=1;
}
void sn_allow() //东西红灯南北绿灯
{sn_led=1;ew_led=1;ew_red=0;ew_yellow=1;ew_green=1;sn_red=1;sn_yellow=1;sn_green=0;
}
void sn_wait() //东西红灯南北黄灯
{sn_led=1;ew_led=1;ew_red=0; //低电平亮ew_yellow=1;ew_green=1;sn_red=1;sn_yellow=0;sn_green=1;
}void delay()
{ int i;int j;for(i=0;i<100;i++)for(j=0;j<10;j++);
}
void chushi() //P1初始化
{P1_0=0;P1_1=0;P1_2=0;P1_3=0;P1_4=0;P1_5=0;
}void jinzhi() //按下禁止按钮后四个方向都禁止(都为红灯) 且时间显示为99
{chushi();P2=shuzi[9]; //段码P1_0=1;P1_2=1; P1_4=1;delay();chushi();P1_1=1; P1_3=1;P1_5=1;ew_red=0;ew_yellow=1;ew_green=1;sn_red=0;sn_yellow=1;sn_green=1;sn_led=1;ew_led=1;delay();
}
void display_led() //led灯显示
{if(s<=20-left)ew_allow(); //东西绿灯南北红灯else if(s<=20) ew_letf(); //东西(绿灯,左转灯)南北红灯else if(s<=25) //5sew_wait(); //东西黄灯南北红灯else if(s<=45-left)sn_allow(); //东西红灯南北绿灯else if(s<=45) //5ssn_letf(); //东西红灯南北(绿灯,左转灯)else if(s<=50) sn_wait();elsejinzhi();}
void display_shuzi1() //绿灯以及黄灯的倒计时显示
{if(s<=20){chushi();P2=shuzi[(20-s)/10]; //每100t=5s 十位(0-2)P1_1=0;P1_0=1;delay();chushi();P2=shuzi[(20-s)%10]; //个位(0-9) 2次P1_1=1; //个位P1_0=0; //十位delay();}else if(s<=25){chushi();P2=shuzi[(25-s)/10];P1_1=0;P1_0=1;delay();chushi();P2=shuzi[(25-s)%10];P1_1=1;P1_0=0;delay();}else if(s<=45){chushi();P2=shuzi[(45-s)/10];P1_3=0;P1_2=1;delay();chushi();P2=shuzi[(45-s)%10];P1_3=1;P1_2=0;delay();}else if(s<=50){chushi();P2=shuzi[(50-s)/10];P1_3=0;P1_2=1;delay();chushi();P2=shuzi[(50-s)%10];P1_3=1;P1_2=0;delay();}elsejinzhi();}
void display_shuzi2() //红灯的倒计时显示
{ if(s<=25){chushi();P2=shuzi[(25-s)/10];P1_3=0; //个位P1_2=1; //南北数码管十位delay();chushi();P2=shuzi[(25-s)%10];P1_3=1;P1_2=0;delay();} else if(s<=50){chushi();P2=shuzi[(50-s)/10];P1_1=0;P1_0=1;delay();chushi();P2=shuzi[(50-s)%10];P1_1=1;P1_0=0;delay();}elsejinzhi();}
void display_shuzi3()
{if(s<=50){chushi();P2=shuzi[left/10];P1_4=1;P1_5=0;delay();chushi();P2=shuzi[left%10];P1_4=0;P1_5=1;delay();}if(s==51)jinzhi();
}
void panduan() //按键的判断
{if(P3_2==0) //按下时切换到东西绿灯刚亮起的时间段s=1;if(P3_3==0) //按下时切换到南北绿灯刚亮起的时间段s=26;if(P3_4==0) //按下时切换到循环之外的时间段 实现全部禁止(恢复通行需要按下南北通行或东西通行)s=51;if(left_add==0) leftadd=1;if(left_add==1&&leftadd==1) //按下并弹起增加南北通行时间5s(东西通行时无效){left++;leftadd=0;}if(sn_reduce==0)snreduce=1;if(sn_reduce==1&&snreduce==1) //按下并弹起减少南北红灯时间3s(东西通行时无效){if(s>=0&&s<20)s=s+3;if(s>=20&&s<25)s=25;snreduce=0;}if(left_reduce==0)leftreduce=1;if(left_reduce==1&&leftreduce==1) //按下并弹起增加东西通行时间5s(南北通行时无效){left--;leftreduce=0;} if(ew_reduce==0)ewreduce=1;if(ew_reduce==1&&ewreduce==1) //按下并弹起减少东西通行时间5s(南北通行时无效){if(s>=25&&s<45)s=s+3;if(s>=45&&s<50)s=50;ewreduce=0;} }void main()
{TMOD=0x01;TH0=(65536-50000)/256;TL0=(65536-50000)%256;EA=1;ET0=1;TR0=1;left=10; //定义左转时间初值while(1){ display_led(); display_shuzi1();display_shuzi2();display_shuzi3();panduan();}
}
四、效果图
1.状态1
东西:绿灯(20-ts)——蓝灯ts(10s)——黄灯5s
南北:红灯(25s)
南北:红灯
东西:蓝灯
南北:红灯
东西:黄灯
2.状态2
南北:绿灯(20-ts)——蓝灯ts(10s)——黄灯5s
东西:红灯(25s)
后续图就不发了,因为跟状态一类似的
3.按键
1.东西通行
就是切换到东西绿灯南北红灯的状态,会读秒,但单击按钮旁边的红色键可以一直保持这个状态
2.南北通行
切换到南北绿灯,东西红灯的状态,与东西通行同理
3.全部禁止
全部红灯不通行,不读秒
4. 左转时间加
即加蓝灯的时间,按一下+1s,下次循环绿灯就少了1s(20-t)
5.左转时间减
与4同理
6.南北红灯时间减
这个只有在南北是红灯状态下有用,按下南北红灯时间减3s,因为要保持南北东西状态一致(每边都是50s,要统一),所以按下后东西的时间也会减3s
7.东西红灯时间减
与6同理
五、最后
希望能对你有用!!
当然还有最重要的事,麻烦各位大佬给个三连,毕竟码字不容易。
如果三连不行就点个赞吧(卑微)。