此次综合设计为模拟交通灯控制系统,是采用计算机通过编写汇编语言程序控制实验箱上的硬件资源实现的。红灯停,绿灯行的交通规则,广泛用于十字路口,车站, 码头等公共场所,成为人们出行生活中不可少的必需品,由于计算机技术的成熟与广泛应用,使得交通灯的功能多样化,远远超过老式交通灯, 交通灯的数字化给人们生产生活带来了极大的方便,而且大大地扩展了交通灯的功能。诸如闪烁警示、鸣笛警示,时间程序自动控制、倒计时显示,所有这些,都是以计算机为基础的;还可以根据主、次干道的交通状况的不同任意设置各自的不同的通行时间。
因此,在本设计中将采用Intel 8086系列CPU交通控制系统来实现。 整个交通灯控制系统由8086CPU、交通灯显示、键盘扫描、紧急处理、时间模式手动设置等模块组成。系统除基本交通灯功能外还具有通行时间手动设置、可倒计时显示、急车强行通过等相关功能。
1、东西方向和南北方向交替准行控制:
东西方向准行时,东西方向上的绿灯亮,南北方向红灯亮,经过一段时间后,南北方向准行,南北方向上的绿灯亮,东西方向红灯亮,如此交替。各方向信号灯顺序为:红→绿→黄→红→绿→黄……,某一方向红灯亮的时间等于另一方向绿灯和黄灯亮的时间之和。
2、各方向红、绿灯亮的时间为11~ 99秒(可灵活的任意设定),以满足不同交通路口的需要。
3、当准行时间倒计时到最后10秒时,准行方向上绿灯灭,同时该方向的黄灯变为闪烁。
4、各方向要有两位数码管分别显示准行时间或禁行时间,并以秒倒计时。
5、设置功能按键:
1)在发生交通事故时,东西方向和南北方向同时禁行。
2)强制东西方向通行。
3)强制南北方向通行。
4)恢复正常交替通行。
综合利用实验箱上的资源,利用8254单元输入1MHz的时钟信号,连接MIR7定时向控制系统发出中断信号,实现倒计时的功能,通过8255单元控制的键盘及数码管显示单元,动态扫描通行时间的变化以及功能键模式下的显示,实时扫描键盘的输入,通过软件处理的方式,实现各个键盘的处理,开关及LED显示单元则来用显示交通灯的变化,B口输出数码管段码,A口与C口共同控制数码管的位选、键盘扫描以及LED灯的亮灭。
如图1,是实现整个交通灯控制系统的接线图:
图1 实验接线图
2.1 8086CPU
2.2 可编程并行接口芯片——8255A
2.3 可编程计数/定时器芯片——8254
2.4 可编程中断控制器——8259A
3.1设计总流程图:
3.2初始化流程图:
3.3按键处理流程图:
3.4显示流程图:
3.5 按键扫描流程图:
3.6 中断流程图
根据接线图,将系统总线与8255单元、键盘及数码管显示单元、开关及LED显示单元连接,编写程序,扫描键盘输入,并将扫描结果进行处理后送数码管显示。
实验具体内容如下:将键盘进行编号,记作0~F,当按下其中一个按键时:
①数字键“0~9”: 仅在设置通行时间时按键有效(设置键:“D”),实现通行时间设置的组合,数码管实时显示“XX——XX”(XX表示预设的时间)
②功能键“A”: 东西方向和南北方向同时禁行,数码管显示“888888”,东西方向和南北方向都亮红灯。
③功能键“B”: 强制东西方向通行,数码管显示“888888”,东西方向亮绿灯,南北方向亮红灯。
④功能键“C”: 强制南北方向通行,数码管显示“888888”,南北方向亮绿灯,东西方向亮红灯。
⑤设置键“D”:按一下可以对东西方向进入通行时间设置,再按一下对南北方向进入通行时间设置
⑤确定键“E”:将时间预设值修改,不符要求的方向不更改,按下后进入正常状态。
⑥取消键“F”:退出时间设置模式和功能键模式
PC机一台,TD-PITE实验装置一套
按要求接好线并下载程序后,能够正常实现交通灯的显示与功能键的启用,但在通行时间的设置上仍有一些问题:
①本应显示交通灯状态“-”“_”“¯”的数码管不按预想中的显示;
②数码管显示的顺序与预想中的相反
解决办法:
①经过检查,是在存数码管段码的数组中,将A~F的也写了进去,对应“-”“_”“¯”的段码无法对应上去,把A~F的段码删去后正常显示。
②经过检查,是数码管的扫描与取段码的顺序不一致,所以只需要把动态扫描的顺序更换一下就可以,修改后正常显示。
此次综合设计可以说是获益匪浅。通过在图书馆和互联网上查阅了很多相关资料,了解到了许多汇编程序的思想,扩展了自己的视野,不再仅仅局限于书本中几条简短的程序,而且更重要的是明白写程序的态度:仔细谨慎,精益求精。
在明白整个系统的工作流程后,我就开始一个代码一个代码地敲,从基本程序开始逐步添加功能,在没有实验环境的情况下,仔细地推敲自己的程序,把一个个例程打印出来做好笔记,用纸演算,综合处理较多的是按键处理和数码管模块,以及利用有限的I/O实现交通灯LED的开关模块显示。在按键处理中,运用合理的公式将数字键组成(11~99)的数字,利用计数器原理实现不同按键功能的切换;在数码管模块中,要根据不同的时间状态显示不同的字符,在实现动态扫描的同时,保留开关模块的LED交通灯状态,学会了让某一位置数或复位的技巧。
现实是骨感的,再好的程序也需要去检验,在实验室调试过程中,首先就要排除语法错误等的错误,一些小的细节自己也无法即时检查出来,在系统加电调试中,针对一些问题,将错误之处缩小在最小范围内,通过后期一次次的排查终于将整个系统完善好。
这次设计,我把学过的计算机编译原理的知识强化,能够把课堂上学的知识通过自己设计的程序表示出来,加深了对理论知识的理解。以前对微机原理与系统的认识是模糊的,概念上的,现在通过自己动手做实验,从实践上认识了微机系统是如何处理命令的,如何协调各个部件运行,对微机编译原理的认识更加深刻。
最后,综合所学微机原理与接口技术相关软件、硬件知识,并应用基础实验所获得的实验设计技能,独立设计解决实际应用问题的系统。
/***********************************************************
* 文件名: Traffic_Light.c
* 功能描述: 使用8255、8253及8259完成交通灯综合设计实验
**********************************************************
* 8255的B口为数码管的段驱动
* A口 PA0~PA5 为数码管位驱动
* A口 PA0~PA3 为列扫描
* C口 PC0~PC3 为行扫描
* A口 PA6~PA7 PC口为黄灯,方便置数/复位
* C口 PC4 为东西方向指示灯 PA7-红,PA6-绿,PC4-黄
* C口 PC5~PC7 为南北方向指示灯 PC7-红,PC6-绿,PC5-黄
* 按下按键,对应功能会被执行。
********************************************************/
#include
#include
#define uchar unsigned char
//8254端口地址IOY3 接1MHz的CLK
#define M8254_A 0x6c0
#define M8254_B 0x6c2
#define M8254_C 0x6c4
#define M8254_CON 0x6c6
//8255端口地址IOY0
#define MY8255_A 0x0600
#define MY8255_B 0x0602
#define MY8255_C 0x0604
#define MY8255_MODE 0x0606
#define Rdata(port) inportb(port)
#define Wdata(port, x) outportb(port, x)
//晶振:12MHz
void dis(void);
void clear(void); //清屏
void ccscan(void); //按键扫描
void getkey(void); //获取键值key_num
void delay(int time);
void Initial(void);
void Ini_Interrupt(void);
void Ini_Timer(void);
void Button_Pro(void);
void EW1_update(void); //东西绿南北红
void EW2_update(void); //东西黄南北红
void SN1_update(void); //东西红南北绿
void SN2_update(void); //东西红南北黄
void set_update(void); //更新设置时应显示的值
/******************************
变量、控制位定义
******************************/
uchar EW=12,SN=15; //初始化交通灯通行时间
/* 交通灯端口定义
#define EW_red PA7:X0000000b
#define EW_green PA6:0X000000b
#define EW_yellow PC4:000X0000b
X=1,亮 X=0,灭
#define SN_red PC7:X0000000b
#define SN_green PC6:0X000000b
#define SN_yellow PC5:00X00000b */
uchar EW_SN; //功能键标志
uchar EW_EN;
uchar SN_EN;
uchar TIME_SET; //设置键标志
uchar EW_TEMP;
uchar SN_TEMP;
char Time_EW; //东西方向计时变量
char Time_SN; //南北方向计时变量
// 数码管显示对应值代码
char a[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66,
0x6d, 0x7d, 0x07, 0x7f, 0x6f,
0x01, 0x40, 0x08};
//最后3位是用数码管表示的东西南北方向红绿灯状态,分别是红"ˉ"、黄"-"、绿"_"
//每0.5s进入一次中断,表示1Hz的方波时钟信号的电平,用给黄灯当闪烁频率
uchar count=0;
//设置模式下存放要显示的值,与a[]配合使用
char SET_NUM [6];
//char SET_NUM = {EW_TEMP/10,EW_TEMP%10,'-','-',SN_TEMP/10,SN_TEMP%10};
//正常模式下存放要显示的值,与a[]配合使用
char TIME_NUM [6];
//char TIME_NUM = {EW/10,EW%10,EW_STATE,SN_STATE,SN/10,SN%10};
int cc;
//按键值0~f
int key_num;
完整文档下载:
https://download.csdn.net/download/u012579502/10655911