基于51单片机的红绿灯模拟系统.docx

上传人:b****5 文档编号:3742906 上传时间:2022-11-25 格式:DOCX 页数:26 大小:255.21KB
下载 相关 举报
基于51单片机的红绿灯模拟系统.docx_第1页
第1页 / 共26页
基于51单片机的红绿灯模拟系统.docx_第2页
第2页 / 共26页
基于51单片机的红绿灯模拟系统.docx_第3页
第3页 / 共26页
基于51单片机的红绿灯模拟系统.docx_第4页
第4页 / 共26页
基于51单片机的红绿灯模拟系统.docx_第5页
第5页 / 共26页
点击查看更多>>
下载资源
资源描述

基于51单片机的红绿灯模拟系统.docx

《基于51单片机的红绿灯模拟系统.docx》由会员分享,可在线阅读,更多相关《基于51单片机的红绿灯模拟系统.docx(26页珍藏版)》请在冰豆网上搜索。

基于51单片机的红绿灯模拟系统.docx

基于51单片机的红绿灯模拟系统

 

基于增强型8051单片机的红绿灯模拟控制系统

 

2012年11月13日

目录

系统功能介绍2

1.1系统结构框图2

1.2各部分功能说明3

二、系统方案3

2.1系统设计与结构框图3

2.2方案论证与比较3

2.2.1虚拟仿真模块3

2.2.2控制器模块4

2.2.3交通灯显示模块5

2.2.4数码管显示模块6

2.2.5蜂鸣器模块8

2.2.6矩阵键盘模块8

三、方案不足与改进方案9

3.1控制器模块9

3.2显示输出模块(数码管模块、红绿灯模块)9

3.3输入模块(矩阵键盘模块)9

3.4拓展模块9

四、项目清单与注意事项10

4.1项目清单10

4.2注意事项10

4.2.1模拟仿真10

4.2.2连接电路10

4.2.3软件调试与故障排除10

五、程序代码10

附录、相关芯片资料21

74HC573中文资料21

摘要:

本系统是以STC公司的STC12C5A60S2单片机为主控制器,通过74HC573驱动4位数码管显示红绿灯倒计时,能实现红绿灯的模拟控制,并具有比较强的适应性和可调性。

关键词:

4×4矩阵键盘;STC12C5A60S2;74HC573。

系统功能介绍

1.1系统结构框图

1.2各部分功能说明

(1)红绿灯模块可以实现红绿灯系统的显示模拟,在黄灯亮时,另一个方向上的红灯会闪烁;

(2)数码管模块可以显示路口各个方向红灯、黄灯和绿灯的持续时间,并进行倒计时;

(3)矩阵键盘模块可以进行对倒计时时间的修改,修改的时间可由数码管显示;

(4)蜂鸣器在交通灯的状态发生改变时,会有不同的声音提示。

二、系统方案

2.1系统设计与结构框图

根据题目要求,本系统主要由虚拟仿真模块,控制器模块,交通灯显示模块,数码管显示模块,蜂鸣器模块,矩阵键盘模块组成。

2.2方案论证与比较

2.2.1虚拟仿真模块

我们决定先通过proteus软件仿真,设计好电路与程序,再动手焊接系统板。

因为通过软件仿真,设计系统时灵活性会大一些,可以提前选择好硬件,便于硬件部分的修改,也可以做到软件部分的即时调试。

仿真时的状况如图2-2所示:

图2-1Proteus软件欢迎界面

图2-2Proteus仿真情况

2.2.2控制器模块

控制器模块我们决定选择STC公司的STC12C5A32S2单片机。

STC12C5A60S2/AD/PWM系列单片机是STC生产的单时钟/机器周期(1T)的单片机,是高速/低功耗/超强抗干扰的新一代8051单片机,指令代码完全兼容传统8051,但速度快8-12倍。

内部集成MAX810专用复位电路,2路PWM,8路高速10位A/D转换(250K/S,即25万次/秒),针对电机控制,强干扰场合。

(《STC12C5A32S2系列单片机器件手册》);内部结构相对简单,可用作入门级芯片;而且我们手中已经有几块STC12C5A32S2系列单片机最小应用系统,便于硬件电路的焊接。

最小系统电路图参考图2-3:

图2-3最小系统电路图

2.2.3交通灯显示模块

方案一:

采用四组红黄绿三色二极管,通过10K的排阻分别连至单片机的P1.0-P1.6口,通过改变P1.1-P1.6的输出电平控制交通灯的亮灭。

缺点是占用I/O口较多,但易于编程控制;

方案二:

采用74HC573芯片控制四组发光二极管。

通过P0.0-P0.5向74HC573发送信号,P2中某一I/O口控制芯片的开启和关闭。

优点是能比较大的节约I/O口,缺点是会增加编程复杂度。

