位码即位选信号DIG,它决定哪个数码管工作,哪个数码管不工作。
当需要某一位数码管显示数字时,只需要先选中这位数码管的位信号,再给显示数字的段码。
4.2软件应用
1.Proteus7.5简介:
Proteus软件不仅具有EDA工具软件的仿真功能,还能仿真单片机及外围器件Proteus从原理图布图、代码调试到单片机与外围电路协同仿真,一键切换到PCB设计,真正实现了将电路仿真软件、PCB设计软件和虚拟模型仿真软件三合一的设计平台,其处理器模型支持8051、HC11、PIC10/12/16/18/24/30/DsPIC33、AVR、ARM、8086和MSP430等。
在编译方面,它支持IAR、Keil和MPLAB等多种编译器。
2.KeilC51开发系统简介:
KeilC51是51系列兼容单片机C语言软件开发系统,与汇编相比,C语言在功能上、结构性、可读性、可维护性上有明显的优势,因而易学易用。
KeilC51软件提供丰富的库函数和功能强大的集成开发调试工具,全Windows界面,生成的目标代码效率非常之高,多数语句生成的汇编代码紧凑,容易理解。
在开发大型软件时更能体现其高级语言的优势。
5.主程序设计
/*********11.0952M晶振***********************************/
#include//头文件
#include//头文件
#defineucharunsignedchar//宏定义
#defineuintunsignedint//宏定义
sbitRED_ZHU=P1^0。
sbitYELLOW_ZHU=P1^1。
sbitGREEN_ZHU=P1^2。
sbitRED_ZHI=P1^3。
sbitYELLOW_ZHI=P1^4。
sbitGREEN_ZHI=P1^5。
uintaa,bai,shi,ge,bb。
//定义变量
/*数码管显示0-9*/
uintcodetable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}。
/*子函数声明*/
voiddelay(uintz>。
voiddelay0(uintz>。
//voidinit(uinta>。
voiddisplay(uintge,uintshi>。
voidxtimer0(>。
voidinit1(>。
voidinit2(>。
voidinit3(>。
voidinit4(>。
voidinit5(>。
voidxint1(>。
voidxint0(>。
voidLED_ON(>。
voidLED_OFF(>。
/**********************主函数************************/
voidmain(>
{
P0=0XFF。
P1=0xFF。
P2=0xFF。
EA=1。
//打开外部中断
EX1=1。
//允许外部中断1中断
IT1=0。
//INT0为沿触发方式
init1(>。
while(1>
{
init2(>。
//第2个状态
init3(>。
//第3个状态
init4(>。
//第4个状态
init5(>。
//第5个状态
}
}
voidinit1(>//第一个状态:
主干道、支干道均亮红灯5S
{
uinttemp。
temp=6。
//变量赋初值
TMOD=0x01。
//定时器0工作于方式1
TH0=0x4c。
TL0=0x00。
//定时器赋初值
EA=1。
//开外部中断
ET0=1。
//开定时中断
TR0=1。
//开定时器0
while(1>
{
RED_ZHU=0。
//第一个状态主干道、支干道均亮红灯5S
RED_ZHI=0。
GREEN_ZHU=1。
GREEN_ZHI=1。
YELLOW_ZHU=1。
YELLOW_ZHI=1。
if(aa==20>//定时20*50MS=1S
{
aa=0。
//定时完成一次后清0
temp--。
//变量自增
//delay(10>。
if(temp>250>//定时100S
{
temp=6。
//变量清0
break。
}
shi=temp%100/10。
//显示十位
ge=temp%10。
//显示个位
}
display(ge,shi>。
}
}
voidinit2(>//第二个状态:
主干道亮绿灯30S、支干道亮红灯
{
uinttemp。
temp=31。
//变量赋初值
TMOD=0x01。
//定时器0工作于方式1
TH0=0x4c。
TL0=0x00。
//定时器赋初值
EA=1。
//开外部中断
ET0=1。
//开定时中断
TR0=1。
//开定时器0
while(1>
{
RED_ZHU=1。
RED_ZHI=0。
GREEN_ZHU=0。
GREEN_ZHI=1。
YELLOW_ZHU=1。
//第二个状态:
主干道亮绿灯30S、支干道亮红灯
YELLOW_ZHI=1。
if(aa==20>//定时20*50MS=1S
{
aa=0。
//定时完成一次后清0
temp--。
//变量自增
if(temp==3>//定时100S
{
temp=30。
//变量清0
break。
}
shi=temp%100/10。
//显示十位
ge=temp%10。
//显示个位
}
display(ge,shi>。
}
}
voidinit3(>//第三个状态:
主干道绿灯闪3次转亮黄灯、支干道亮红灯3S
{
uinttemp。
temp=4。
//变量赋初值
TMOD=0x01。
//定时器0工作于方式1
TH0=0x4c。
TL0=0x00。
//定时器赋初值
EA=1。
//开外部中断
ET0=1。
//开定时中断
TR0=1。
//开定时器0
while(1>
{
RED_ZHI=0。
GREEN_ZHU=1。
//YELLOW_ZHU=~YELLOW_ZHU。
if(aa==20>//定时20*50MS=1S
{
aa=0。
//定时完成一次后清0
temp--。
//变量自增
YELLOW_ZHU=~YELLOW_ZHU。
if(temp>200>//定时100S
{
temp=4。
//变量清0
break。
}
shi=temp%100/10。
//显示十位
ge=temp%10。
//显示个位
}
display(ge,shi>。
。
}
}
voidinit4(>//第四个状态:
主干道亮红灯、支干道亮绿灯25S
{
uinttemp。
temp=26。
//变量赋初值
TMOD=0x01。
//定时器0工作于方式1
TH0=0x4c。
TL0=0x00。
//定时器赋初值
EA=1。
//开外部中断
ET0=1。
//开定时中断
TR0=1。
//开定时器0
while(1>
{
RED_ZHU=0。
RED_ZHI=1。
YELLOW_ZHU=1。
//第一个状态主干道、支干道均亮红灯5S
GREEN_ZHI=0。
if(aa==20>//定时20*50MS=1S
{
aa=0。
//定时完成一次后清0
temp--。
//变量自增
if(temp==3>//定时100S
{
temp=25。
//变量清0
break。
}
shi=temp%100/10。
//显示十位
ge=temp%10。
//显示个位
}
display(ge,shi>。
}
}
voidinit5(>//第五个状态:
主干道亮红灯、支干道绿灯闪3次转亮黄灯3S
{
uinttemp。
temp=4。
//变量赋初值
TMOD=0x01。
//定时器0工作于方式1
TH0=0x4c。
TL0=0x00。
//定时器赋初值
EA=1。
//开外部中断
ET0=1。
//开定时中断
TR0=1。
//开定时器0
while(1>
{
RED_ZHI=1。
RED_ZHU=0。
GREEN_ZHU=1。
GREEN_ZHI=1。
//YELLOW_ZHI=~YELLOW_ZHI。
if(aa==20>//定时20*50MS=1S
{
aa=0。
//定时完成一次后清0
temp--。
//变量自增
YELLOW_ZHI=~YELLOW_ZHI。
if(temp>200>//定时100S
{
temp=4。
//变量清0
break。
}
shi=temp%100/10。
//显示十位
ge=temp%10。
//显示个位
}
display(ge,shi>。
}
}
/*显示子函数*/
voiddisplay(uintge,uintshi>
{
P0=0xfd。
P2=table[shi]。
//显示十位
delay0(5>。
P0=0xfe。
P2=table[ge]。
//显示个位
delay0(5>。
}
voidxint0(>interrupt2//外部中断1,这里用2是INT1的优先级为0
{
LED_ON(>。
}
voidLED_ON(>//外部中断0显示子程序
{
RED_ZHI=0。
RED_ZHU=0。
GREEN_ZHI=1。
GREEN_ZHU=1。
YELLOW_ZHI=1。
YELLOW_ZHU=1。
delay0(1000>。
return。
}
/*定时中断子函数*/
voidxtimer0(>interrupt1
{
TH0=0x4c。
TL0=0x00。
aa++。
}
/*延时子函数*/
voiddelay0(uintz>
{
uinti,j。
for(i=0。
ii++>
for(j=0。
j<110。
j++>。
}
/********500ms延时函数晶振:
11.0592MHz*******/
voiddelay(unsignedcharj>
{
unsignedchark。
unsignedinti。
for(。
j>0。
j-->
{
for(i=1250。
i>0。
i-->
{
for(k=180。
k>0。
k-->。
}
}
}
6.系统实现
1.使用keilC51编写程序;
2.将编好的程序“.C”文件用KeilC51转换成“.hex”文件;
3.画出设计系统仿真图;
3.打开proteus7.5,将画好的仿真图载入,鼠标右击图中的51单片机选择“编辑属性”,在ProgramFile中载入之前的“.hex”文件,再点击“调试”中的“开始”或点击软件左下角的“
”,即仿真开始运行;
4.观察运行现象是否与设计结果相符;
5.确定设计后,按图焊接硬件电路;
6.测试硬件电路。
7.仿真运行
8.设计心得
用单片机实现交通灯控制,可以使我们的生活方便快捷。
这项看起来不需要多少技术的工作却是非常需要耐心和精力,几天的设计对我们来说的意义,不仅仅是让我们把所学的理论知识与实践相结合起来,还提高了我们的实际动手能力和独立思考的能力,更重要的是团队合作,虽然我们这次设计仓促,制作有些简单,但我们得到了很多远大于设计的东西!
9.参考文献
单片机原理及应用
51单片机原理及应用--基于KeilC与Proteus
Proteus7.5Professional51单片机入门教程
XX文库:
AT89C51中文资料
Proteus仿真论坛