编写程序,模拟现实生活中的交通信号灯。

编写程序,模拟现实生活中的交通信号灯。

源程序和仿真已打包 需要的可以自行下载(纯原创 请珍惜本人劳动成果 欢迎转发)

链接: 点击前往下载

交通灯实验要求:

1、交通灯正常运行时可分为4个状态:

状态1:东西方向绿灯亮,东西Blue数码管倒计时显示;南北方向红灯亮,南北红色数码管倒计时显示(时间自定);
状态2:剩余3秒,东西南北方向黄灯闪,最后转向状态3;
状态3:东西方向红灯亮,东西红色数码管倒计时显示;南北方向绿灯亮,南北Blue数码管倒计时显示(时间自定);
状态4:剩余3秒,东西南北方向黄灯闪,最后转向状态1。

2.异常状态(中断实现):

东西发生异常时,东西方向黄灯灯闪,闪60秒;
南北发生异常时,南北方向黄灯灯闪,闪60秒。
(注:通过中断模拟异常情况的发生。)

代码实现

1.程序的核心思想

①: 本次实验加入了头文件(.h文件)。将实验中用到的所有函数(延时函数void delay(int j),判断按钮函数int key(),二位数码管显示函数void showNumByCA(int num))。通过这样设置,可使主程序耦合度最低,结构清晰。
②: 头文件中的showNumByCA函数中有多个,差别在不同的showNumByCA控制不同的数码管。
③: 交通灯程序原理:所有的二位数码管使用的是同一个端口(P0)。显示相同的数字,通过使用不同的showNumByCA函数(showNumByCA1,showNumByCA2…)控制不同的数码管来达到红蓝数码管切换的功能。
④:关于中断0:中断0的功能是使东西不亮,交通灯闪黄灯,南北正常计数。所以在程序中设置了一个全局变量repair=0,当按钮按下时repair置成10。在主程序中,每次状态的切换都会检查repair的值,当值是0时,代表按钮没按下,进行正常显数。当按钮按下,repair=10。代表异常状态,此时按程序要求使用不同的showNumByCA函数(showNumByCA1,showNumByCA2…)使对应的数码管关闭,调整对应的交通灯显色。每显示一个数字后,repair都会自减1,所以,当减到repair=0时,程序回归正常。异常状态进行了repair=10次。
⑤:关于中断1:类比于④,唯一的差别是按钮按下时,repair=-10,每显示一个数字后,repair都会自增1,所以,当增加到repair=0时,程序回归正常。异常状态进行了repair=-10次。
⑥:本实验交通信号灯采用精准1S定时(定时中断实现)

2.程序源码