由于单片机的I/O口足够用来实现系统的基本功能,所以我们决定采用方案一。

如果之后扩展功能时还会需要更多的I/O口时,可以考虑换成方案二。

方案一的电路图如下:

图2-4交通灯模块电路图(方案一)

2.2.4数码管显示模块

方案一:

采用两片74HC595芯片驱动共阳极四位数码管。

一片控制段选,一片控制位选。

位选信号通过三极管9012放大。

优点是占用I/O口较少,但在仿真过程中出现了一些问题。

问题如下:

静态显示时数码管显示正常,但动态仿真时虽然单片机的各个引脚的电平变化正常,但位选信号(9012的基极输入信号)的一直为零。

更改限流电阻以后,数码管全部显示8。

经查阅资料,得知在程序和硬件电路正常显示的情况下,数码管不正常显示的原因,可能是因为数码管的响应时间过短,对PNP三极管的仿真速度太低。

资料中建议使用NPN型三极管,并将数码管的minimumTriggerTime值调高。

这也说明了仿真与硬件电路之间的不统一。

电路图如下图所示:

方案二:

采用两片74HC573芯片驱动共阴极四位数码管。

一片控制段选,一片控制位选。

通过P0口控制输出电平,故需要上拉电阻。

上拉电阻采用10K的排阻。

优点是软件控制比较简单,但相比方案一要占用更多的I/O口。

此方案在仿真时也出现了问题,即数码管显示乱码。

之后通过对数码管进行软件清屏的方法使数码管显示正常。

方案二的电路图如下图所示:

为了使硬件电路与仿真有较高的统一性,我们决定采用方案二。

图2-5数码管电路仿真图(方案一)

图2-6数码管电路仿真图(方案二)

2.2.5蜂鸣器模块

方案一:

通过控制蜂鸣器,使蜂鸣器发出不同的声音,指示交通灯路口的不同状态。

其优点是控制较为简易,缺点是通过蜂鸣器的发声,不同路口之间通行状态是通过蜂鸣器的不同频率的声音决定的,但不同频率的声音与不同方向的通行状态之间的对应关系不直观,交互性较差。

方案二:

通过ISD400x系列语音芯片,录放不同的声音,指示交通灯路口的不同状态。

其优点是可以让通行者直观的了解各个方向下一步的通行状态,有很强的交互性,缺点是硬件电路和软件控制较为复杂,占用较多的I/O口,而且与其他部分之间的时序比较难以协调。

由于本系统的制作本着仿真模拟的原则,暂时通过蜂鸣器来代替语音信息,但在以后的实验中可以考虑用ISD400x系列语音芯片代替蜂鸣器。

2.2.6矩阵键盘模块

根据题目要求,本系统最少三个按键就可以实现按键调节时间功能。

但为了更好的完成项目,和以后的功能拓展,我们决定采用4*4矩阵按键。

方案一:

通过P3口控制矩阵按键。

优点是易于编程,其缺点是占用过多的I/O口。

但由于按键在一般情况下都是断开的,所以同一个引脚还可以扩充其他功能。

其原理图如下图所示:

方案二:

采用改进型I/O端口键盘。

优点是I/O端口只占用4个,但在编程上复杂度增加。

其原理图如下图所示:

所以目前在I/O口比较充足的情况下,我们决定先采用方案一,在以后的改进工作中考虑将其换成方案二。

图2-7矩阵键盘仿真电路图(方案一)

三、方案不足与改进方案

3.1控制器模块

I/O口的利用情况较差。

在各引脚中,P0口和P2.6,P2.7用来控制74HC573驱动数码管,P2.0—P2.5用来控制红绿灯;P3控制按键;P1.0控制蜂鸣器,还有P1.1—P1.7没有用。

这几个口可以用来接更多的外设,比如AD模块等。

但在很多模块上,存在着引脚“浪费”的情况。

矩阵按键可以用四个I/O口实现,也可以用P0口的模数转化器ADC通道实现。

可以考虑把两片74HC573芯片换成功能更强大的MAX7219芯片;如果仍使用74HC573芯片的话,可以考虑将红绿灯模块也用该芯片驱动,这样只会再增加一个I/O口的使用。

3.2显示输出模块(数码管模块、红绿灯模块)

1、显示模块就占用了P1,P2的14个I/O口,使得系统的可改进程度降低。

可以考虑更换显示模块的驱动芯片,如3.1中所述,也可以将红绿灯与倒计时协调起来,用另外一片74HC573驱动。

2、倒计时方面,由于在各个方向上(除一个方向上亮黄灯,另一个方向上红灯闪烁外)倒计时的显示相同,在做仿真模拟时只选择了两位数码管进行倒计时显示。

在改进阶段,需要把黄灯亮,红灯闪烁的情况考虑进去,将数码管SEG1的剩余两位用上,SEG1的前两位和后两位分别显示不同方向上的倒计时。

