AT89S52交通灯设计Word格式.docx
《AT89S52交通灯设计Word格式.docx》由会员分享,可在线阅读,更多相关《AT89S52交通灯设计Word格式.docx(12页珍藏版)》请在冰豆网上搜索。
![AT89S52交通灯设计Word格式.docx](https://file1.bdocx.com/fileroot1/2022-11/28/3c9df5a0-5f3a-4a64-aacc-01071217dfdd/3c9df5a0-5f3a-4a64-aacc-01071217dfdd1.gif)
最后循环至南北绿灯,东西红灯。
在这些状态下,有时钟倒数计时。
当按下S1键时,进入绿灯时间设置模式,第二次按下S1键,进入黄灯设置模式,第三次按下S1键,设置时间结束。
4芯片介绍
AT89S52是一个低电压,高性能CMOS8位单片机,片内含8kbytes的可反复擦写的Flash只读程序存储器和256bytes的随机存取数据存储器(RAM),器件采用ATMEL公司的高密度、非易失性存储技术生产,兼容标准MCS-51指令系统,片内置通用8位中央处理器和Flash存储单元,功能强大的AT89S52单片机可为您提供许多较复杂系统控制应用场合。
AT89S52有40个引脚,32个外部双向输入/输出(I/O)端口,同时内含2个外中断口,3个16位可编程定时计数器,2个全双工串行通信口,2个读写口线,AT89S52可以按照常规方法进行编程,也可以在线编程。
其将通用的微处理器和Flash存储器结合在一起,特别是可反复擦写的Flash存储器可有效地降低开发成本。
主要功能特性:
•兼容MCS51指令系统
•8k可反复擦写(>
1000次)FlashROM
•32个双向I/O口
•256x8bit内部RAM
•3个16位可编程定时/计数器中断
•时钟频率0-24MHz
•2个串行中断
•可编程UART串行通道
•2个外部中断源
•共6个中断源
•2个读写中断口线
•3级加密位
•低功耗空闲和掉电模式
•软件设置睡眠和唤醒功能
5硬件设计
6软件程序设计
6.1定时器初始化
定时器/计数器是单片机中最常用、最重要的功能模块之一,本次实训通过交通灯控制器实例来演示定时器的使用。
首先介绍交通灯以及定时器/计数器的基础知识,接着介绍本实例的硬件电路构成,然后逐步分析定时器的编程以及程序的全貌。
定时器/计数器的4种工作方式下的逻辑结构如表所示。
M1
M2
工作方式
方式0,为13位定时器/计数器
1
方式1,为16位定时器/计数器
方式2,为初值自动重装的8位定时器/计数器
方式3,仅T0有效,将T0分为两个8位定时器/计数器
定时器工作在工作方式1,是初值自动重装的16位定时器/计数器,在12MHz晶振条件下,16位定时器的最长定时时间是65.535ms,为了方便计算取定时时间为1ms,所以,定时1s需要定时器中断100次。
下面计算定时器的初值。
定时器初值TC=M-T/t=65535-1000/1=64535,因此TH0=d8H,TL0=f0H.
定时器初始化程序如下,定时器T0设定为工作方式1,初始值为d8f0H,自动重装入值为d8f0H。
TMOD|=0x01;
//定时器T0设置10msin12Mcrystal
TH0=0xd8;
//设定时器T0的初始值,并自动重载
TL0=0xf0;
ET0=1;
//打开中断
TR0=1;
//启动定时器
EA=1;
//中断允许总控制位使能
6.2程序流程图
流程图如下:
6.3程序设计(见附件)
7总结
本次单片机的实训,回顾起整个过程,我们仍感慨颇多,学到了很多的东西。
同时不仅巩固了以前所学过的知识,而且还学到了很多在书本上所没有学到过的知识。
在实际设计中才发现,书本上理论性的东西与在实际运用中的还是有一定的出入的,所以有些问题不但要深入地理解,而且要不断地更正以前的错误思维。
一切问题必须要靠自己一点一滴的解决,而在解决的过程当中你会发现自己在飞速的提升。
对于单片机设计,其硬件电路是比较简单的,主要是解决程序设计中的问题,而程序设计是一个很灵活的东西,它反映了你解决问题的逻辑思维和创新能力,它才是一个设计的灵魂所在。
因此可以说单片机的设计是软件和硬件的结合,二者是密不可分的。
通过这次课程设计我发现单片机原理应用行很强,只有老师的讲解不行,只看也不中,只有自己动手去做才会发现自己确实有太多的不足,许多的原理,程序看似简单,真正去做才知道知识并没有自己想象的那样扎实。
从而懂得了理论与实际相结合是很重要的,只有理论知识是远远不够的,只有把所学的理论知识与实践相结合起来,从理论中得出结论,才能真正为社会服务,从而提高自己的实际动手能力和独立思考的能力。
树立了对自己工作能力的信心,相信会对今后的学习工作生活有非常重要的影响。
而且大大提高了动手的能力,使我充分体会到了在创造过程中探索的艰难和成功时的喜悦。
附件
#include<
reg52.h>
bitred_green=0,red_yellow=1,green_red=0,yellow_red=0;
sbitKEY1=P3^0;
sbitKEY2=P3^1;
sbitKEY3=P3^2;
unsignedcharsecond=55,counts=0,green_time=55,yellow_time=5;
//红灯55s,黄灯5s
codeunsignedchartab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
//共阴数码管0-9
unsignedcharStrTab[4];
//定义缓冲区
voidDelay(unsignedintcnt)
{
while(--cnt);
}
voidtime(void)interrupt1using1
staticunsignedcharcount=0;
TH0=0xd8;
//重新赋值,10ms中断一次
TL0=0xf0;
count++;
if(count==100)
{
count=0;
second--;
//秒减1
if(second==0)
{
if(red_yellow)
{
red_yellow=0;
green_red=1;
second=yellow_time;
P1=0xf6;
//车道红灯,人行道黄灯,5s
}
elseif(green_red)
green_red=0;
yellow_red=1;
second=green_time;
P1=0xed;
//车道绿灯,人行道红灯,55s
elseif(yellow_red)
yellow_red=0;
red_green=1;
P1=0xf9;
//车道黄灯5s,人行道红灯,5s
elseif(red_green)
red_green=0;
red_yellow=1;
P1=0xde;
//车道红灯,人行道绿灯,55s
}
}
voidSettime(void)
if(!
KEY1)//按键去抖以及动作
Delay(10000);
if(!
KEY1)
{
counts++;
if(counts==3)//设置完成
counts=0;
red_green=0,red_yellow=1,green_red=0,yellow_red=0;
//
P1=0xde;
if(counts==1&
&
!
KEY2)//绿灯时间+
{
if(counts==1&
KEY2)
green_time++;
if(green_time==100)green_time=55;
KEY3)//绿灯时间-
KEY3)
green_time--;
if(green_time==0)green_time=55;
if(counts==2&
KEY2)//黄灯时间+
if(counts==2&
yellow_time++;
if(yellow_time==100)yellow_time=5;
KEY3)//黄灯时间-
yellow_time--;
if(yellow_time==0)yellow_time=5;
voidDisplay(void)//显示函数
{
if(counts==0)
if(red_yellow)
StrTab[0]=tab[(second+yellow_time)/10];
StrTab[1]=tab[(second+yellow_time)%10];
StrTab[2]=tab[(second)/10];
StrTab[3]=tab[(second)%10];
if(green_red||red_green)
StrTab[0]=tab[second/10];
StrTab[1]=tab[second%10];
StrTab[2]=tab[second/10];
StrTab[3]=tab[second%10];
if(yellow_red)
StrTab[2]=tab[(second+yellow_time)/10];
StrTab[3]=tab[(second+yellow_time)%10];
(counts==0))
StrTab[0]=tab[green_time/10];
StrTab[1]=tab[green_time%10];
StrTab[2]=tab[yellow_time/10];
StrTab[3]=tab[yellow_time%10];
voidtime1(void)interrupt3using0//定时器1用来动态扫描
staticunsignedcharnum;
TH1=0xF8;
//重入初值
TL1=0xf0;
num++;
if(num==4)num=0;
//扫描4次,使用4个数码管
switch(num)
case0:
P2=0;
P0=StrTab[0];
break;
//分别调用缓冲区的值进行扫描
case1:
P2=1;
P0=StrTab[1];
case2:
P2=2;
P0=StrTab[2];
case3:
P2=3;
P0=StrTab[3];
default:
if(counts==1)
P2=4;
;
if(counts==2)
voidmain(void)
TMOD|=0x01;
ET0=1;
TR0=1;
TMOD|=0x10;
//定时器1用于动态扫描
ET1=1;
TR1=1;
EA=1;
P1=0xde;
while
(1)
Settime();
Display();