单片机交流
登录
直播中
孙奕
7年用户
870经验值
私信
关注
[问答]
如何去完成一种基于51单片机的十字路***通灯实验?
开启该帖子的消息推送
交通灯
51单片机
如何去完成一种基于51
单片机
的十字路***通灯实验?
如何对基于51单片机的十字路***通灯进行
proteus
仿真
?
回帖
(1)
李建平
2021-7-19 15:11:16
一、实验名称:十字路***通灯实验
二、实验目的:
利用51单片机完成模拟正常路***通灯的运行过程,过程中配备紧急调控按键(路口均为红灯,模拟突发情况禁止路口通行),南北调度按键(紧急调度南北或者东西方向的通行),每个事件结束后,均可以恢复原来的通行秩序,也就是涉及了保护现场和恢复现场。
三、实验平台:
Keil4编写代码,Proteus仿真程序
四、Proteus仿真搭建:
显示路口时间器件我们选择了两位数码管动态显示,动态显示的特点是将所有数码管的段选线并联在一起,通过控制位选信号来控制数码管的点亮。这样一来,就没有必要给每一位数码管配一个锁存器,从而大大简化了硬件威廉希尔官方网站 。数码管采用动态扫描显示,即轮流向各位数码管送出字形码和相应的位选,利用发光管的余辉和人眼的视觉暂留作用,使人感觉好像各位数码管在同时显示,因此亮度比静态显示要差一些,所以在选择限流电阻时应略小于静态显示威廉希尔官方网站 中的限流电阻。
五、程序分析
1、对于需要用到的单片机外设的初始化设置,外设的意义我在初始化函数里写的很清楚了,下面上代码:
void init(){ second=25; //当前数码管显示南北方向红绿灯初始时间 second1=30; //当前数码管显示东西方向红绿灯时间 TMOD=0x01; // M0=1,M1=0 定时器0设置工作方式为方式1,即16位定时器/计数器 TH0=(65536-50000)/256;//晶振默认为12MHz,所以执行一条指令的时间为1us TL0=(65536-50000)%256;//这里表示进入一次定时器中断,耗时为50ms EA=1; //系统允许中断,即开启总中断 ET0=1;//定时0(TR0)定时中断开启位 EX0=1;//外部中断0使能 IT0=1;//外部中断0触发方式为:下降沿触发,即引脚P30接受到一次下降信号,触发外部中断0 EX1=1;//外部中断1使能 IT1=1;//外部中断1触发方式为:下降沿触发,即引脚P31接受到一次下降信号,触发外部中断0 IP=0x02;//定时器0中断优先,这个比较重要,不然默认外部中断0优先级是先于定时器0中断的 TR0=1;//开启定时器0 a=0; b=0; c=10; d=10; e=10; f=10;} 我们在初始化函数里面开启了定时器,开启了定时器中断,开启了外部中断,并且设置了中断的优先级,防止紧急情况定时器中断由于优先级被挡死在外面,导致定时器不进行。其实给abcdef这几个变量的赋值本质上就是一个bool值得关系,是非0即1的关系,所以给这些变量赋值10,或者赋值100,1,18…都是没有影响的。
2、定时器中断:
在定时器中断我们其实只是完成一个定时1s后对设定值second自减(比如南北方向我们设定初始绿灯30s,那么定时器就会在每秒对30这个设定值second自减),在主程序中我们把这个动态的设定值显示在数码管上即可。代码太长我们这里就不全列出来了。
有一点我们讲一下,就是这个程序中标志量c d 为一组,e f 为一组,用来完成紧急事件的定时工作和恢复现场(即按下按键之前各个交通灯是什么值,恢复回来,系统又可以稳定的运行了。)这里以e f(禁止通行标志量)列一下代码吧:
if(e==0) { timer3++; if(timer3==15) { timer3=0; second--; } if(second==0)//保护现场 { a=m;b=n; e=10;f=10; second=v;second1=x; } if(f==0) { timer3++; if(timer3==15) { timer3=0; second1--; } } 3、外部中断:
在仿真图中我们可以很容易的看到我们单片机上的外部中断引脚连接了两个按键,根据初始化函数,按下按键就会触发中断进入外部中断0/1中。
这里我们以外部中断0为例,这个中断是紧急禁行(全是红灯)事件,我们按下按键,进入该中断里:
void waibu0(void) interrupt 0 { TR0=0; m=a;n=b;v=second;x=second1;//保存进入外部中断0后,程序的变量大小 second=20; //设定禁止通行时间,并通过数码管显示出来 second1=20; a=10;b=10; //改变这6个标志位,控制进入定时器中断执行哪些语句 c=10;d=10; e=0;f=0; EX0=0; //关闭外部中断,即在此按下不会打断现有状况 EX1=0; TR0=1; g=1;r=0;y=1; //改变交通灯,使其均变为红灯 G1=1;R1=0;Y1=1; } 在这个中断里面有一行指令m=a;n=b;v=second;x=second1;这个指令其实就是我们平时说的保护现场,把进入中断时当前场景的有关变量保存起来,执行完相关命令后,再恢复现场。
再说一下外部中断1函数吧:
void waibu1(void) interrupt 2 { if(key1==0) { TR0=0; j=second;h=second1; second=20; second1=20; a=10;b=10; c=0;d=0; e=10;f=10; TR0=1; g=1;r=0;y=1; G1=0;R1=1;Y1=1; } if(key2==0) { TR0=0; j=second;h=second1; second=20; second1=20; a=10;b=10; c=0;d=0; e=10;f=10; TR0=1; g=0;r=1;y=1; G1=1;R1=0;Y1=1; }} 其实思路和外部中断0里的一样,但是我们这里设计的是在按下这个按键之前就要先选择是哪一路通行,即按下key1或者key2并自锁以后,再按下这个外部中断1按键,才能正常的进行调控,这里是程序不太合理的地方,有时间改改!
4、主程序:
主程序就很简单了,就是数码管的扫描和显示,根据标志位判断路***通灯的变化。我们这里把程序列一下:
void main(){ init(); while(1) { // P1=0x02; YOU1=1;ZUO1=0;ZUO2=0;YOU2=0; P2=~table[second/10]; delay(10);// P1=0x01; YOU1=0;ZUO1=1;ZUO2=0;YOU2=0; P2=~table[second%10]; delay(10);// P1=0x04; ZUO1=0;YOU1=0;ZUO2=1;YOU2=0; P0=~table[second1/10]; delay(10);// P1=0x08; ZUO1=0;YOU1=0;ZUO2=0;YOU2=1; P0=~table[second1%10]; delay(10); if(a==0) {g=0;r=1;} if(a==1) {y=0;g=1;} if(a==2) {r=0;y=1;} if(b==0) {R1=0;Y1=1;} if(b==1) {G1=0;R1=1;} if(b==2) {Y1=0;G1=1;} }} 六、实验现象:
其中按键功能我们通过图片不好表示,我又懒得上视频,有时间把程序和仿真图都放出来大家可以自己下载测试一下!
一、实验名称:十字路***通灯实验
二、实验目的:
利用51单片机完成模拟正常路***通灯的运行过程,过程中配备紧急调控按键(路口均为红灯,模拟突发情况禁止路口通行),南北调度按键(紧急调度南北或者东西方向的通行),每个事件结束后,均可以恢复原来的通行秩序,也就是涉及了保护现场和恢复现场。
三、实验平台:
Keil4编写代码,Proteus仿真程序
四、Proteus仿真搭建:
显示路口时间器件我们选择了两位数码管动态显示,动态显示的特点是将所有数码管的段选线并联在一起,通过控制位选信号来控制数码管的点亮。这样一来,就没有必要给每一位数码管配一个锁存器,从而大大简化了硬件威廉希尔官方网站 。数码管采用动态扫描显示,即轮流向各位数码管送出字形码和相应的位选,利用发光管的余辉和人眼的视觉暂留作用,使人感觉好像各位数码管在同时显示,因此亮度比静态显示要差一些,所以在选择限流电阻时应略小于静态显示威廉希尔官方网站 中的限流电阻。
五、程序分析
1、对于需要用到的单片机外设的初始化设置,外设的意义我在初始化函数里写的很清楚了,下面上代码:
void init(){ second=25; //当前数码管显示南北方向红绿灯初始时间 second1=30; //当前数码管显示东西方向红绿灯时间 TMOD=0x01; // M0=1,M1=0 定时器0设置工作方式为方式1,即16位定时器/计数器 TH0=(65536-50000)/256;//晶振默认为12MHz,所以执行一条指令的时间为1us TL0=(65536-50000)%256;//这里表示进入一次定时器中断,耗时为50ms EA=1; //系统允许中断,即开启总中断 ET0=1;//定时0(TR0)定时中断开启位 EX0=1;//外部中断0使能 IT0=1;//外部中断0触发方式为:下降沿触发,即引脚P30接受到一次下降信号,触发外部中断0 EX1=1;//外部中断1使能 IT1=1;//外部中断1触发方式为:下降沿触发,即引脚P31接受到一次下降信号,触发外部中断0 IP=0x02;//定时器0中断优先,这个比较重要,不然默认外部中断0优先级是先于定时器0中断的 TR0=1;//开启定时器0 a=0; b=0; c=10; d=10; e=10; f=10;} 我们在初始化函数里面开启了定时器,开启了定时器中断,开启了外部中断,并且设置了中断的优先级,防止紧急情况定时器中断由于优先级被挡死在外面,导致定时器不进行。其实给abcdef这几个变量的赋值本质上就是一个bool值得关系,是非0即1的关系,所以给这些变量赋值10,或者赋值100,1,18…都是没有影响的。
2、定时器中断:
在定时器中断我们其实只是完成一个定时1s后对设定值second自减(比如南北方向我们设定初始绿灯30s,那么定时器就会在每秒对30这个设定值second自减),在主程序中我们把这个动态的设定值显示在数码管上即可。代码太长我们这里就不全列出来了。
有一点我们讲一下,就是这个程序中标志量c d 为一组,e f 为一组,用来完成紧急事件的定时工作和恢复现场(即按下按键之前各个交通灯是什么值,恢复回来,系统又可以稳定的运行了。)这里以e f(禁止通行标志量)列一下代码吧:
if(e==0) { timer3++; if(timer3==15) { timer3=0; second--; } if(second==0)//保护现场 { a=m;b=n; e=10;f=10; second=v;second1=x; } if(f==0) { timer3++; if(timer3==15) { timer3=0; second1--; } } 3、外部中断:
在仿真图中我们可以很容易的看到我们单片机上的外部中断引脚连接了两个按键,根据初始化函数,按下按键就会触发中断进入外部中断0/1中。
这里我们以外部中断0为例,这个中断是紧急禁行(全是红灯)事件,我们按下按键,进入该中断里:
void waibu0(void) interrupt 0 { TR0=0; m=a;n=b;v=second;x=second1;//保存进入外部中断0后,程序的变量大小 second=20; //设定禁止通行时间,并通过数码管显示出来 second1=20; a=10;b=10; //改变这6个标志位,控制进入定时器中断执行哪些语句 c=10;d=10; e=0;f=0; EX0=0; //关闭外部中断,即在此按下不会打断现有状况 EX1=0; TR0=1; g=1;r=0;y=1; //改变交通灯,使其均变为红灯 G1=1;R1=0;Y1=1; } 在这个中断里面有一行指令m=a;n=b;v=second;x=second1;这个指令其实就是我们平时说的保护现场,把进入中断时当前场景的有关变量保存起来,执行完相关命令后,再恢复现场。
再说一下外部中断1函数吧:
void waibu1(void) interrupt 2 { if(key1==0) { TR0=0; j=second;h=second1; second=20; second1=20; a=10;b=10; c=0;d=0; e=10;f=10; TR0=1; g=1;r=0;y=1; G1=0;R1=1;Y1=1; } if(key2==0) { TR0=0; j=second;h=second1; second=20; second1=20; a=10;b=10; c=0;d=0; e=10;f=10; TR0=1; g=0;r=1;y=1; G1=1;R1=0;Y1=1; }} 其实思路和外部中断0里的一样,但是我们这里设计的是在按下这个按键之前就要先选择是哪一路通行,即按下key1或者key2并自锁以后,再按下这个外部中断1按键,才能正常的进行调控,这里是程序不太合理的地方,有时间改改!
4、主程序:
主程序就很简单了,就是数码管的扫描和显示,根据标志位判断路***通灯的变化。我们这里把程序列一下:
void main(){ init(); while(1) { // P1=0x02; YOU1=1;ZUO1=0;ZUO2=0;YOU2=0; P2=~table[second/10]; delay(10);// P1=0x01; YOU1=0;ZUO1=1;ZUO2=0;YOU2=0; P2=~table[second%10]; delay(10);// P1=0x04; ZUO1=0;YOU1=0;ZUO2=1;YOU2=0; P0=~table[second1/10]; delay(10);// P1=0x08; ZUO1=0;YOU1=0;ZUO2=0;YOU2=1; P0=~table[second1%10]; delay(10); if(a==0) {g=0;r=1;} if(a==1) {y=0;g=1;} if(a==2) {r=0;y=1;} if(b==0) {R1=0;Y1=1;} if(b==1) {G1=0;R1=1;} if(b==2) {Y1=0;G1=1;} }} 六、实验现象:
其中按键功能我们通过图片不好表示,我又懒得上视频,有时间把程序和仿真图都放出来大家可以自己下载测试一下!
举报
更多回帖
rotate(-90deg);
回复
相关问答
交通灯
51单片机
怎么实现基于
51
单片机
的
十字路
***通
灯
系统的设计?
2021-11-04
1839
如何实现基于
51
单片机
的
十字路
***通
灯
的设计?
2021-10-18
1154
如何
去
实现
一种
计时
十字路
***通信号灯及公共时钟的设计
2021-08-11
3484
设计
一
个
十字路
***通
灯
控制器
2019-03-23
7371
如何
去
完成
一种
基于
51
单片机
点亮led
灯
的
实验
?
2021-07-14
1077
基于labview的
十字路
***通
灯
怎么加模糊控制?
2016-05-18
2316
求大家帮助,自己做的labview
十字路
***通
灯
老是出错
2016-06-14
3056
请问labview中如何控制循迹小车检测并通过
十字路
口
2018-08-19
3787
智能小车过
十字路
口
2018-12-01
5643
用
单片机
/ARM实现交通
灯
2014-12-31
2627
发帖
登录/注册
20万+
工程师都在用,
免费
PCB检查工具
无需安装、支持浏览器和手机在线查看、实时共享
查看
点击登录
登录更多精彩功能!
英国威廉希尔公司网站
william hill官网 版块
小组
免费开发板试用
ebook
直播
搜索
登录
×
20
完善资料,
赚取积分