3、做好倒计时模块以后,还有SEG2数码管没有用上。

可以考虑将其做成一个温度计,选择功能比较强大的如DS18xx数字化温度传感器,占用线口少、连接方便、测量精度高的传感器。

3.3输入模块(矩阵键盘模块)

1、4*4的矩阵键盘占用了P3口,限制了功能的拓展。

但按键在释放的状态下,P3口还是可以用来实现更多功能,只要按键不被按下,P3口的其他功能就不会受影响;

2、矩阵键盘16个按键目前为止只用了四个,分别是:

时间选择键、个/十位切换键、增加键、减小键。

但还有12个键没有使用。

这十二个键可以仿照小键盘的模式,分别对应0-9这十个数,另外两个键设定为紧急状态键。

3、若在之后的改进中存在I/O口不够用的情况,可以换成改进型I/O端口键盘。

3.4拓展模块

1、可以考虑用压力传感器模拟超载监测装置;

2、可以考虑用光敏电阻、ADC,DAC来制作可调光强的红绿灯。

四、项目清单与注意事项

4.1项目清单

(1)数码管显示模块:

74HC573,

(2)MCU控制模块:

STC12C5A32S2,IC座,LED,SPI插座等

(3)基本元器组件:

电阻、瓷片电容,电解电容,9012,8050,1N4007,排针,杜邦线,开关,导线

4.2注意事项

4.2.1模拟仿真

模拟仿真只是工具,仿真的目的是为了更好的制作硬件和辅助调试软件。

当程序和电路图没有问题时却得不到正确的仿真效果,应该考虑是不是仿真本身的问题;或者将该模块的硬件先搭出来,通过硬件电路调试。

不要过度的依赖仿真。

4.2.2连接电路

连接电路前尽量都要做出仿真实验,避免不必要的麻烦和损失(元器件烧坏等问题);做不出仿真的先手动搭出硬件电路,经测试成功后再焊接。

电路板可以选用一种多个金属环连接在一起的板子,减少焊接线的数量。

4.2.3软件调试与故障排除

如果在调试中出现问题,应考虑是硬件问题还是软件问题。

若是硬件问题,对照电路图检查连接是否有误;检查芯片是否坏掉;检查各焊点是否存在虚焊等接触不良的问题;若是软件问题,检查算法是否有误;还有编译器自身的问题。

五、程序代码

(本程序在proteus上已仿真成功)

#include"reg51.h"

#defineucharunsignedchar

#defineuintunsignedint

sbitdula=P2^6;//U2锁存器的锁存端

sbitwela=P2^7;//U3锁存器的锁存端

ucharcodetable[]=

{0x3f,0x06,0x5b,0x4f,

0x66,0x6d,0x7d,0x07,

0x7f,0x6f,0x77,0x7c,

0x39,0x5e,0x79,0x71,0x08};//最后一个是下划线,用来做闪烁

uintcodejiepai[]={524,262,293,330,349,392,440,494};//节拍

ucharcodeyindiao[]={55,110,98,87,82,73,65,58};//音谱

sbitP20=P2^0;//红绿灯的位定义

sbitP21=P2^1;

sbitP22=P2^2;

sbitP23=P2^3;

sbitP24=P2^4;

sbitP25=P2^5;

sbits1=P3^0;//定义按键,功能键

sbits2=P3^1;//定义按键,十位个位选择键

sbits3=P3^2;//定义按键,增大键

sbits4=P3^3;//定义按键,减小键

sbitrd=P3^7;

sbitfmq=P1^0;//蜂鸣器定义端

uchar

num1,//倒计时剩余时间,单位是秒

num2,//50ms计数标志位

shi,ge;//十位个位倒计时暂存变量

uchars1num;//按键功能判断标志,取值为1,2,3,4,分别对应两个方向的倒计时不同状态

uinttimer[4]={10,5,10,5};//数组,里面的数据是4种不同状态倒计时的时间

unsignedintm;//红灯闪烁延时

uintcnt=1;//状态切换标志

uintflag=0;//时间调整个位十位切换位

voiddelayms(unit);//延时函数声明

voiddisplay(uchar,uchar);//数码管显示函数声明

voidmatrixkeyscan();//扫描键盘函数

voidmove();//修改定位

voidsave_data(uint,uint);//保存数据

voidyanzou(ucharyindiao,uintjiepai);//蜂鸣器函数声明

/***************************************************************

函数功能:

主函数

****************************************************************/

voidmain(void)

