基于单片机的交通灯信号控制器设计(含源程序和电路图)
设计一个基于单片机的交通灯信号控制器。已知东、西、南、北四个方向各有红黄绿色三个灯,在东西方向有两个数码管,在南北方向也有两个数码管。要求交通灯按照表1进行显示和定时切换,并要求在数码管上分别倒计时显示东西、南北方向各状态的剩余时间。
表1 交通灯的状态切换表
南北方向
东西方向
序号
状态
序号
状态
1
绿灯亮25秒,红、黄灯灭
1
红灯亮30秒,绿、黄灯灭
2
黄灯亮5秒,红、绿灯灭
3
红灯亮30秒,绿、黄灯灭
2
绿灯亮25秒,红、黄灯灭
3
黄灯亮25秒,红、绿灯灭
回到状态1
回到状态1
3.2.1模块1:系统设计
(1)任务分析与整体设计思路
试题要求实现的功能主要包括计时功能、动态扫描以及状态的切换等几部分。
计时功能:要实现计时功能则需要使用定时器来计时,通过设置定时器的初始值来控制溢出中断的时间间隔,再利用一个变量记录定时器溢出的次数,达到定时1秒中的功能。当计时每到1秒钟后,东西、南北信号灯各状态的暂存剩余时间的变量减1。当暂存剩余时间的变量减到0时,切换到下一个状态,同时将下一个状态的初始的倒计时值装载到计时变量中。开始下一个状态,如此循环重复执行。
动态扫描:需要使用4个数码管分别显示东西、南北的倒计时数字,将暂存各状态剩余时间的数字从变量中提取出“十位”和“个位”,用动态扫描的方式在数码管中显示。
整个程序依据定时器的溢出数来计时,每计时1s则相应状态的剩余时间减1,一直减到0时触发下一个状态的开始。
(2)单片机型号及所需外围器件型号,单片机硬件电路原理图
图3-5 交通灯硬件电路原理图
选用mcs51系列at89s51单片机作为微控制器,选择两个四联的共阴极数码管组成8位显示模块,由于at89s51单片机驱动能力有限,采用两片74hc244实现总线的驱动,一个74hc244完成共阴极数码管位控线的控制和驱动,另一个74hc244完成数码管的7段码输出,在7段码输出口上各串联一个100欧姆的电阻对7段数码管限流。用p3口的p3.0-p3.5完成发光二极管的控制,实现交通灯信号的显示,每个发光二极管串联500欧姆电阻起限流作用。硬件电路原理图如图3-5所示。
(3)程序设计思路,单片机资源分配以及程序流程
①单片机资源分配
单片机p3口的p3.0-p3.1引脚用作输出,控制发光二极管的显示。在计时模块中,需要定义两个数组变量(init_sn[3],init_ew[3])来存储东西、南北两个方向在不同状态中倒计时的初始值,题目中每个方向的交通灯共有3种显示状态,因此数组元素个数为3。还需要定义两个变量( cnt_ sn, cnt_ ew)暂存东西、南北两个方向的倒计时剩余时间。
在状态的切换中,为了明确当前处于哪种状态,东西、南北方向各设置一个状态变量(state_val_sn, state_val_ew),当倒计时的剩余时间到零时,状态变量增1,表示启动下一个状态,当该变量增到3时变为0,回到序号为1的状态。
②程序设计思路
在设计中,由于没有键盘功能,因此只涉及定时计数和动态扫描功能。主程序将变量初始化之
后,设置单片机定时器和中断特殊功能寄存器的初始值,将定时器t1的工作方式设置为8位自动
装载模式,定时器每隔250us产生一次溢出。
在初始化变量与寄存器后,主程序进入一个循环结构,在循环中只做动态扫描的工作,根据东西、南北两向的剩余时时间进行动态扫描显示。
计时以及状态的切换通过定时器的中断服务程序来实现,在中断服务程序中,每计时到一秒时,则各方向当前状态的剩余时间减1,一直减到0时触发下一个状态的开始,改变交通灯的指示。
③程序流程
(4)软硬件调试方案
软件调试方案:伟福软件中,在“文件\新建文件”中,新建c语言源程序文件,编写相应的程序。在“文件\新建项目”的菜单中,新建项目并将c语言源程序文件包括在项目文件中。
在 “项目\编译”菜单中将c源文件编译,检查语法错误及逻辑错误。在编译成功后,产生以 “*.hex”和“*.bin” 后缀的目标文件。
硬件调试方案:在设计平台中,将单片机的p3.0-p3.5分别与独立式键盘的相应位通过插线连接起来。
在伟福中将程序文件编译成目标文件后,运行“mcu下载程序”,选择相应的flash 数据文件,点击“编程”按钮,将程序文件下载到单片机的flash中。
然后,上电重新启动单片机,检查所编写的程序是否达到题目的要求,是否全面完整地完成试题的内容。
3.2.2 程序设计(仅供参考的c语言源程序)
//晶振:11.0592m t1-250微秒溢出一次
/*变量的定义:
show_val_sn,show_val_ew: 显示的值0-59
state_val_sn,state_val_ew: 状态值 南北方向0-绿灯亮;1-黄灯亮;2-红灯亮
t1_cnt: 定时器计数溢出数
cnt_sn,cnt_ew: 倒计时的数值
init_sn[3],init_ew[3] 倒计时
led_seg_code:数码管7段码
*/
#include reg51.h
sbit sn_green=p3^2 ;//南北方向绿灯
sbit sn_yellow=p3^1 ;//南北方向黄灯
sbit sn_red=p3^0 ;//南北方向红灯
sbit ew_green=p3^5 ;//东西方向绿灯
sbit ew_yellow=p3^4 ;//东西方向黄灯
sbit ew_red=p3^3 ;//东西方向红灯
unsigned char data cnt_sn,cnt_ew;
unsigned int data t1_cnt;
unsigned char data state_val_sn,state_val_ew;
char code led_seg_code[10]={0x3f,0x06,0x05b,0x04f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
char code init_sn[3]={24,4,29};
char code init_ew[3]={29,24,4};
//------------------------
void delay(unsigned int i)//延时
{ while(--i); }
//------------------------
void led_show(unsigned int u,unsigned int v)
{ unsigned char i;
i=u%10; //暂存个位
p0=led_seg_code[i];
p2=0xbf;
delay(100); //延时
i=u%100/10; //暂存十位
p0=led_seg_code[i];
p2=0x7f;
delay(100); //延时
i=v%10; //暂存个位
p0=led_seg_code[i];
p2=0xfe;
delay(100); //延时
i=v%100/10; //暂存十位
p0=led_seg_code[i];
p2=0xfd;
delay(100); //延时
}
//-------------------------
void timer1() interrupt 3 //t1中断
{ t1_cnt++;
if(t1_cnt>3999) //如果计数>3999, 计时1s
{ t1_cnt=0;
if (cnt_sn!=0) //南北方向计时
{ cnt_sn--; }
else
{ state_val_sn++;
if (state_val_sn>2) state_val_sn=0;
cnt_sn=init_sn[state_val_sn];
switch (state_val_sn) //根据状态值,刷新各信号灯的状态
{ case 0: sn_green=0 ;//南北方向绿灯
sn_yellow=1 ;//南北方向黄灯
sn_red=1 ;//南北方向红灯
break;
case 1: sn_green=1 ;//南北方向绿灯
sn_yellow=0 ;//南北方向黄灯
sn_red=1 ;//南北方向红灯
break;
case 2:sn_green=1 ;//南北方向绿灯
sn_yellow=1 ;//南北方向黄灯
sn_red=0 ;//南北方向红灯
break;
}
}
if (cnt_ew!=0) //东西方向计时
{ cnt_ew--; }
else
{ state_val_ew++;
if (state_val_ew>2) state_val_ew=0;
cnt_ew=init_ew[state_val_ew];
switch (state_val_ew) //根据状态值,刷新各信号灯的状态
{ case 0: ew_green=1 ;//东西方向绿灯
ew_yellow=1;//东西方向黄灯
ew_red=0 ;//东西方向红灯
break;
case 1: ew_green=0 ;//东西方向绿灯
ew_yellow=1 ;//东西方向黄灯
ew_red=1 ;//东西方向红灯
break;
case 2: ew_green=1 ;//东西方向绿灯
ew_yellow=0 ;//东西方向黄灯
ew_red=1 ;//东西方向红灯
break;
}
}
}
}
//-------------------------
main()
{//初始化各变量
cnt_sn=init_sn[0];
cnt_ew=init_ew[0];
t1_cnt=0;
state_val_sn=0; //启动后,默认工作在序号为1的状态
state_val_ew=0;
//初始化各灯的状态
sn_green=0 ;//南北方向绿灯亮
sn_yellow=1 ;//南北方向黄灯灭
sn_red=1 ;//南北方向红灯灭
ew_green=1 ;//东西方向绿灯灭
ew_yellow=1;//东西方向黄灯灭
ew_red=0 ;//东西方向红灯亮
//初始化51的寄存器
tmod=0x20;//用t1计时 8位自动装载定时模式
th1=0x19;//0x4b; //500微秒溢出一次; 250=(256-x)*12/11.0592 -> x= 230.4
tl1=0x19;
ea=1; //开中断
et1=1;
tr1=1; //开定时器t1
while(1)
{ led_show(cnt_sn,cnt_ew);}}
//主程序结束
微软新研究提出一个新的多任务深度神经网络模型——MT-DNN
IBM 大中华区技术高峰论坛:让混合云和人工智能“照进”认知型企业的现实
iPhone8要推出双卡双待?落后12年,酷派发图“欢迎”!
Camille bauer认证级电能质量监测解决方案
我国智能传感器产业将在技术创新和产业规模上取得重大突破
基于单片机的交通灯信号控制器设计(含源程序和电路图)
如何正确布设运算放大器的电路板
有关屏幕,最容易误导你的14个参数
弱电人,你还在和做工的PK吗?河姆渡智能建筑了解一下!
CEEASIA亚洲消费电子展:扶摇直上,共创美好科学发展前景
大联大推出基于安森美GS-065-011-1-L功率晶体管的65W PD电源方案
R&S新型毫米波变频器真正实现上限至325 GHz的网络分析
微软发布自研AI芯片——Azure Maia100
车载智能硬件,谁是花架子?哪些正中用户需求痛点
微软引入更多产品的Windows Update更新方式
赣锋锂业与安达科技达成合作,拟投建年产2万吨正极材料项目
虹科新闻 | 虹科与美国ATTO正式建立合作伙伴关系,携手致力于网络基础设施建设!
请问怎样去加密S7-GRAPH块呢
可穿戴医疗技术关键及典型参考设计集锦
紫光同创携全系列FPGA芯片惊艳亮相IDEE2023