资源描述
摘 要
本系统由单片机系统、键盘、LED 显示、交通灯演示系统组成。系统包括人行道、左转、右转、以及基本的交通灯的功能。系统除基本交通灯功能外,还具有倒计时、时间设置、紧急情况处理、分时段调整信号灯的点亮时间、违规车辆检测以及根据具体情况手动控制等功能。
本文通过查询相关资料及对系统设计要求和交通灯电路逻辑的分析,结合MCS-51的使用特点提出了一套系统实现的软、硬件方案,并通过MCS-51开发装置实现了该设计方案的基本功能,对交通灯系统设计进行了一种经济、有效的尝试。
关键词 MCS-51单片机 KEIL C51编译器 LED显示 时序
目 录
第1章 引言··································································1
第2章 总体方案设计·························································5
第3章 第4章第5章 系统调试·····························································23结论·········································································24
参考文献·····································································25
附录·········································································26
第1章 引言
51的编程语言常用的有二种,一种是汇编语言,一种是C语言。汇编语言的机器代码生成效率很高但可读性却并不强,复杂一点的程序就更是难读懂,而C语言在大多数情况下其机器代码生成效率和汇编语言相当,但可读性和可移植性却远远超过汇编语言,而且C语言还可以嵌入汇编来解决高时效性的代码编写问题。对于开发周期来说,中大型的软件编写用C语言的开发周期通常要小于汇编语言很多。综合以上C语言的优点,本文在程序编写时选择了C语言来作为编译语言。 KEIL C51标准C编译器为8051微控制器的软件开发提供了C语言环境,同时保留了汇编代码高效,快速的特点。C51编译器的功能不断增强,使你可以更加贴近CPU本身,及其它的衍生产品。C51已被完全集成到uVision2的集成开发环境中,这个集成开发环境包含:编译器,汇编 器,实时操作系统,项目管理器,调试器。uVision2 IDE可为它们提供单一而灵活的开发环境。
C51是目前最高效、灵活的8051开发平台。它可以支持所有8051的衍生产品,也可以支持所有兼容的仿真器,同时支持其它第三方开发工具。
工程(project)是由源文件、开发工具选项以及编程说明三部分组成的。
一个单一的uVision2工程能够产生一个或多个目标程序。产生目标程序的源文件构成“组”。开发工具选项可以对应目标,组或单个文件。
uVision2包含一个器件数据库(device database),可以自动设置汇编器、编译器、连接定位器及调试器选项,来满足用户充分利用特定 微控制器的要求。此数据库包含:片上存储器和外围设备的信息,扩展数据指针(extra data pointer)或者加速器(math accelerator)的特 性。
uVision2可以为片外存储器产生必要的连接选项:确定起始地址和规模。
uVision2编辑器包含了所有用户熟悉的特性。彩色语法显像和文件辩识都对C源代码进行和优化。可以在编辑器内调试程序并且可以编写或使用类似C的数语言进行调试。
KEIL C51编译器在遵循ANSI标准的同时,为8051微控制器系列特别设计。语言上的扩展能让用户使用应用中的所有资源。
C51允许用户使用C语言编写中断服务程序,快速进、出代码和寄存器区的转换功能使C语言中断功能更加高效。可再入功能是用关键字来定义的。多任务,中断或非中断的代码要求必须具备可再入功能。
C51提供了灵活高效的指针。通用指针用3个字节来存储存储器类型及目标地址,可以在8051的任意存储区内存取任何变量。特殊指针在声明的同时已指定了存储器类型,指向某一特定的存储区域。由于地址的存储只需1-2字节,因此,指针存取非常迅速。
uVision2调试器具备所有常规源极调试,符号调试特性以及历史跟踪,代码覆盖,复杂断点等功能。DDE界面和shift语言支持自动程序测试。
第2章 总体方案设计
车人行驶
行人灯
行人灯
白圈代表红灯
左弯灯
右弯灯
黑圈代表绿灯
图2-1标号设定
图2-2规则状态图
图2-3(a)车辆行驶状态S1 图2-3(b)车辆行驶状态S2
图2-3(c)车辆行驶状态S3 图2-3(d)车辆行驶状态S4
2-3 交通灯四种状态
S1的状态
A
B
C
D
E
F
G
H
逻辑值
显示时间
从40秒到0秒
S2的状态
A
B
C
D
E
F
G
H
逻辑值
显示时间
从30秒到0秒
S3的状态
A
B
C
D
E
F
G
H
逻辑值
显示时间
从70秒到30秒
S4的状态
A
B
C
D
E
F
G
H
逻辑值
显示时间
从30秒到0秒
表2-1 交通灯的循环逻辑表
图2-4电源电路
第3章 硬件系统设计
图3-1 LED控制电路
图3-2(a) E10501外形图 图3-2(b) E10501等效电路图
图3-2(c) 数码管显示
图3-3 违规检测电路第4章 软件系统设计
图4-1主程序流程图
////////////////////////////主函数//////////////////////////
Void main ()
{
t=5;
TIME_Init (); //定时器初始化
sec=COUNT_DOWN; //定时初值
while(1)
{
key_scan(); //按键扫描
switch (key_flag)
{
case 0:t++;if(t>=30)t=5;break; //设置时间
case 1:TR2 = 1;break; //恢复
case 2:EW_ON;P1=LED[4];TR2 = 0;break;
//南北禁行,定时器停止
case 3:SN_ON;P1=LED[4];TR2 = 0;break;
//东西禁行,定时器停止
}
//==========状态S1========
if( (aspect_flag == 0)&(interim_flag == 0)&(key_flag == 0) )
{
EW_ON;
P1=LED[0];
P2=LED7Code[(sec-INTERIM)/10];//东西方向绿灯,少5秒
Delay1Ms(1);
P2 = 0XFF;
P1=LED[1];
P2=LED7Code[(sec-INTERIM)%10];
Delay1Ms(1);
P1=LED[2];
P2=LED7Code[sec/10]; //南北方向红灯
Delay1Ms(1);
P2=0XFF;
P1=LED[3];
P2=LED7Code[sec%10];
Delay1Ms(1);
}
//==========状态S2========
if( (aspect_flag == 0)&(interim_flag == 1)&(key_flag == 0) )
{
if(half_sec % 2 == 1) EW_Y_ON;
else EW_Y_OFF;
P1=LED[0];
P2=LED7Code[sec/10]; //东西方向黄灯
Delay1Ms(1);
P2 = 0XFF;
P1=LED[1];
P2=LED7Code[sec%10];
Delay1Ms(1);
P1=LED[2];
P2=LED7Code[sec/10]; //南北方向红灯
Delay1Ms(1);
P2 = 0XFF;
P1=LED[3];
P2=LED7Code[sec%10];
Delay1Ms(1);
}
//==========状态S3========
if( (aspect_flag == 1)&(interim_flag == 0)&(key_flag == 0) )
{
SN_ON;
P1=LED[0];
P2=LED7Code[sec/10]; //东西方向红灯
Delay1Ms(1);
P2 = 0XFF;
P1=LED[1];
P2=LED7Code[sec%10];
Delay1Ms(1);
P1=LED[2];
P2=LED7Code[(sec-INTERIM)/10];//南北方向绿灯,少5秒
Delay1Ms(1);
P2 = 0XFF;
P1=LED[3];
P2=LED7Code[(sec-INTERIM)%10];
Delay1Ms(1);
}
//==========状态S4========
if( (aspect_flag == 1)&(interim_flag == 1)&(key_flag == 0) )
{
if(half_sec % 2 == 1) SN_Y_ON;
else SN_Y_OFF;
P1=LED[0];
P2=LED7Code[sec/10];
Delay1Ms(1);
P2 = 0XFF;
P1=LED[1];
P2=LED7Code[sec%10];
Delay1Ms(1);
P1=LED[2];
P2=LED7Code[sec/10];
Delay1Ms(1);
P2 = 0XFF;
P1=LED[3];
P2=LED7Code[sec%10];
Delay1Ms(1);
}
}
}
4-2按键子程序流程图
图4-3 按键设置
图4-4 矩阵键盘的原理图
图4-5 键闭合和断开时的电压抖动void key_scan()
{
if (KEY1 == 0)
{
Delay1Ms(10); //按下延时消颤
if (KEY1 == 0)
{
if(key_flag == 1)
key_flag = 0; //取消
else
key_flag = 1; //确定
}
while(KEY1 == 0);
Delay1Ms(5); //弹起延时消颤
while(KEY1 == 0);
}
if (KEY2 == 0)
{
Delay1Ms(10); //按下延时消颤
if (KEY2 == 0)
{
if(key_flag == 2)
key_flag = 0; //取消
else
key_flag = 2; //确定
}
while(KEY2 == 0);
Delay1Ms(5); //弹起延时消颤
while(KEY2 == 0);
}
if (KEY3 == 0)
{
Delay1Ms(10); //按下延时消颤
if (KEY3 == 0)
{
if(key_flag == 3)
key_flag = 0; //取消
else
key_flag = 3; //确定
}
while(KEY3 == 0);
Delay1Ms(5); //弹起延时消颤
while(KEY3 == 0);
}if (KEY4 == 0)
{
Delay1Ms(10); //按下延时消颤
if (KEY4 == 0)
{
if(key_flag == 4)
key_flag = 0; //取消
else
key_flag = 4; //确定
}
while(KEY4== 0);
Delay1Ms(5); //弹起延时消颤
while(KEY4 == 0);
}
}第5章 系统调试图5-1 ISP下载软件结论参考文献及网站
附录
//******************************************************
//程序名称: 十字路口简易交通灯
//功能介绍:
// KEY1按下,设置时间
// KEY2按下,恢复
// KEY3按下,东西禁止通行
// KEY4按下,南北禁止通行
//******************************************************
#include <reg52.h>
#include <intrins.h>
//===========================================================
#define uchar unsigned char
#define uint unsigned int
//=====================指示灯状态定义========================
#define ALL_OFF (P0 = 0xdb) //全部禁行
#define EW_ON (P0 = 0xeb) //东西绿灯,南北红灯
#define SN_ON (P0 = 0xdd) //南北绿灯,东西红灯
#define EW_Y_ON (P0 = 0xF3) //南北红灯,东西黄灯亮
#define EW_Y_OFF (P0 = 0xFB) //南北红灯,东西黄灯灭
#define SN_Y_ON (P0 = 0xDE) //东西红灯,南北黄灯亮
#define SN_Y_OFF (P0 = 0xDF) //东西红灯,南北黄灯灭
#define COUNT_DOWN 70 //定时时间
#define INTERIM t //黄灯过渡时间
//====================按键定义===============================
sbit KEY1 = P2^4; //时间设置
sbit KEY2 = P2^5; //恢复
sbit KEY3 = P2^6; //东西禁行
sbit KEY4 = P2^7; //南北禁行
//====================函数定义===============================
void TIME_Init (); //定时器初始化
void Delay1Ms(uchar t); //延时t*1Ms
void Delay1s(uchar t); //延时t*1s
void key_scan(); //键盘扫描
//======================数码管选择定义=======================
const uchar LED7Code[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};
//段码
const uchar LED[]={0x01,0x02,0x04,0x08,0x00};
//共阳数码管位选
//====================变量定义===============================
uchar t50ms = 0; //50ms累加位
uchar half_sec,sec; //半秒,秒寄存器
uchar key_flag; //键值标记位
uint t;
bit aspect_flag = 0; //0:东西通行,1:南北通行
bit interim_flag = 0; //0:东西黄灯,1:南北黄灯
////////////////////////////主函数//////////////////////////
Void main ()
{
t=5;
TIME_Init (); //定时器初始化
sec=COUNT_DOWN; //定时初值
while(1)
{
key_scan(); //按键扫描
switch (key_flag)
{
case 0:t++;if(t>=30)t=5;break; //设置时间
case 1:TR0 = 1;break; //恢复
case 2:EW_ON;P1=LED[4];TR0 = 0;break;
//南北禁行,定时器停止
case 3:SN_ON;P1=LED[4];TR0 = 0;break;
//东西禁行,定时器停止
}
//==========状态S1========
if( (aspect_flag == 0)&(interim_flag == 0)&(key_flag == 0) )
{
EW_ON;
P1=LED[0];
P2=LED7Code[(sec-INTERIM)/10];//东西方向绿灯,少5秒
Delay1Ms(1);
P2 = 0XFF;
P1=LED[1];
P2=LED7Code[(sec-INTERIM)%10];
Delay1Ms(1);
P1=LED[2];
P2=LED7Code[sec/10]; //南北方向红灯
Delay1Ms(1);
P2=0XFF;
P1=LED[3];
P2=LED7Code[sec%10];
Delay1Ms(1);
}
//==========状态S2========
if( (aspect_flag == 0)&(interim_flag == 1)&(key_flag == 0) )
{
if(half_sec % 2 == 1) EW_Y_ON;
else EW_Y_OFF;
P1=LED[0];
P2=LED7Code[sec/10]; //东西方向黄灯
Delay1Ms(1);
P2 = 0XFF;
P1=LED[1];
P2=LED7Code[sec%10];
Delay1Ms(1);
P1=LED[2];
P2=LED7Code[sec/10]; //南北方向红灯
Delay1Ms(1);
P2 = 0XFF;
P1=LED[3];
P2=LED7Code[sec%10];
Delay1Ms(1);
}
//==========状态S3========
if( (aspect_flag == 1)&(interim_flag == 0)&(key_flag == 0) )
{
SN_ON;
P1=LED[0];
P2=LED7Code[sec/10]; //东西方向红灯
Delay1Ms(1);
P2 = 0XFF;
P1=LED[1];
P2=LED7Code[sec%10];
Delay1Ms(1);
P1=LED[2];
P2=LED7Code[(sec-INTERIM)/10];//南北方向绿灯,少5秒
Delay1Ms(1);
P2 = 0XFF;
P1=LED[3];
P2=LED7Code[(sec-INTERIM)%10];
Delay1Ms(1);
}
//==========状态S4========
if( (aspect_flag == 1)&(interim_flag == 1)&(key_flag == 0) )
{
if(half_sec % 2 == 1) SN_Y_ON;
else SN_Y_OFF;
P1=LED[0];
P2=LED7Code[sec/10];
Delay1Ms(1);
P2 = 0XFF;
P1=LED[1];
P2=LED7Code[sec%10];
Delay1Ms(1);
P1=LED[2];
P2=LED7Code[sec/10];
Delay1Ms(1);
P2 = 0XFF;
P1=LED[3];
P2=LED7Code[sec%10];
Delay1Ms(1);
}
}
}
/******************************************************************
名称:void TIME_Init ();
功能:定时器初始化
指令:
调用:无
返回:无
/******************************************************************/
void TIME_Init ()
{
TMOD = 0x01;
RCAP2H =(65536-50000)/256; //定时50ms 自动重装
RCAP2L =(65536-50000)%256;
EA = 1; //总中断使能
ET0 = 1; //定时器0中断开
TR0 = 1; //关定时器0
}
/******************************************************************
名称:void Tim0 () interrupt 1
功能:T0中断,
参数:
调用:
返回:
******************************************************************/
void PWM_Time0 () interrupt 1
{
RCAP2H =(65536-50000)/256; //定时50ms 自动重装
RCAP2L =(65536-50000)%256;
TF2 = 0; //清零中断标志位
//ET2 = 0; //定时器0中断禁止
if(++ t50ms == 10)
{
half_sec++;
t50ms = 0;
}
if(half_sec == 2)
{
half_sec = 0; //清零
if(--sec ==INTERIM )
{
interim_flag = 1; //黄灯闪烁标志
}
if(sec ==0)
{
sec = COUNT_DOWN;
aspect_flag = !aspect_flag; //换向
interim_flag = 0; //黄灯闪烁关闭
}
}
}
/******************************************************************
名称:void key_scan()
功能:按键扫描
参数:
调用:
返回:
******************************************************************/
void key_scan()
{
if (KEY1 == 0)
{
Delay1Ms(10); //按下延时消颤
if (KEY1 == 0)
{
if(key_flag == 1)
key_flag = 0; //取消
else
key_flag = 1; //确定
}
while(KEY1 == 0);
Delay1Ms(5); //弹起延时消颤
while(KEY1 == 0);
}
if (KEY2 == 0)
{
Delay1Ms(10); //按下延时消颤
if (KEY2 == 0)
{
if(key_flag == 2)
key_flag = 0; //取消
else
key_flag = 2; //确定
}
while(KEY2 == 0);
Delay1Ms(5); //弹起延时消颤
while(KEY2 == 0);
}
if (KEY3 == 0)
{
Delay1Ms(10); //按下延时消颤
if (KEY3 == 0)
{
if(key_flag == 3)
key_flag = 0; //取消
else
key_flag = 3; //确定
}
while(KEY3 == 0);
Delay1Ms(5); //弹起延时消颤
while(KEY3 == 0);
}if (KEY4 == 0)
{
Delay1Ms(10); //按下延时消颤
if (KEY4 == 0)
{
if(key_flag == 4)
key_flag = 0; //取消
else
key_flag = 4; //确定
}
while(KEY4== 0);
Delay1Ms(5); //弹起延时消颤
while(KEY4 == 0);
}
}
/*=========================================================================
名称: void Delay1Ms(uchar t);
功能:延时1ms
参数:t,最大255
调用: 无
返回:无
=========================================================================*/
void Delay1Ms(uchar t)
{
uchar i;
for (;t>0;t--)
{
for (i=0;i<138;i++)
{
_nop_();_nop_();_nop_();_nop_();_nop_();
}
}
}
展开阅读全文