{

num1=timer[0];

TMOD=0x01;//计时器设置

TH0=(65536-45872)/256;//计时器设置

TL0=(65536-45872)%256;//计时器设置

TR0=1;//计时器设置

ET0=1;//计时器设置

EX0=1;//emergency中断设置

IT0=1;//emergency中断设置

EA=1;//总开关

num1=timer[0];

shi=num1/10;//使数码管初始显示正确

ge=num1%10;

s1num=0;

rd=0;

while

(1)

{

matrixkeyscan();//在主函数中不停进行按键扫描

switch(cnt)

{

case1:

while

(1)

{

//状态1

matrixkeyscan();//在主函数中不停进行按键扫描

display(shi,ge);//数码管倒计时显示

P20=1;//红绿灯显示

P21=1;

P22=0;

P23=0;

P24=1;

P25=1;

if(cnt==2)

{

yanzou(yindiao[1],jiepai[1]/2);

yanzou(yindiao[2],jiepai[2]/2);

break;

}

}break;

case2:

while

(1)

{

//状态2

matrixkeyscan();//在主函数中不停进行按键扫描

display(shi,ge);

P20=1;

P21=0;

P22=1;

P23=1;

for(m=150;m>0;m--)

{

display(shi,ge);

}

P23=0;

for(m=150;m>0;m--)

{

display(shi,ge);

}

P24=1;

P25=1;

if(cnt==3)

{

yanzou(yindiao[2],jiepai[2]/2);

yanzou(yindiao[3],jiepai[3]/2);

break;

}

}break;

case3:

while

(1)

{

//状态3

matrixkeyscan();//在主函数中不停进行按键扫描

display(shi,ge);

P20=0;

P21=1;

P22=1;

P23=1;

P24=1;

P25=0;

if(cnt==4)

{

yanzou(yindiao[5],jiepai[5]/2);

yanzou(yindiao[6],jiepai[6]/2);

break;

}

}break;

case4:

while

(1)

{

//状态4

matrixkeyscan();//在主函数中不停进行按键扫描

display(shi,ge);

P21=1;

P22=1;

P23=1;

P24=0;

P25=1;

P20=1;

for(m=150;m>0;m--)

{

display(shi,ge);

}

P20=0;

for(m=150;m>0;m--)

{

display(shi,ge);

}

if(cnt==1)

{

yanzou(yindiao[6],jiepai[6]/2);

yanzou(yindiao[1],jiepai[1]/2);

break;

}

}break;

}

}

}

/***************************************************************

函数功能:

延迟cnt毫秒

****************************************************************/

voiddelay(longcnt)//闪烁延时函数

{

uinti,j;

for(i=cnt;i>0;i--)

for(j=110;j>0;j--);

}

/****************************************************************/

/*****************************************************************

函数功能:

将十位和个位数字送至数码管显示

******************************************************************/

voiddisplay(ucharshi,ucharge)//显示子函数

{

dula=1;

P0=table[shi];//送段选数据

dula=0;

P0=0xff;//*送位选数据前关闭所有显示,防止打开位选锁存时

wela=1;//原来的段选数据通过位选锁存器造成混乱*/

P0=0xfe;//送位选数据

wela=0;

delay

(1);//延时约1毫秒

P0=0x00;

dula=1;

P0=table[ge];

dula=0;

P0=0xff;

wela=1;

P0=0xfd;

wela=0;

delay

(1);

P0=0x00;

}

/*****************************************************************/

/****************************************************************

函数功能:

中断服务函数,可计算出送给数码管的数据

******************************************************************/

voidT0_time(void)interrupt1//时间延时函数

{

TH0=(65536-45872)/256;//计时器设置

TL0=(65536-45872)%256;//计时器设置

num2++;

if(num2==20)//如果到了20次,说明1秒时间已到

{

num2=0;//然后把num2清0重新再计20次

num1--;

shi=num1/10;//把一个2位数分离后分别送给数码管显示

ge=num1%10;//十位和个位

if(num1==0)

{//这个数用来送数码管显示,到60后归0

cnt++;

switch(cnt)

{

case1:

num1=timer[0];break;

case2:

num1=timer[1];break;

case3:

num1=timer[2];break;

case4:

num1=timer[3];break;

default:

cnt=1;num1=timer[0];break;

}

}

}

}

/*****************************************************************/

/****************************************************************

函数功能:

键盘扫描

******************************************************************/

voidmatrixkeyscan()

{

if(s1==0)

{

delay(5);

if(s1==0)

{

s1num++;

while(!

s1);

if(s1num==1)//绿灯时长

{

TR0=0;

move();//修改定位

shi=num1/10;//把一个2位数分离后分别送给数码管显示

ge=num1%10;//十位和个位

//shining();//修改闪烁

}

if(s1num==2)//黄灯时长

{

move();//修改定位

shi=num1/10;//把一个2位数分离后分别送给数码管显示

ge=num1%10;//十位和个位

//shining();//修改闪烁

}

if(s1num==3)//绿灯时长

{

TR0=0;

move();//修改定位

shi=num1/10;//把一个2位数分离后分别送给数码管显示

ge=

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 小学教育 > 语文

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1