//头文件部分 使用时要额外创建 .h 文件 文件名见主函数引入
void delay(unsigned char k){unsigned char i,j,h;for(h=0;h<k;h++){for(i=0;i<25;i++){for(j=0;j<20;j++);}}
}
void twoDigitDisplay(unsigned char num,unsigned char time,unsigned char portNumber){unsigned char box[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0xf82,0xf8,0x80,0x90};unsigned char k;if(portNumber==0){if(num<0||num>99||time<0){for(k=0;k<40;k++){P2=0x00;}	}else{		for(k=0;k<time;k++){unsigned char numR = num%10;unsigned char numL = num/10;P2=0x11;P0=box[numL];delay(12);P2=0x22;P0=box[numR];delay(12);}}}	
}
void twoDigitDisplay1(unsigned char num,unsigned char time,unsigned char portNumber){unsigned char box[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0xf82,0xf8,0x80,0x90};unsigned char k;if(portNumber==0){if(num<0||num>99||time<0){for(k=0;k<40;k++){P2=0x00;}	}else{		for(k=0;k<time;k++){unsigned char numR = num%10;unsigned char numL = num/10;P2=0x44;P0=box[numL];delay(12);P2=0x88;P0=box[numR];delay(12);}}}	
}
void twoDigitDisplay2(unsigned char num,unsigned char time,unsigned char portNumber){unsigned char box[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0xf82,0xf8,0x80,0x90};unsigned char k;if(portNumber==0){if(num<0||num>99||time<0){for(k=0;k<40;k++){P2=0x00;}	}else{		for(k=0;k<time;k++){unsigned char numR = num%10;unsigned char numL = num/10;P2=0x10;P0=box[numL];delay(12);P2=0x20;P0=box[numR];delay(12);}}}	
}
void twoDigitDisplay3(unsigned char num,unsigned char time,unsigned char portNumber){unsigned char box[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0xf82,0xf8,0x80,0x90};unsigned char k;if(portNumber==0){if(num<0||num>99||time<0){for(k=0;k<40;k++){P2=0x00;}	}else{		for(k=0;k<time;k++){unsigned char numR = num%10;unsigned char numL = num/10;P2=0x40;P0=box[numL];delay(12);P2=0x80;P0=box[numR];delay(12);}}}	
}
void twoDigitDisplay4(unsigned char num,unsigned char time,unsigned char portNumber){unsigned char box[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0xf82,0xf8,0x80,0x90};unsigned char k;if(portNumber==0){if(num<0||num>99||time<0){for(k=0;k<40;k++){P2=0x00;}	}else{		for(k=0;k<time;k++){unsigned char numR = num%10;unsigned char numL = num/10;P2=0x01;P0=box[numL];delay(12);P2=0x02;P0=box[numR];delay(12);}}}	
}
void twoDigitDisplay5(unsigned char num,unsigned char time,unsigned char portNumber){unsigned char box[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0xf82,0xf8,0x80,0x90};unsigned char k;if(portNumber==0){if(num<0||num>99||time<0){for(k=0;k<40;k++){P2=0x00;}	}else{		for(k=0;k<time;k++){unsigned char numR = num%10;unsigned char numL = num/10;P2=0x04;P0=box[numL];delay(12);P2=0x08;P0=box[numR];delay(12);}}}	
}
// 主函数部分
#include<reg51.h>
#include"ShowNum.h"
char repair=0;
void main(){char num;IT0=1;EA=1;EX0=1;IT1=1;EX1=1;P1=0x00;while(1){for(num=10;num>=0;num--){if(num<=3&&num>=0){if(repair==0){P1=0x22;twoDigitDisplay(num,8,0);}if(repair<=10&&repair>=1){P1=0x22;twoDigitDisplay2(num,8,0);repair--;}if(repair<=-1&&repair>=-10){P1=0x22;twoDigitDisplay4(num,8,0);repair++;}P1=0x00;if(repair==0){twoDigitDisplay(num,8,0);}if(repair<=10&&repair>=1){twoDigitDisplay2(num,8,0);repair--;}if(repair<=-1&&repair>=-10){twoDigitDisplay4(num,8,0);repair++;}continue;}			if(repair==0){P1=0x41;twoDigitDisplay(num,15,0);}if(repair<=10&&repair>=1){P1=0x42;twoDigitDisplay2(num,8,0);P1=0x40;twoDigitDisplay2(num,8,0);repair--;}if(repair<=-1&&repair>=-10){P1=0x21;twoDigitDisplay4(num,8,0);P1=0x01;twoDigitDisplay4(num,8,0);repair++;}}for(num=10;num>=0;num--){if(num<=3&&num>=0){if(repair==0){P1=0x22;twoDigitDisplay1(num,8,0);}if(repair<=10&&repair>=1){P1=0x22;twoDigitDisplay3(num,8,0);repair--;}if(repair<=-1&&repair>=-10){P1=0x22;twoDigitDisplay5(num,8,0);repair++;}P1=0x00;if(repair==0){twoDigitDisplay1(num,8,0);}if(repair<=10&&repair>=1){twoDigitDisplay3(num,8,0);repair--;}if(repair<=-1&&repair>=-10){twoDigitDisplay5(num,8,0);repair++;}continue;}			if(repair==0){P1=0x14;twoDigitDisplay1(num,15,0);}if(repair<=10&&repair>=1){P1=0x42;twoDigitDisplay2(num,8,0);P1=0x40;twoDigitDisplay2(num,8,0);repair--;}if(repair<=-1&&repair>=-10){P1=0x21;twoDigitDisplay4(num,8,0);P1=0x01;twoDigitDisplay4(num,8,0);repair++;}}}
}
void int0() interrupt 0 {//东西异常 东西方向的黄灯闪10次后正常 南北正常计时repair=10;
}
void int1() interrupt 2 {//南北异常 南北方向的黄灯闪10次后正常 南北正常计时repair=-10;
}

二、仿真演示

仿真演示 定时10S一轮 参数可以在程序里调整!仿真演示 定时10S一轮 参数可以在程序里调整

源程序和仿真已打包 需要的可以自行下载

链接: 点击下载

喜欢单片机的朋友可以一起交流


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部