资源描述
资料内容仅供您学习参考,如有不当之处,请联系改正或者删除。
单片机课程设计报告
单片机控制的交通灯控制系统设计
摘要
本设计是根据我们所学习的单片机课程, 按照大纲要求对我们进行的一次课程检验, 是进行单片机课程训练的必要任务, 也对我们掌握单片机应用有很大的帮助。掌握单片机技术是一门不可或缺的技术, 对我们将来的工作以及生活和学习都有很密切的联系。当今世界的发展是以科学技术为基础的, 微控技术在生产中所占的比重也越来越大。单片机的出现是近代计算机技术发展史上的一个重要里程碑。近年来, 随着电子技术和微机计算机的迅速发展, 单片机的档次不断提高, 其应用领域也在不断的扩大, 已在工业控制、 尖端科学、 智能仪器仪表、 日用家电、 汽车电子系统、 办公自动化设备、 个人信息终端及通信产品中得到了广泛的应用, 成为现代电子系统中最重要的智能化的核心部件。
我的这次单片机课程设计就是利用单片机的基本特点, 使用C语言实现一个简易的交通灯电路, 但由于能力的有限, 编出的程序只能实现课程设计的最基本的要求, 没有对其进行更多的扩展, 以后有能力的时候再去完善它。现就我这次课程设计的主要内容及主要方法概括一下。本设计设计的是一个交通灯控制系统, 以单片机为核心, 采用当前比较流行的AT89C51单片机, 对十字路口交通灯电路进行了仿真制作, 主要完成十字路口交通灯的红、 绿、 黄灯的点亮时间控制, 并模拟了两道均有车辆要求经过时、 一道有车辆要求经过时、 以及在紧急情况下三种状态下交通灯的时间控制方式。在模拟系统中, 采用了多组红、 黄、 绿三种发光二极管分别代表各车道上的红绿灯, 采用了数码管显示每种灯点亮的时间; 并采用了⑤个按钮开关来模拟系统要求的各种状态。在本次设计中, 程序并没有采用原来学习书本上的C语言编写, 程序仿真采用流行的PROTEUS软件, 和keil联合仿真, 方便调试程序和修改硬件, 结果证明方案的硬件设计正确, 程序也符合要求。
关键词: 单片机; 数码管; LED
目录
1 概述 - 4 -
1.1单片机认识 - 4 -
1.2 单片机的应用 - 4 -
1.3设计任务 - 5 -
2 系统总体方案及硬件设计 - 6 -
2.1交通管理的方案 - 6 -
2.2总体硬件设计 - 6 -
2.3系统时钟电路 - 7 -
2.4系统复位电路 - 7 -
2.5数码管显示电路 - 8 -
2.6路灯指示电路 - 8 -
2.7按键电路设计 - 9 -
3 软件系统设计 - 11 -
3.1设计思路及关键技术 - 11 -
3.2 软件流程 - 11 -
3.3 交通灯的设计程序说明 - 12 -
3.4 延时函数 - 12 -
3.5 延时函数 - 13 -
3.6 显示函数 - 13 -
3.7定时器0中断函数 - 13 -
4 Proteus软件仿真 - 15 -
4.1 Proteus软件仿真 - 15 -
4.2 南北路灯切换时仿真 - 15 -
4.3 紧急情况下的仿真 - 16 -
4.4东西紧急情况下的仿真 - 16 -
5 心得体会 - 17 -
参考文献 - 17 -
附1 源程序代码 - 18 -
附2 系统原理图 - 23 -
1 概述
1.1单片机认识
MCS-51单片机是Intel公司在1980年继MCS-48系列8位单片机之后推出的高档8位单片机。MCS-51单片机在性能和片内功能方面大大优于MCS-48系列单片机。
MCS-51的典型产品有: 8051、 8031、 8751、 80C51、 80C31、 87C51等, 8051内部有4kB ROM, 8751内部有4kB EPROM, 8031片内无ROM。除此之外, 三者的内部结构及引脚完全相同。
89S51是一种低功耗、 高性能CMOS8位微控制器, 具有4K 在系统可编程Flash 存储器。使用Atmel 公司高密度非易失性存储器技术制造, 与工业80C51 产品指令和引脚完全兼容。片上Flash允许程序存储器在系统可编程, 亦适于常规编程器。在单芯片上, 拥有灵巧的8 位CPU 和在系统可编程Flash, AT89S51为众多嵌入式控制应用系统提供高灵活、 超有效的解决方案。
1.2 单片机的应用
单片机是应工业测控需要而产生的, 最能反映其功能及形态的名称是在一个应用系统中, Single-chip Micro-controller。按照测控系统的特点和要求, 单片机的应用可分为单机应用和多机应用两大类。我们这次要完成的单片机课程设计就是它的单机应用, 下面在介绍一下单片机在单机应用领域内的主要内容。
( 1) 智能产品
单片机与传统机械产品相结合, 使传统机械产品结构简化, 控制智能化, 购成新一代机电一体化产品。当前, 利用单片机构成的智能产品已广泛应用于家用电器、 办公设备、 数控机床、 纺织机械、 工业设备等行业。
( 2) 智能仪表
当前, 各种传感器、 变送器、 控制仪表已普遍采用单片机应用系统。它集测量、 处理、 控制功能于一体, 具有各种智能化功能, 如存储、 数据处理、 查找、 判断、 联网和语音等功能。
单片机构成的智能仪表, 能使仪表具有数字化、 智能化、 多功能化、 综合化、 柔性化等优点, 赋予测量仪表以崭新的面貌, 使传统的仪器、 仪表发生根本性的变革, 它代表了仪器仪表的发展趋势。
( 3) 测控技术
用单片机构成的各种工业控制系统中的数据采集系统具有工作稳定可靠、 抗干扰能力强的优点, 如炉温恒温控制系统、 电镀生产自动控制系统等。
( 4) 智能接口
在计算机系统, 特别是较大型的工业测控系统中, 除通用外部设备外, 还由许多外部通信、 采集、 多路分配管理、 驱动控制等接口。这些外部设备与接口如果完全由主机进行管理, 势必会造成主机负担过重, 运行速度降低, 接口的管理水平也不可能提高。如果用单片机进行接口的控制与管理, 单片机与主机可并行加工处理, 能够大量降低接口的通信密度, 极大的提高了接口控制管理水平。在一些通用计算机外部设备上, 已实现了单片机的键盘管理、 打印机控制、 绘图仪控制、 硬盘驱动控制等。
1.3设计任务
(1) 当东西方向为红灯, 此道车辆禁止通行, 东西道行人可经过; 南北道为绿灯, 此道车辆经过, 行人禁止通行。通行时间为60秒
( 2) 黄灯闪烁2秒, 警示车辆和行人红、 绿灯状态即将切换。
( 3) 当东西方向为绿灯, 此道车辆通行; 南北方向为红灯, 南北道车辆禁止通行, 行人通行。时间为90秒。东西方向车辆打通行时间长。
( 4) 这样如上表的时间和红、 绿、 黄出现的顺序依次处出现这样行人和车辆就能安全畅通的通行。
( 5) 此表可根据车辆动态设定红绿灯初始值。
2 系统总体方案及硬件设计
2.1交通管理的方案
A、 B两干道交于一个十字路口, 各干道有一组红、 黄、 绿三色的指示灯, 指挥车辆和行人安全通行。红灯亮禁止通行, 绿灯亮允许通行。黄灯亮提示人们注意红、 绿灯的状态即将切换, 且黄灯燃亮时间为A、 B两干道的公共停车时间。设A道比B道的车流量大, 指示灯燃亮的方案如表2-1-1。
1
4
1
5
1
4
……
A道
黄灯亮
红灯亮
黄灯亮
绿灯亮
黄灯亮
红灯亮
……
B道
黄灯亮
绿灯亮
黄灯亮
红灯亮
黄灯亮
绿灯亮
……
表2-1-1
说明:
( 1) 当为黄灯时 A、 B两道同时为黄灯; 以提示行人或车辆下一个灯色即将到来 时间 1秒。
( 2) 当A到为红灯, A 道车辆禁止通行, A 道行人可经过; B 道为绿灯, B 道车辆经过, 行人禁止通行。时间为4秒。
( 3) 当A道绿灯, A 道车辆通行; B 道为红灯, B 道车辆禁止经过, 行人通行。时间为5秒。 A道车流大 通行时间长
( 4) 这样如上表的时间和红、 绿、 黄出现的顺序依次出现这样行人和车辆就能安全畅通的通行。
( 5) 此表可根据车流量动态设定
在没有特殊情况下, 即在两道均有车辆要求经过时, 交通灯按常规运行。经过控制开关能够输入要模拟的其它状态, 交通灯将按照其输入状态的情况进行运行。
2.2总体硬件设计
交通灯控制系统的结构框图如图2-2-1所示。总体设计方案共有五个部分组成, 分别是: 单片机AT89C51、 红、 绿、 黄灯显示电路、 LED数显时间电路、 晶振及复位控制电路、 控制与调时开关电路。在进行仿真调试过程中, 程序运行正确, 五个部分就同时工作, 从而实现了交通灯的基本功能及调时功能。系统的总的原理框图如图2-1所示。
图2-2-1 硬件设计方案
2.3系统时钟电路
晶振采用了内部时钟信号源的方式。对于时间要求不是很高的系统, 只要按图进行设计就能使系统可靠起振并稳定运行。但由于图中的C1、 C2电容起着系统时钟频率微调和稳定的作用, 因此, 在本系统的实际应用中一定要注意正确选择参数( 30±10 PF) , 并保证对称性( 尽可能匹配) 。
图2-3-1 系统时钟电路
2.4系统复位电路
复位电路我采用上电+按钮复位的方式。当开关打开时, RST经过电阻接地, 当有开关闭合时由于电容的作用使电源VCC经过电阻施加在单片机复位端RST上, 实现单片机复位。只是可惜, 在进行仿真器调试过程中, 该复位电路是不起作用的。具体电路如图2-4-1所示。
图2-4-1 系统复位电路
2.5数码管显示电路
数码管工作原理 这里我们介绍8段数码管的工作原理。8段数码管又称为8字型数码管, 分为8段: A、 B、 C、 D、 E、 F、 G、 DP。其中, DP为小数点。数码管常见的有10根管脚, 每一段有一根管脚, 另外两根管脚为一个数码管的公共段, 两根之间相互连通。
发光二极管的发光原理, 我们已经介绍过了, 同理, 8段LED数码管, 则是在一定形状的绝缘材料上, 利用不同形状点划的发光二极管组合, 排列成”8”字型的数码管, 分别引出它们的电极, 点亮相应的点划来显示0-9的数字。
从电路上, 按数码管的接法不同又分为共阴和共阳两种。图2-5-1是共阴和共阳极数码管的内部电路, 它们的发光原理是一样的, 只是它们的电源极性不同而已。
图2-5-1 数码管的内部电路接法
在设计时, 为了系统图的美观, 我采用了6个数码管组成的数码管组, 采用共阴极接法。如图2-5-2。
图2-5-2 系统数码管电路
2.6路灯指示电路
在设计路灯时, 采用了发光二极管代替路灯。先介绍一下二极管, 见图 2-6-1。二极管工作原理是单向导通, 即只有正极电压高于负极电压某特定值时才会导通, 而负极电压高于正极电压是不导通的。
图 2-6-1 发光二极管示意图
发光二极管是一种特殊的二极管, 导通时会发光( 发光二极管导通压降一般为1.7V~1.9V) 。另外, 工作电流要满足该二极管的工作电流。
发光二极管的正负极能够用万用表进行判断, 把万用表拨至二极管档或电阻挡, 用两个表笔分别接触二极管的两个引出脚。若发光二极管被点亮, 则与红表笔相接的引出脚为正极。从外观上看, 发光二极管的正极引脚的长度也比较长。
一般发光二极管与I/O端口之间都会再连接一个电阻, 其作用在于限制经过二极管的电流, 从而达到减少功耗或者满足端口对最大电流的限制。一般发光二极管的点亮电流为5mA至10mA。
路灯设计时我采用了红、 黄、 绿三种发光二级管。如图2-6-2所示。
图2-6-2 路灯设计电路
2.7按键电路设计
按键工作方式能够是中断方式也能够是扫描方式, 对扫描方式来说, 扫描是一直调用按键扫描程序, 也能够用定时调用按键扫描程序, 不论哪一种, 都需要占用系统宝贵的时间资源, 相比较而言中断就有优势, 中断键盘只有在有按键按下时才去执行键盘程序, 在没有按键按下的情况下, 能够处理其它的事务, 使资源得到充分的利用, 故中断键盘有占用资源少, 响应速度快的优点, 但在有按键按下时有数码管闪烁的缺点, 这是因为处理中断时, 数码管停止了扫描, 对显示要求不高的场合下, 这也是完全能够满足要求的。但实际应用中, 为了保证安全查询键值和响应, 一般还要进行按键去抖和等待键释放( 查询按键是否抬起) 的动作, 由于按键本身是机械开关, 因此在触点闭合或断开的瞬间会出现电压抖动的现象。按键设计如图2-7-1所示。
图2-7-1 按键电路
3 软件系统设计
3.1设计思路及关键技术
一个完整的交通灯相当于一个简单的单片机系统, 该系统有交通灯设置电路、 单片机、 显示电路等构成。单片机是集成的IC芯片, 只需根据实际设计要求选型。其它部分都需要根据应用要求和性能指标自行设计。首先了解实际交通灯的变化规律。假设一个十字路口为东西南北走向。初始状态0为东西红灯, 南北红灯。然后转状态1南北绿灯通车, 东西红灯。过一段时间转状态2, 南北绿灯闪几次转亮黄灯, 延时几秒, 东西依然红灯。再转状态3, 东西绿灯通车, 南北红灯。过一段时间转状态4, 东西绿灯闪几次转亮黄灯, 延时几秒, 南北依然红灯。最后循环至状态1。
3.2 软件流程
系统总体流程图如图3-2-1所示:
图3-2-1整体软件设计流程图
3.3 交通灯的设计程序说明
这部分中定义了一些全局变量的数组和变量以及位标志, 只是些定义的东西不需要画流程图了。这部分程序如下:
#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int
sbit nom=P3^7;
uchar code led_table[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
//显示数码表
uchar code light_state[]={0x21,0x12,0x0c,0x12};//交通灯状态存储表
uchar code em_state[3]={0x24,0x21,0x0c};//紧急灯状态显示表
uchar light_time[][2]={{0,4},{0,1},{0,5},{0,1}};//显示时间存储表
uchar statebef,time1s=100,state=0;//存储紧急灯状态, 定时基数, 状态基数
uint time;//显示时间变量
bit md_flag,state_flag=1,red;//显示时间更改状态, 状态切换标志位, 红绿切换标志位
定义局部变量i, j
i--
j--
j<100
i==100
j==100
i<100
y
y
N
N
3.4 延时函数
延时函数的流程图如图3-4-1。
延时程序如下:
/*--------------------------------
延时函数
------------------------*/
void delay(void)
{
uchar i,j;
for(i=100;i>0;i--)
{ for(j=100;j>0;j--); //循环10000次
}
}
图3-4-1 延时函数的流程图
3.5 延时函数
读状态函数的流程图如图3-5-1。
定义局部变量
value
读P3口状态
value右移4位
取value低三位
状态改变?
return 0
return 1
Y
N
statebef=value
读状态函数如下:
/*--------------------------
读状态函数: 判断是否有紧急灯状况出现
---------------------*/
uchar rd_emstate(void)
{
uchar value;
value=P3;
value>>=4;
value&=0x07;
if(value!=statebef){statebef=value;return 1;}
//判断是否有紧急灯状况发生,
//保存按键值, 置返回标志为1
else return 0;
}
3.6 显示函数
显示函数如下:
void display(void)
{
if(md_flag==1)//显示更改时间状态
{
if(1==red) {// 南北方向红灯时间显示
P2=0xf6; P0=led_table[light_time[0][0]];delay();//分钟
P2=0xed; P0=led_table[light_time[0][1]/10];delay();//秒的十位
P2=0xdb; P0=led_table[light_time[0][1]%10];delay();//秒的个位
}
……
else //正常状态, 显示时间
{
P2=0xf6; P0=led_table[time/100]; delay();//分钟
P2=0xed; P0=led_table[time/10%10];delay();// 秒的十位
P2=0xdb; P0=led_table[time%10]; delay();//秒的个位
} }
3.7定时器0中断函数
定时器0中断函数如下:
void Time0int(void) interrupt 1
{ EA=0;
TH0=-10000/256;
TL0=-10000%256;
time1s--;
if(time1s==0){//一秒中到, 重新置数
time1s=100;
time--;//显示时间自减
if(time==0){//显示时间减到0时切换显示时间状态
state++;//四个状态轮流切换
if(state==4) state=0;
state_flag=1;//置状态切换标志位
} } EA=1; }
4 Proteus软件仿真
4.1 Proteus软件仿真
Proteus软件用于系统的仿真, 编译软件采用keil UV3。程序的仿真用英国的labcenter公司的Protens V7.13。其果如下: 加电后的结果如图4-3-1。此时时间已经走过一秒, 南北是红灯, 东西是绿灯。
图4-3-1 加电后仿真
4.2 南北路灯切换时仿真
切换时, 转为黄灯亮, 时间为一秒钟。如图4-2-1。
图4-2-1 黄灯亮时
4.3 紧急情况下的仿真
此时, 全部为红灯, 所用车辆禁行, 时间被锁定, 此时允许特殊车辆经过。如图4-3-1。
图4-3-1 紧急情况下的路灯显示
4.4东西紧急情况下的仿真
此时, 南北为红灯, 东西为绿灯, 南北车辆禁行, 东西能够经过。时间被锁定, 此时允许东西车辆经过。如图4-4-1。
图4-4-1 东西紧急情况下的路灯显示
5 心得体会
经过此次课程设计让我能够亲身参与电子产品的设计使我更加深深地体会到: 现代的社会是信息的社会, 很多与人们生活紧密相关的产品都是电子产品。要熟练地掌握单片机的基本知识, 这样才能对试验中出现的问题进行分析解决。经过这次对交通灯系统的设计, 我们掌握了设计一个实用装置电路的基本方法和基本步骤, 掌握了实用装置工作的基本原理, 实际解决了设计中出现的问题, 增强了寻找问题, 解决问题的能力。此次电子设计的成功不但帮助我们更好地掌握书本知识, 特别重要的是增强了我们的自信, 培养了我们独立思考的能力!
经过这周紧张而充实的课程设计, 我学到了很多东西, 让我重新认识自己, 收益匪浅, 并对我以后所要做的毕业设计有了一个初步的了解。做好一个课程设计或毕业设计不但要具备扎实的书本知识并会善于应用, 还要学会查阅资料, 对以前学过的知识不清楚的地方还要进行复习, 实在搞不明白的地方要向老师或同学请教, 这样才可能做出一个比较不错的课程设计。在这里我要感谢我们的指导老师, 非常感谢老师的指导和帮助。希望以后还能参加这样的课程设计。我想我会做的更好的。
参考文献
[1]余发山.单片机原理及应用技术.中国矿业大学.
[2]李朝青.单片机原理及接口技术( 修订版) .北京: 北京航空航天大学出版社, 1998
[3]李广弟.单片机基础.北京: 北京航空航天大学出版社, 1992
附1 源程序代码
#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int
sbit nom=P3^7;
uchar code led_table[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//显示数码表
uchar code light_state[]={0x21,0x12,0x0c,0x12};//交通灯状态存储表
uchar code em_state[3]={0x24,0x21,0x0c};//紧急灯状态显示表
uchar light_time[][2]={{0,4},{0,1},{0,5},{0,1}};//显示时间存储表
uchar statebef,time1s=100,state=0;//存储紧急灯状态, 定时基数, 状态基数
uint time;//显示时间变量
bit md_flag,state_flag=1,red;//显示时间更改状态, 状态切换标志位, 红绿切换标志位
/*--------------------------------
延时函数
------------------------*/
void delay(void)
{
uchar i,j;
for(i=100;i>0;i--)
{
for(j=100;j>0;j--);
}
}
/*--------------------------
读状态函数: 判断是否有紧急灯状况出现
---------------------*/
uchar rd_emstate(void)
{
uchar value;
value=P3;
value>>=4;
value&=0x07;
if(value!=statebef){statebef=value;return 1;}//判断是否有紧急灯状况发生, 保存按键值, 置返回标志为1
else return 0;
}
/*------------------------
显示函数
----------------------*/
void display(void)
{
if(md_flag==1)//显示更改时间状态
{
if(1==red) {// 南北方向红灯时间显示
P2=0xf6; P0=led_table[light_time[0][0]];delay();//分钟
P2=0xed; P0=led_table[light_time[0][1]/10];delay();//秒的十位
P2=0xdb; P0=led_table[light_time[0][1]%10];delay();//秒的个位
}
else {//南北绿灯东西红灯亮时间显示
P2=0xf6;P0=led_table[light_time[2][0]]; delay();//分钟
P2=0xed;P0=led_table[light_time[2][1]/10]; delay();//秒的十位
P2=0xdb;P0=led_table[light_time[2][1]%10]; delay();//秒的个位
}
}
else //正常状态, 显示时间
{
P2=0xf6; P0=led_table[time/100]; delay();//分钟
P2=0xed; P0=led_table[time/10%10];delay();// 秒的十位
P2=0xdb; P0=led_table[time%10]; delay();//秒的个位
}
}
/*---------------------------
主函数
--------------------*/
void main()
{
//初始化定时器0, 外部中断1
EA=1;
EX1=1;
IT1=1;
ET0=1;
TMOD=0x01;
TH0=-10000/256;
TL0=-10000%256;
TR0=1;
while(1){
if(rd_emstate())//如果有紧急灯按下, 进行如下紧急处理
{
switch(statebef)
{
case 0x04:P1=em_state[0];TR0=0;break;//紧急灯亮
case 0x02:P1=em_state[1];TR0=0;break;//东西应急灯亮
case 0x01:P1=em_state[2];TR0=0;break;//南北应急灯亮
case 0x00:TR0=1;break;
default: break;
}
}
if(state_flag)//正常状态下时间切换, 如果状态标志为1, 进行如下处理, 进行状态间切换
{
switch(state)
{
case 0:time=light_time[0][0]*60+light_time[0][1];
P1=light_state[0];break;//南北红灯亮时间
case 1:time=light_time[1][0]*60+light_time[1][1];
P1=light_state[1];break;//黄灯亮时间
case 2:time=light_time[2][0]*60+light_time[2][1];
P1=light_state[2];break;//南北绿灯亮时间
case 3:time=light_time[1][0]*60+light_time[1][1];
P1=light_state[1];break;//黄灯亮时间
default: break;
}
state_flag=0;//清标志位
}
if(nom==0) { md_flag=0;}//恢复时间状态, 更改为最近更改的值
display();
}
}
/*-----------------
定时器0
--------------------*/
void Time0int(void) interrupt 1
{
EA=0;
TH0=-10000/256;
TL0=-10000%256;
time1s--;
if(time1s==0){//一秒中到, 重新置数
time1s=100;
time--;//显示时间自减
if(time==0){//显示时间减到0时切换显示时间状态
state++;//四个状态轮流切换
if(state==4) state=0;
state_flag=1;//置状态切换标志位
}
}
EA=1;
}
/*---------------------
外部中断1
----------------------*/
void Exint1(void) interrupt 2
{
EA=0;
md_flag=1;//置更改时间标志位
if(red)
{
switch(P3&0X07)
{
case 6: light_time[0][1]++;
if(light_time[0][1]==60) light_time[0][1]=0;break;//南北方向绿灯时间 秒加 小于60s
case 5: light_time[0][0]++;
if(light_time[0][0]==10) light_time[0][0]=0;break;//分加 小于10m
case 3: red=0;break;//红绿灯切换
}
}
else
switch(P3&0X07)
{
case 6: light_time[2][1]++;
if(light_time[2][1]==60) light_time[2][1]=0;break;
//南北方向红灯时间 秒加 小于60
case 5: light_time[2][0]++;
if(light_time[2][0]==10) light_time[2][0]=0;break;//分加 小于10
case 3: red=1;break;//红绿灯切换
}
EA=1;
}
附2 系统原理图
展开阅读全文