1.设计目的- 学习AT89C51的原理及应用
- 了解使用单片机处理复杂逻辑的方法
2.设计任务 本系统的软件设计主要分为四大模块:定时模块、倒计时显示、红绿灯显示、按键输入。定时模块通过定时器T0在模式1下,完成1秒的定时功能,每1秒时间到,将会对通行时间进行倒计时。显示模块采用动态显示的方式,段选码从P2端口输出,位选码从P1端口输出。红绿灯显示采用单片机IO端口直接驱动,当IO端口输出低电平时,相应的发光二极管发光;当IO端口输出高电平时,相应的发光二极管熄灭。按键输入,主要完成“东西通行”、“南北通行”、“禁止通行”三个功能,每次按键输入的时候,会对按键进行软件消抖,从而保证按键的准确输入。 基本要求 a显示电路采用七段共阴极数码管显示,南北方向的数码管的段选端分别与P2端口的P2.0~P2.7相连,位选端分别与P1.2和P1.3相连;东西方向的数码管的段选端也与P2端口的P2.0~P2.7相连,位选端分别与P1.0和P1.1相连 b. 实现这三个功能:东西通行、南北通行、禁止通行。
在以上设计基础上,在单片机的P1.0-P1.3口分别接入4个按键:
- 东西方向和南北方向的通行时间输入和输入时间的显示
- 在绿灯亮起时,添加声音提示行人通行。
3.设计原理图
4.数字钟程序流程图 
图9.3 智能交通灯控制主程序流程图 
代码:
- #include <reg51.h> //包含MCS-51单片机头文件
- #define uchar unsigned char //定义宏uchar
- #define uint unsigned int //定义宏uint
- sbit P1_0 =P1^0; //定义单片机IO口P1.0
- sbit P1_1 =P1^1; //定义单片机IO口P1.1
- sbit P1_2 =P1^2; //定义单片机IO口P1.2
- sbit P1_3 =P1^3; //定义单片机IO口P1.3
- sbit ew_red=P0^0; //定义单片机IO口P0.0为东西方向红灯控制位
- sbit ew_yellow=P0^1; //定义单片机IO口P0.1为东西方向黄灯控制位
- sbit ew_green=P0^2; //定义单片机IO口P0.2为东西方向绿灯控制位
- sbit sn_red=P0^3; //定义单片机IO口P0.3为南北方向红灯控制位
- sbit sn_yellow=P0^4; //定义单片机IO口P0.4为南北方黄灯控制位
- sbit sn_green=P0^5; //定义单片机IO口P0.5为南北方向绿灯控制位
- sbit key_earth_west=P3^2; //定义单片机IO口P3.2东西方向通行控制按键
- sbit key_sourth_north= P3^3; //定义单片机IO口P3.3南北方向通行控制按键
- sbit all_not=P3^4; //定义单片机IO口P3.4为全部禁行控制位
- sbit key_earth_west_add=P3^0; //定义单片机IO口P3.0为东西加
- sbit key_earth_west_jian= P3^1; // 定义单片机IO口P3.1为东西减
- sbit key_sourth_north_add=P3^5; // 定义单片机IO口P3.5为南北加
- sbit key_sourth_north_jian= P3^6; // 定义单片机IO口P3.6为南北减
- uchar code s7_table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
- //七段码显示表
- uchar a,b,c,d; //定义东西南北时间
- uchar sou_nor_time; //南北通行时间变量定义
- uchar east_weat_time; //东西通行时间变量定义
- uchar time_flag; //时间标志位定义
- uchar traffic_flag; //traffic_flag=0时南北通行,traffic_flag=1时东西通行
- uchar time_multiply; //定义计时变量
- void delayms(uchar z) //延时子程序
- {
- uchar i,j; //定义变量i,j
- for(i=z;i>0;i--) //for循环,共循环z次
- for(j=110;j>0;j--); //for循环,共循环j次
- }
- void display_time( ) //显示倒计时子程序
- {
- P1_0 =0; //P1.0输出低电平,位选使能
- P1_1 =1; //P1.1输出高电平
- P1_2 =1; //P1.2输出高电平
- P1_3 =1; //P1.3输出高电平
- P2=s7_table[a/10]; //P2端口输出显示的段码
- delayms(2); //延时2毫秒
- P2=0; //P2端口输出低电平
- P1_0 =1; //P1.0输出高电平
-
- P1_1 =0; //P1.1输出低电平,位选使能
- P2=s7_table[b%10]; //P2端口输出显示的段码
- delayms(2); //延时2毫秒
- P2=0; //P2端口输出低电平
- P1_1 =1; //P1.1输出高电平
-
- P1_2 =0; //P1.2输出低电平,位选使能
- P2=s7_table[(c)/10]; //P2端口输出显示的段码
- delayms(2); //延时2毫秒
- P2=0; //P2端口输出低电平
- P1_2 =1; //P1.2输出高电平
-
- P1_3 =0; //P1.3输出低电平,位选使能
- P2=s7_table[(d)%10]; //P2端口输出显示的段码
- delayms(2); //延时2毫秒
- P2=0; //P2端口输出低电平
- P1_3 =1; //P1.3输出高电平
- }
- void south_north_allow() //南北通行允许子程序
- {
- ew_red=0; //东西方向红灯亮
- ew_green=1; //东西方向绿灯熄灭
- ew_yellow=1; //东西方向黄灯熄灭
-
- sn_red=1; //南北方向红灯熄灭
- sn_green=0; //南北方向绿灯亮
- sn_yellow=1; //南北方向黄灯熄灭
- }
- void east_west_allow() //东西通行允许子程序
- {
- ew_red=1; //东西方向红灯熄灭
- ew_green=0; //东西方向绿灯亮
- ew_yellow=1; //东西方向黄灯熄灭
- sn_red=0; //南北方向红灯亮
- sn_green=1; //南北方向绿灯熄灭
- sn_yellow=1; //南北方向绿灯熄灭
- }
- void init0_timer0() //定时器0初始化子程序
- {
- TMOD=0X01; //定时器0设置为模式1
- TH0=(65536-50000)/256; //TH0装载初值
- TL0=(65536-50000)%256; //TL0装载初值
- ET0=1; //开启定时器中断
- EA=1; //开启CPU中断
- TR0=1; //启动定时器T0
- }
- void keyscan() //键盘扫描子程序
- {
- if(key_sourth_north==0) //判断南北通行控制按键是否按下
- {
- delayms(2); //延时2毫秒
- if(key_sourth_north==0) //再次判断南北通行控制按键是否按下
- {
- south_north_allow(); //调用南北通行子程序
- while(!key_sourth_north) display_time(); //南北通行时,
- //显示通行倒计时
- TR0=0; //南北通行结束,关闭定时器T0
-
- }
- }
- if(key_earth_west==0) //判断东西通行控制按键是否按下
- {
- delayms(2); //延时2毫秒
- if(key_earth_west==0) //再次判断东西通行控制按键是否按下
- {
- east_west_allow(); //调用东西通行子程序
- while(!key_earth_west) display_time(); //东西通行时,
- //显示通行倒计时
- TR0=0; //东西通行结束,关闭定时器T0
- }
- }
- if(all_not==0) //判断全部禁行按键是否按下
- {
- delayms(2); //延时2毫秒
- if(all_not==0) //再次全部禁行按键是否按下
- {
- TR0=0; //进入全部禁行子程序,关闭定时器T0
- ew_red=0; //东西方向红灯亮
- ew_green=1; //东西方向绿灯熄灭
- ew_yellow=1; //东西方向黄灯熄灭
- sn_red=0; //南北方向红灯亮
- sn_green=1; //南北方向绿灯熄灭
- sn_yellow=1; //南北方向黄灯熄灭
- }
- }
- if(key_earth_west_add==0) // 东西时间+1
- {
- delayms(200);
- if(key_earth_west_add==1)
- {
- east_weat_time=east_weat_time+1;
- time_flag=time_flag+1;
- }
- }
- if(key_earth_west_jian==0) //东西时间-1
- {
- delayms(200);
- if(key_earth_west_jian==1)
- {
- east_weat_time=east_weat_time-1;
- time_flag=time_flag-1;
- }
- }
- if(key_sourth_north_add==0) //南北时间+1
- {
- delayms(200);
- if(key_sourth_north_add==1)
- {
- sou_nor_time=sou_nor_time+1;
- time_flag=time_flag+1;
- }
- }
- if(key_sourth_north_jian==0) //南北时间-1
- {
- delayms(200);
- if(key_sourth_north_jian==1)
- {
- sou_nor_time=sou_nor_time-1;
- time_flag=time_flag-1;
- }
- }
- }
-
- void main() //主程序
- {
- sou_nor_time=15; //初始化南北通行时间为15秒
- east_weat_time=6; //初始化东西通行时间为6秒
- traffic_flag=0; //初始化,南北通行
- time_flag=sou_nor_time; //设置南北通行的时间
- time_multiply =0; //计时变量初始化
-
- init0_timer0(); //调用定时器T0初始化子程序
- south_north_allow(); //调用南北通行允许子程序
-
- while(1) // while(1)无限循环
- {
- keyscan(); //调用键盘扫描子程序
- display_time(); //调用显示倒计时子程序
- }
- }
- void int0_isr() interrupt 1 //定时器T0中断服务程序
- {
- TH0=(65536-50000)/256; //TH0装载初值
- TL0=(65536-50000)%256; //TL0装载初值
- time_multiply++; //计时变量加1
- if(time_multiply>=20) //判断计时变量是否大于20
- {
- time_multiply=0; //计时变量大于20,则把计时变量清零
- time_flag--; //倒计时的秒数减1
-
- if(traffic_flag==0) //若traffic_flag为0,则进入南北通行模式
- {
- if(time_flag>2) //南北通行倒计时进行中
- {
- south_north_allow();//南北通行红绿灯输出
- a=time_flag;
- b=time_flag;
- c=time_flag-3;
- d=time_flag-3;
- }
- else if(time_flag>0) //若倒计时时间小于2秒
- {
- sn_red=1;
- sn_green=1;
- sn_yellow=0; //此时南北黄灯亮2秒
- ew_red=0; //此时东西仍然是红灯亮
- ew_green=1;
- ew_yellow=1;
- a=time_flag;
- b=time_flag;
- c=0;
- d=0;
-
- }
- else
- {
- traffic_flag=1; //此时南北通行计时结束,改为东西通行模式
- time_flag= east_weat_time; //东西通行时间变量赋值
- }
- }
- if(traffic_flag==1) //此时为东西通行模式
- {
- if(time_flag>2) //东西通行计时未结束
- {
- east_west_allow(); //东西通行红绿灯输出
- c=time_flag; //北时间
- d=time_flag; //南时间
- a=time_flag-3; //西时间
- b=time_flag-3; //东时间
-
- }
- else if(time_flag>0)
- {
-
- ew_red=1; //此时东西黄灯亮2秒
- ew_green=1;
- ew_yellow=0;
- sn_red=0; //此时南北仍然是红灯亮
- sn_green=1;
- sn_yellow=1;
- c=time_flag;
- d=time_flag;
- a=0;
- b=0;
- }
- else
- {
- traffic_flag=0; //此时东西通行计时结束,改为东西通行模式
- time_flag= sou_nor_time; //南北通行时间变量赋值
- }
- }
- }
- else if(time_multiply>=10) //判断计时变量是否大于20
- {
- if(traffic_flag==0) //若traffic_flag为0,则进入南北通行模式
- {
- if(time_flag>2) //南北通行倒计时进行中
- {
- south_north_allow();//南北通行红绿灯输出
- }
- else if(time_flag>0) //若倒计时时间小于2秒
- {
- sn_red=1;
- sn_green=1;
- sn_yellow=1; //此时南北黄灯亮2秒
- ew_red=0; //此时东西仍然是红灯亮
- ew_green=1;
- ew_yellow=1;
- }
- else
- {
- traffic_flag=1; //此时南北通行计时结束,改为东西通行模式
- time_flag= east_weat_time; //东西通行时间变量赋值
- }
- }
- if(traffic_flag==1) //此时为东西通行模式
- {
- if(time_flag>2) //东西通行计时未结束
- {
- east_west_allow(); //东西通行红绿灯输出
- }
- else if(time_flag>0)
- {
-
- ew_red=1; //此时东西黄灯亮2秒
- ew_green=1;
- ew_yellow=1;
- sn_red=0; //此时南北仍然是红灯亮
- sn_green=1;
- sn_yellow=1;
- }
- else
- {
- traffic_flag=0; //此时东西通行计时结束,改为东西通行模式
- time_flag= sou_nor_time; //南北通行时间变量赋值
- }
- }
- }
- }
复制代码 |