基于单片机交通灯设计(精选8篇)
设计程序:
#include
//共阳极
uchar
code table1[5]={0xf3,0xf5,0xde,0xee,0xf6};/*各种状态下红绿灯段选码, 状态1:A绿灯,B红灯;状态2:A黄灯亮,B红灯;状态3:A红灯,B绿灯;状态4:A红灯,B黄灯亮;状态5:A红灯,B红灯;*/ uchar
code tab[4]={0x1E,0x2D,0x4E,0x8D};//数码管显示位选码 sbit key1=P1^0;//放行A sbit key2=P1^1;//放行B sbit key3=P1^2;//禁止通行
uchar EW=40,SN=30,K1_T=15,K2_T=15,K3_T=20;//初始化交通灯时间 uchar count;//计时中断次数 uchar i,j;//循环控制变量 char Timer;//子程序说明语句 void Process();void Display(uchar j);void Delay(uchar a);/**************************主程序**************************/ main(){ IP=0X02;//设置定时器中断为高优先级//成为中断嵌套
TMOD=0x01;//定时器工作方式
TH0=0x3C;//定时器初始化
TL0=0xB0;IT0=1;//中断触发方式为下降沿触发
EA=1;//CPU开中断
ET0=1;//开定时中断
TR0=1;//启动定时
EX0=1;//启动外部中断0 while(1)
{
Process();
} } /*************************交通灯显示子程序*************************/ void Display(uchar j)//j控制显示table中连续位的起始点 {
char h,l;
h=Timer/10;//EW通行时间十位
l=Timer%10;//EW通行时间个位
for(i=0;i<4;)//按位显示通行状况及时间 {
P0=table1[j];//通行状况显示
P3=tab[i];//位选显示
i++;
//j++;
if(i%2)//两位计时显示
{
P2=table[l];
Delay(400);
}
else
{
P2=table[h];
Delay(400);
} } Delay(5);
//设置扫描时间
} /*********键控*******/ void Keyboard()interrupt 0 using 0 {
if(key1==0)
{ Timer=K1_T;
while(Timer>0)
{
j=0;
Display(0);
//显示一次
}
if(key2==0)
{
Timer=K2_T;
while(Timer>0)
{
j=2;
Display(j);
}
if(key3==0)
{
Timer=K3_T;
while(Timer>0)
{
j=4;
Display(j);
}
} } /**************************延时子程序**************************/ void Delay(uchar a)//循环a次 { uchar x;x=a;while(x--){;} }
/************************TO计时中断服务程序************************/ void timer0(void)interrupt 1 using 1//T0中断 { TH0=0x3C;TL0=0xB0;//定时计数初值
count++;//中断溢出一次count+1 if(count==20){
Timer--;
count=0;//中断次计数,count回,倒计时时间
} } /**************************亮灯控制**************************/ void Process(){ Timer=EW;//初始化方向通行时间
while(Timer>3)//状态:A绿灯,B红灯;{
j=0;
Display(j);//调用显示函数
} while(Timer>0)//状态:A黄灯亮,B红灯;{
j=1;
Display(j);
} Timer=SN;while(Timer>3)//状态:A红灯,B绿灯;{
j=2;
Display(j);} while(Timer>0)//状态:A红灯,B黄灯亮;{
j=3;
Display(j);
}
}
一、交通灯的设计要求
双向交通灯红、黄、绿灯对应相同, 红灯5s, 黄灯1s, 绿灯5s。当有急救车到达时, 双向交通信号为全红, 以便让急救车通过。假定急救车通过路口时间为10s, 急救车通过后, 交通灯恢复中断前状态。
二、AT89C51单片机的中断系统介绍
计算机系统中止当前的正常工作, 转入处理突发事件, 等到突发事件处理完毕之后, 再回到原来被中断的地方, 继续原来的工作, 这样的整个过程称为中断。能够实现这种功能的部件称为中断系统。产生中断请求的事件称为中断源。其中AT89C51单片机具有5个中断源, 在本次设计中我们采用的是外部事情中断请求源0, 以及T1计数溢出事情中断请求这两个中断源。
三、AT89C51单片机的定时/计数器介绍
在单片机中, 通常计数器和定时器设计成一个部件——计数器, 当计数脉冲的周期一定时, 计数器就作为定时器, 定时时间就是计数器计数次数和计数脉冲周期的乘积。在此我们采用的就是计数器的这个定时功能。
四、交通灯的硬件电路搭建
本次设计的硬件电路搭建如图1。两路交通灯的6个灯依次接在51单片机P1口的P1.0到P1.5, 另外在单片机的P3.2口接一个按压式开关作为救护车到来时的中断源。
五、交通灯的软件编程设计
中断部分的程序设计。首先, 应将51单片机中中断允许寄存器IE的EA位设为1, 这代表允许中断源向CPU申请中断, 即CPU开放中断。同时将IE的EX0位设为1, 这代表允许外中断0向CPU申请中断。这样的话, 当救护车来的时候, 可以借此发出中断请求。接下来, 应将定时器控制寄存器TCON的IT0位设为1, 这代表外部中断0的触发方式选择为边沿触发方式。由于笔者采用了按压式的开关作为中断的发出方式, 这样会产生一个脉冲, 因此应当选择边沿触发方式。定时部分的程序设计。首先, 应将控制寄存器TCON的TR1位置1, 启动定时器T1计数。接下来, 应将方式寄存器TMOD的值设为0x01, 使得定时器T1工作在方式1, 即16位定时/计数方式。然后, 由于计时器的定时周期是1s, 笔者使用定时/计数器T1精确定时50ms, 则20次50ms中断时, 定时时间就是1s。在定时器中断部分, 笔者采用的是查询方式, 即CPU不断查询TF1的状态, 当TF1为1时, 表示50ms定时已到, 在主程序中判断是否20次50ms定时已到, 如是, 则时间恰好为1s。同时TF1位软件清0。根据公式, 当定时时间为50ms时, 计数初值应为15536, 换算成十六进制是3CB0H, 即计数器T1中TL1的初值为B0H;TH0的初值为3CH。当救护车到来时, 双向交通灯置红, 即将双向交通灯的红灯所对应的P1口位置1, 其他位清0即可。时间长短的设置方法同上。最后, 由于双向交通灯红灯5s, 黄灯1s, 绿灯5s, 共11个状态, 我们利用switch语句为这11个状态分别设置相应P1口的值, 再利用一个循环即可。
六、结语
在机动车数量激增的今天, 车辆拥堵、交通崩溃的现象还是时有发生的。其原因多半是交通灯时长设置的不合理, 抑或无法根据一天之内不同时间的车流状况, 对交通灯的状态进行调整。因此, 合理地设计交通系统, 同时对于交通灯的适当调试无疑将会派上很大用场。
摘要:交通灯在日常生活中扮演着重要角色, 本文基于Atmel公司生产的型号为AT89C51的单片机, 利用uvision的编译环境进行编程, 同时在Proteus的环境中进行仿真, 对交通信号灯进行设计, 使交通灯具有应急状况处理的功能。
关键词:Arduino;数码管
中图分类号:TP273.5
电子产品智能化使人们可以在炎炎夏日躲在被窝里开启空调调节室内温度,茶余饭后坐在沙发上使用遥控器更换电视频道,开车迷路时可以打开GPS导航寻找出路……其实,生活中很多的电器或者设备的控制并不都需要使用高性能计算机实现,而是采用单片机来实现控制的。在众多的单片机开发工具中,你不需要关心程序的具体实现过程,只需要学会使用单片机提供的工具包即可,简化了开发过程。
1 开发平台及工具简介
1.1 Arduino单片机简介。Arduino是基于AVR指令集单片机的一种开发平台,相对于传统的单片机而言,Arduino基于C/C++这种入门级的程序设计语言基础上进行编程,大量库文件可以直接从网络中下载获得,价格也比普通单片机便宜,软硬件平台均开源,常用的计算机操作系统(Windows、Linux等)均支持Arduino软件。Arduino电路板提供6个模拟输入/输出端口,14个数字输入/输出端口,可以读取传感器、各种开关元件的信号来控制各种电子设备,实现时可以仅开发一个Arduino独立项目,也可以建立与PC机中程序的相互通讯。基于以上优势,Arduino具有很好的发展前景。
1.2 编程语言。要实现设备控制,少不了进行编写程序。在使用Arduino编程语言编程时,很多参数设置均已函数化处理了,只需要用户直接调用即可。要掌握好Arduino编程语言,就需要认真复习C语言语法。Arduino编程语言中运算符号、数据类型、流程控制语句均可参考C语言要求,而Arduino程序的主要结构包括初始化变量、设置管教模式的void setup()函数和类似于C语言中void main()函数功能的循环执行函数void loop()。Arduino编程语言提供数字I/O口输入输出模式的定义函数、模拟I/O输入输出函数、时间函数和数学函数等众多函数。
1.3 主要硬件设备——数码管。数码管是一种用于显示数字0-9(也可包含小数点)的可发光元件,按照段数分有七段数码管和八段数码管,八段数码管多一位小数点。若将数码管的8个发光二极管的阳极并接在一起,8个阴极分开,则为共阳极数码管;若将数码管的8个发光二极管的阴极并接在一起,8个阳极分开,则为共阴极数码管。实际的数码管引脚排列可按以下方法判别:从数码管正面看,左下角第一个引脚为1脚,以逆时针方向依次为1~10脚,其中3脚和8脚连通,称为公共脚。
2 功能和硬件材料简介
2.1 功能简介。通过数码管连线和程序编写,通过程序控制数码管连续循环显示数字9~1,每显示一个数字后间隔1s再显示下一个数字。
2.2 工作原理。通过对数码管特性的分析,将数码管的管脚通过限流电阻的一端连接到数字I/O接口中,公共极接5V(共阳极数码管)或者接GND(共阴极数码管)。对于共阳极数码管来说,通过程序给连接好数码管的数字口设置低电平时,数码管在该管脚和公共极之间就会产生压降,因此可以将数码管相应字段点亮。反言之,通过程序给连接好数码管的数字口设置高电平时,数码管在该管脚和公共极之间则不产生压降,数码管相应字段就不亮。
2.3 硬件材料清单。主要的硬件材料包括:1个Arduino 328控制板、1个原形开发扩展板、1个面包板、1个8位数码管、8个220欧电阻、5根多彩面包板实验跳线、1根USB连接线。
2.4 硬件线路连接。将Arduino 328控制板、原形开发扩展板和面包板连接好,并将USB线接入相应插口。按照数码管的接线规则,从数码管的正面看,将数码管的第10个管脚(即左上角的管脚)连接1个220欧电阻,电阻的另一端连接数字口的第9个引脚。同理,将数码管的第9、7、6个管脚分别通过1个电阻连接到数字口的第8、7、6个引脚。将数码管的第5、4个管脚分别通过1个电阻和1根跳线连接到数字口的第5、4个引脚,第8个管脚(公共极)通过1根跳线与5V接口连接,另一个数码管公共极即第3管脚不做连接。
3 驱动程序开发与运行情况
3.1 驱动程序设计。驱动程序中共定义了9个全局变量,分别对应数码管的各数字段;定义了9个用于显示9~1数字的子函数digital_9~digital_1供loop()函数调用;在执行loop()函数之前,先在setup()函数中设置数字口4~11引脚为输出模式。digital_1子函数代码如下:
void digital_1(void)
{ unsigned char j;
digitalWrite(c,HIGH);
digitalWrite(b,HIGH);
for(j=7;j<=11;j++)
digitalWrite(j,HIGH);
digitalWrite(dp,HIGH);
}
3.2 运行问题。在运行过程中,数码管能够显示出各数字段和小数点段,说明线路是连通的,因此排除电路板线路连接不通的问题。仔细观察数码管显示的数字段情况后,要显示数字3本应点亮数码管的A、B、C、D和G段,但是实际数码管点亮了E、F和DP段;要显示数字4本应点亮数码管的B、C、F和G段,但是实际数码管点亮了A、E、D和DP段;要显示数字6本应点亮数码管的A、C、D、E、F和G段,但是实际数码管点亮了B和DP段……以此类推,发现数码管点亮的数字段和应该点亮的数字段均相反,因此考虑可能是线路接反导致的。
3.3 问题分析与解决方法。重新检查线路后发现连接线路是按照共阳极数码管的连接规则连接的,运行问题可能是由于数码管阴极和阳极电路接反导致的。从电路板上拆下数码管仔细观察后发现,初始程序源代码是根据共阳极数码管特性编写的,电路板也是根据共阳极数码管性质连接的,而实际准备的材料很可能是共阴极数码管。
使用万用表进行测试,把万用表调到测阻档,红笔端接公共端,黑笔端接任意段码端,没有数字段发亮;将红笔端和黑笔端调换,有数字段发亮,因此使用的为共阴极数码管,所以程序运行后实现的效果与预期的正好相反。
经过对原连接线路的分析,将数码管的公共极改为接地,并对程序代码中进行修改,将代码中所有设置为高电平的地方改为低电平,低电平的地方改为设置高电平。
交通灯倒计时显示器的设计,使我真正理解和掌握了数码管的工作原理和应用方法,并且为拓展设计奠定了基础。比如可以进一步设计智能掷骰器,即再添加一个按键,通过按键来控制数码管数字的显示,按下按键时,数码管停留在当前数字不变;松开按键,数码管继续显示下一个数字并继续循环显示。
参考文献:
[1]邵军.基于单片机控制的交通灯设计[J].中国新技术新产品,2010(14).
[2]王洁琼,王红卫,敬敏.基于单片机的实用交通灯设计[J].科协论坛,2009(06).
作者简介:王希娟(1983.01-),女,西安人,管理科学与工程教研室主任,讲师,工程师,硕士,研究方向:数据库、智能控制方向。
作者单位:陕西国际商贸学院,陕西咸阳 712046
课题:以交通灯为主的多功能任务设计
班级 学号 学生姓名
指导教师
淮阴工学院 电子与电气工程学院
2015-6 1
目录
一、课程设计目的......................................................................................................3
二、设计要求..............................................................................................................3 1. 总体要求........................................................................................................3 2. 具体要求........................................................................................................3 3. 系统硬件总框图............................................................................................4 1)AT89C52单片机.......................................................................................5 3)数码管显示电路........................................................................................6 4)LED灯显示...............................................................................................7 5)键盘扫描模块............................................................................................7 6)蜂鸣器电路................................................................................................8
三、硬件电路的设计及描述......................................................................................8 1. 硬件总框图及原理图....................................................................................8 2. 主程序流程图..............................................................................................10 3. 各模块流程图..............................................................................................11 1)时间显示程序流程图..............................................................................12 2)流水灯程序流程图..................................................................................12 3)利用蜂鸣器的音乐流程图......................................................................13 4)交通灯控制..............................................................................................13
四、源程序代码........................................................................................................14
六、调试情况
六、设计心得............................................................................................................20
七、参考文献............................................................................................................20
一、设计目的
《单片机原理及应用》课程设计是一项重要的实践性教育环节,是学生在校期间必须接受的一项工程训练。在课程设计过程中,在教师指导下,应用工程的方法,通过一个简单课题的设计练习,可使学生初步体验单片机应用系统的设计过程、设计要求、完成的工作内容和具体的设计方法,了解必须提交的各项工程文件,也达到巩固、充实和综合运用所学知识解决实际问题的目的。
通过课程设计,应该能加强学生如下能力的培养:(1)独立工作能力和创造力;
(2)综合运用专业及基础知识,解决实际工程技术问题的能力;(3)查阅图书资料、产品手册和各种工具书的能力;(4)工程绘图的能力;
(5)编写技术报告和编写技术资料的能力。
二、设计要求
1.总体要求
(1)独立完成设计任务(2)绘制系统硬件总框图(3)绘制系统原理电路图
(4)制定编写设计方案,编制软件框图,完成详细完整的程序清单和注释(5)制定编写调试方案,编写用户操作使用说明书
(6)写出设计工作小结。对在完成以上文件过程所进行的有关步骤如设计思想、指标论证、方案确定、参数计算、元器件选择、原理分析等作出说明,并对所完成的设计作出评价,对自己整个设计工作中经验教训,总结收获和今后研究方向。
2.具体要求
本次工程实践的校内部分主要以单片机为基础,进行单片机软件编程,目的 3 是为了提高学生的软件编程和系统设计能力,整个设计系统包括两个部分,硬件及软件部分,硬件部分已经制作成功,学生只需要掌握其原理和焊接相应的元器件,掌握元器件的辨别和元器件的作用以及应用场所即可,另外对所焊接的电路还需要进行仔细的检查,判断是否有焊接错误的地方或者短路的地方,对出现的异常情况要能够根据现象判别原因,并具备解决问题的能力,从而切实提高学生的硬件电子电路的分析、判断能力。
软件编程是本次课程设计的重要环节。在为期两周的工程实践中,将占据主要时间,完成的软件编程任务主要包括以下几点:
1)、熟悉Keil C51编程平台及相关编程软件
2)、编写、调试蜂鸣器、继电器动作、方波程序并进行软硬件联调 3)、编写、调试LED流水灯(循环显示)程序并进行软硬件联调 4)、编写、调试键盘扫描子程序并进行软硬件联调 5)、编写、调试数码管动态扫描程序并进行软硬件联调 6)、基于交通灯的多功能控制设计
其中前五个内容是后两个内容的基础,主要是编制一些子程序,为后继的整个系统设计打下基础。交通灯控制是在五个课题中选做的一个设计,是一个简单的单片机编程设计,来实现智能交通灯的多功能作用。
3.系统硬件总框图
图1 系统设计总框图
此次课程设计,AT89C52是一种带2K字节闪烁可编程可擦除只读存储器(FPEROM—Falsh Programmable and Erasable Read Only Memory)的低电压,高性能CMOS 8位微处理器,俗称单片机。1)AT89C52单片机
设计中所用的单片机型号为AT89C52,其主要功能为:
AT89C52是低功耗、高性能的CMOS 8位单片机。片内带有8KB的Flash存储器,且允许在系统内改写或用编程器编程。另外,AT89C52的指令系统和引脚与80C52完全兼容,所以,近几年AT89C52单片机应用极为广泛。
AT89C52单片机除了含有8KB的Flash存储器外,片内还有256 B的RAM,32条I/O口线,3个16位定时/计算器、6个中断源、1个全双工串行口等。同时,与80C52一样,有空闲和掉电两种节电运行方式。
AT89C52引脚如下图所示:
图2 AT89C52引脚
AT89C52单片机为40脚双列直插封装的8 位通用微处理器,采用工业标准的C51内核,在内部功能及管脚排布上与通用的8xc52 相同,其主要用于会聚调整时的功能控制。功能包括对会聚主IC 内部寄存器、数据RAM及外部接口等功能部件的初始化,会聚调整控制,会聚测试图控制,红外遥控信号IR的接收解码及与主板CPU通信等。
2)DS1302模块
DS1302的RST是复位/片选线,通过把RST输入驱动置高电平来启动所有的数据传送。当RST为高电平时,所有的数据传送被初始化,允许对DS1302进行操作。如果在传送过程中RST置为低电平,则会终止此次数据传送,I/O引脚变为高阻态。
其管脚图如下:
图3 DS1302管脚图
各引脚功能:Vcc1为后备电源,VCC2为主电源,X1和X2是振荡源,SCLK为输入端
RST输入有两种功能:首先,RST接通控制逻辑,允许地址/命令序列送入移位寄存器;其次,RST提供终止单字节或多字节数据的传送手段。
3)数码管显示电路
图4 数码管显示电路
设计中采用六位共阴极数码管,通过单片机STC89C52的P0口控制其位选和段选,以达到动态显示相应数值的效果。在其位选控制部分,采用了一个9012型三极管,要求当P0口输出低电平时,位选成功。
所谓动态扫描就是指我们采用分时的方法,轮流控制各个显示器的COM端,6 使各个显示器轮流点亮。在轮流点亮扫描过程中,每位显示器的点亮时间是极为短暂的(约1ms),但由于人的视觉暂留现象及发光二极管的余辉效应,尽管实际上各位显示器并非同时点亮,但只要扫描的速度足够快,给人的印象就是一组稳定的显示数据,不会有闪烁感。
4)LED灯显示
图5 LED显示模块
本次课程设计中,“程序语言”通过“翻译”软件“翻译”成单片机所需的二进制代码,单片机可工作。要用外加电源和分压电阻来控制低电平驱动点亮,因为单片机不能直接高电平驱动LED灯。如图D1-D8和R1、R2以及R6-R11连接到单片机IO口,当P1口某脚变低时相应LED发光。实现LED灯的闪烁,只需利用编程方法依次从低位到高位逐个变为低电平,等待少许时刻再变高即可。
5)键盘扫描模块
图6 按键输入电路
本模块四个开关分别用于控制流水灯控制电路,时间显示电路,音乐蜂鸣器电路,交通灯四部分功能。当按下其中一个开关时,该部分电路导通,给单片机 发出地址信号,实现其中一项功能的运做,如图4所示。
KEYA键:其功能是当该键按下时,蜂鸣器程序工作; KEYB键:其功能是当该键按下时,流水灯程序工作;
KEYC键:其功能是当该键按下时,数码管动态扫描程序工作; KEYD键:其功能是当该键按下时,交通灯程序工作。
6)蜂鸣器电
图7 蜂鸣器电路
路
蜂鸣器单元电路是通过一个PNP三极管来放大驱动蜂鸣器,蜂鸣器的正极接到+5V电源上面,蜂鸣器的负极接到三极管的发射极,三极管的基极经过限流电阻后由单片机的P3.4控制。
当输出高电平时,三极管截止,蜂鸣器的两引脚间的直流电压接近于0V,没有电流流过线圈,蜂鸣器不发声;当输出低电平时,三极管导通,使蜂鸣器的两个引脚间获得将接近+5V的直流电压,这样蜂鸣器的电流形成回路,发出声音。因此,我们可以通过程序控制IO口输出的电平来控制蜂鸣器是否发出声音,实现各种可能音响的产生。
三、硬件电路的设计及描述
1.硬件总框图及原理图
图8 硬件总框图
图9 硬件总原理图
2.主程序流程图
3.各模块流程图 1)时间显示程序流程图
2)流水灯程序流程图
3)利用蜂鸣器的音乐流程图
4)智能交通灯
四、源程序代码
/******************************************************************** * 文件名
: 4个功能由按键控制.c * 描
述
: 按下A键,实现蜂鸣器动作。
按下B键,实现LED流水灯循环显示。
按下C键,实现数码管动态扫描显示。
按下D键,实现交通灯功能。* 创建人
:
***********************************************************************/ #include
#define uint unsigned int
// 无符号整形习惯的定义
#define uchar unsigned char
//无符号字符型习惯的定义 void buzz_key(void);
//子函数声明 void led_key(void);void tube_key(void);void traffic(void);unsigned char code duanma[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};// 0 1 2 3 4 5 6 7 8 9
unsigned char code weima[6]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf};
// 选择哪个数码管
unsigned char temp[6];uchar i=35;uchar k=30;uchar l=5;uchar j;uchar b;
//定义变量
sbit duan=P2^6;//定义管脚 sbit wei=P2^7;sbit key_A=P3^4;sbit key_B=P3^5;sbit key_C=P3^6;sbit key_D=P3^7;sbit buzz=P2^3;sbit DIOLA=P2^5;sbit csda=P3^2;sbit red=P1^0;//交通灯管脚定义 sbit green=P1^1;sbit yellow=P1^2;/******************************************************************** * 名称 : Delay_1ms()* 功能 : 延时子程序,延时时间为 1ms * x * 输入 : x(延时一毫秒的个数)* 输出 : 无
***********************************************************************/
void Delay_1ms(unsigned int t){ unsigned char x,y;for(x=t;x>0;x--)for(y=110;y>0;y--);
}
/******************************************************************** * 名称 : Main()* 功能 : 实现蜂鸣器,流水灯,数码管,交通灯
***********************************************************************/ void main(){
DIOLA=0;//流水灯锁存器关 流水灯未选通
wei=0;//位选关
duan=1;
P0=0;
duan=0;
csda=0;
while(1){
if(key_A==0 || key_B==0 || key_C==0|| key_D==0)
{
if(key_A==0)
//A键按下
{
buzz_key();
//调用蜂鸣器子程序
}
else if(key_B==0)//B键按下
{
led_key();
//调用流水灯子程序
}
else if(key_C==0)//C键按下时
{
tube_key();//调用数码管显示子程序
}
else
//D键按下时
{
traffic();
//调用交通灯子程序
i=35;
k=30;
l=5;
return;
}
}
} }
/******************************************************************** * 名称 : buzz_key(void)* 功能 : 蜂鸣器子程序
***********************************************************************/
void buzz_key(void)
{
DIOLA=0;wei=0;
buzz=0;
//蜂鸣器响
while(key_B&&key_C&&key_D&&!key_A);
buzz=1;
//关蜂鸣器
}
/********************************************************************* * 名称 : led_key(void)* 功能 : 流水灯子程序
***********************************************************************/ void led_key(void){
DIOLA=1;b=0xfe;
P1=b;//11111110 while(key_B==0){
b=_crol_(b,1);
//左移11111101
Delay_1ms(500);
P1=b;
//111111011
Delay_1ms(500);
}
while(key_A&&key_B&&key_C&&key_D);
P1=0xff;
}
/******************************************************************** * 名称 : tube_key(void)* 功能 : 数码管子程序
***********************************************************************/
void tube_key(void){
DIOLA=0;
//流水灯使能端置0 while(key_C==0)
{ unsigned int i;
for(i=0;i<6;i++)
{
wei=1;
P0=weima[i];
//位选信号
wei=0;
duan=1;
P0=duanma[i];//段选信号
duan=0;
Delay_1ms(500);
}
duan=1;
P0=0;
duan=0;
//清零
}
}
/******************************************************************** * 名称 : traffic_key(void)* 功能 : 交通灯子程序
***********************************************************************/
void traffic(void)
{
DIOLA=0;
while(key_D==0)
{
if(i>0)
{
DIOLA=1;
b=0xfe;
P1=b;//11111110
for(j=0;j<40;j++)
{
P0 = 0;
wei=1;
//消隐
P0 = weima[0];
wei=0;
duan=1;
//第1位数码管显示
P0 = duanma[(i / 10)%10];//在这里取 i 的个位数
Delay_1ms(40);
//延时40毫秒后显示下一个数
P0 = 0;
wei=1;
//消隐
P0 = weima[1];
wei=0;
duan=1;
//第2位数码管显示
P0 = duanma[i % 10];
//在这里取 i 的个位数
Delay_1ms(40);
//延时40毫秒后显示下一个数
}
i--;
}
else if(k>0)
{
DIOLA=1;
b=0xfd;
P1=b;//11111110
for(j=0;j<40;j++)
{
P0 = 0;
wei=1;
//消隐
P0 = weima[0];
wei=0;
duan=1;
//第1位数码管显示
P0 = duanma[(k / 10)%10];//在这里取 i 的个位数
Delay_1ms(40);
//延时3毫秒后显示下一个数
P0 = 0;
wei=1;
//消隐
P0 = weima[1];
wei=0;
duan=1;
//第2位数码管显示
P0 = duanma[k % 10];
//在这里取 i 的个位数
Delay_1ms(40);
//延时3毫秒后显示下一个数
}
k--;
}
else if(l>0)
{
DIOLA=1;
b=0xfb;
P1=b;//11111110
for(j=0;j<40;j++)
{
P0 = 0;
wei=1;
//消隐
P0 = weima[0];
wei=0;
duan=1;
//第1位数码管显示
P0 = duanma[(l / 10)%10];//在这里取 i 的个位数
Delay_1ms(40);
//延时3毫秒后显示下一个数
P0 = 0;
wei=1;
//消隐
P0 = weima[1];
wei=0;
duan=1;
//第2位数码管显示
P0 = duanma[l % 10];
//在这里取 i 的个位数
Delay_1ms(40);
//延时3毫秒后显示下一个数
}
l--;
}
}
}
五、设计心得
通过两个星期的实验,我的设计虽然有一些毛病,但总体上还是成功的。两周的时间虽然短暂,但我从中受益匪浅,毕竟在课堂学习到的东西真真正正的用到实际中还是有很大困难的,要把理论运用于实践确实并非一件易事。我从最初的设想设计一个什么样的数字电路到绘制电路图,然后打印排版,最后矫正设计中的漏洞与不足,整个过程我翻阅了大量的资料。
这次交通灯的课程设计,也使我得到了一次用专业知识、专业技能分析和解决现实问题的能力。使我在单片机的基本原理、单片机应用学习过程中,以及在常用编程设计思路技巧的掌握方面都能向前迈了一大步,为日后成为一名合格的应用型人才打下良好的基础。综合课程设计让我把以前学习到的知识得到巩固和进一步的提高认识,对已有知识有了更深层次的理解和认识。在此,由于自身能力有限,在课程设计中碰到了很多的问题,我通过查阅相关书籍、资料以及和周围同学交流得到解决。
还有交通灯是我们生活中非常常见的一种东西,对于我们学以致用的这种能力得到了很好锻炼,能够为我们以后的工作于学习打下基础。
六、参考文献
题:
基于51单片机数字温度计设计
专
业:
电子信息工程
班
级:
班
学
号:
姓
名:
指导教师:
设计日期:
成绩:
XX大学XX学院电气学院
基于51单片机数字温度计设计
一、设计目的1、掌握单片机电路的设计原理、组装与调试方法。
2、掌握LED数码显示电路的设计和使用方法。
3、掌握DS18B20温度传感器的工作原理及使用方法。
二、设计要求
1、本次单片机课程设计要求以51系列单片机为核心,以开发板为平台。
2、设计一个数字式温度计,要求使用DS18B20温度传感器测量温度。
3、经单片机处理后,要求用4位一体共阴LED数码管来设计显示电路,以显示测量的温度值。
4、另外还要求在设计中加入报警系统,如果我们所设计的系统用来监控某一设备,当设备的温度超过或低于我们所设定的温度值时,系统会产生报警。
5、要求在设计中加入上下限警报温度设置电路。
三、设计的具体实现
1数字温度计设计的方案
在做数字温度计的单片机电路中,对信号的采集电路大多都是使用传感器,这是非常容易实现的,所以可以采用一只温度传感器DS18B20,此传感器,可以很容易直接读取被测温度值,进行转换,就可以满足设计要求。采集之后,通过使用51系列的单片机,可以对数据进行相应的处理,再由LED显示电路对其数据进行显示。
2系统设计框图
温度计电路设计总体设计方框图如下图所示,控制器采用单片机AT89C51,温度传感器采用DS18B20,用4位一体共阴LED数码管以串口传送数据实现温度显示。此外,还添加了报警系统,对温度实施监控。
3主控器AT89C51芯片
对于单片机的选择,可以考虑使用8031与8051系列,由于8031没有内部RAM,系统又需要大量内存存储数据,因而不适用。AT89C51
以低价位单片机可为提供许多高性价比的应用场合,可灵活应用于各种控制领域,对于简单的测温系统已经足够。单片机AT89C51具有低电压供电和体积小等特点,四个端口只需要两个口就能满足电路系统的设计需要该器件是INTEL公司生产的MCS一5l系列单片机中的基础产品,采用了可靠的CMOS工艺制造技术,具有高性能的8位单片机,属于标准的MCS—51的CMOS产品。
AT8951的管脚如下图所示:
AT89C51芯片管脚图
4时钟电路
80C51时钟有两种方式产生,即内部方式和外部方式。80C51中有一个构成内部震荡器的高增益反向放大器,引脚XTAL1和XTAL2分别是该放大器的输入端和输出端。本次采用内部震荡电路,瓷片电容采用22PF,晶振为12MHZ。
晶体震荡电路图
复位电路
单片机系统的复位电路在这里采用的是上电+按钮复位电路形式,其中电阻R采用10KΩ的阻值,电容采用10μF的电容值。
复位电路
温度传感电路
DALLAS
最新单线数字温度传感器DS18B20是一种新型的“一线器件”,其体积更小、更适用于多种场合、且适用电压更宽、更经济。DALLAS
半导体公司的数字化温度传感器DS18B20是世界上第一片支持“一线总线”接口的温度传感器。温度测量范围为-55~+125
摄氏度,可编程为9位~12
位转换精度,测温分辨率可达0.0625摄氏度,分辨率设定参数以及用户设定的报警温度存储在EEPROM
中,掉电后依然保存。被测温度用符号扩展的16位数字量方式串行输出。
DS18B20内部结构主要由四部分组成:64位光刻ROM、温度传感器、非挥发的温度报警触发器TH和TL、配置寄存器。DS18B20的管脚排列、各种封装形式,DQ
为数据输入/输出引脚。开漏单总线接口引脚。当被用着在寄生电源下,也可以向器件提供电源;GND为地信号;VDD为可选择的VDD引脚。当工作于寄生电源时,此引脚必须接地,如下图所示。
DS18B20管脚图
显示电路
对于数字温度的显示,我们采用4位一体共阴LED数码管。足够显示0~100中各位数,并且还能显示一位小数部分。
4位LED数码显示管
温度报警电路
对于数字温度计的设计,除了温度的数字显示功能外还加入了报警系统,当测量的温度超过或低于我们所设定的温度值时,系统会产生报警并亮红灯报警。
其电路图如下所示。
蜂鸣器红灯报警系统电路图
源程序:
/********************************************************************
*
程序名;
基于51单片机的温度计
*
功
能:
实时测量温度,超过上下限报警,报警温度可手动调整。K1是用来
*
进入上下限调节模式的,当按一下K1进入上限调节模式,再按一下进入下限
*
调节模式。在正常模式下,按一下K2进入查看上限温度模式,显示1s左右自动
*
退出;按一下K3进入查看下限温度模式,显示1s左右自动退出;按一下K4消除
*
按键音,再按一下启动按键音。在调节上下限温度模式下,K2是实现加1功能,*
K1是实现减1功能,K3是用来设定上下限温度正负的。
*********************************************************************/
#include
#include
#define
uint
unsigned
int
#define
uchar
unsigned
char
uchar
max=0x00,min=0x00;
//max是上限报警温度,min是下限报警温度
bit
s=0;
//s是调整上下限温度时温度闪烁的标志位,s=0不显示200ms,s=1显示1s左右
bit
s1=0;
//s1标志位用于上下限查看时的显示
void
display1(uint
z);
#include“ds18b20.h“
#include“keyscan.h“
#include“display.h“
/******************************************************/
/*
主函数
/
/*****************************************************/
void
main()
{
beer=1;
//关闭蜂鸣器
led=1;
//关闭LED灯
timer1_init(0);
//初始化定时器1(未启动定时器1)
get_temperature(1);
//首次启动DS18B20获取温度(DS18B20上电后自动将EEPROM中的上下限温度复制到TH和TL寄存器)
while(1)
{
keyscan();
get_temperature(0);
display(temp,temp_d*0.625);
alarm();
}
}
/**********************************************************************
*
程序名;
ds18b20数码管动态显示头文件
*
功
能:
通过定时器0延时是数码管动态显示
**********************************************************************/
#ifndef
__ds18b20_display_H__
#define
__ds18b20_display_H__
#define
uint
unsigned
int
//变量类型宏定义,用uint表示无符号整形(16位)
#define
uchar
unsigned
char
//变量类型宏定义,用uchar表示无符号字符型(8位)
sbit
wei1=P2^4;
//可位寻址变量定义,用wei1表示P2.4口
sbit
wei2=P2^5;
//用wei2表示P2.5口
sbit
wei3=P2^6;
//用wei3表示P2.6口
sbit
wei4=P2^7;
//用wei4表示P2.7口
uchar
num=0;
//定义num为全局无符号字符型变量,赋初值为‘0’
uchar
code
temperature1[]={
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
//定义显示码表0~9
uchar
code
temperature2[]={
0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};
//带小数点的0~9.uchar
code
temperature3[]={
0x00,0x80,0x40,0x76,0x38};//依次是‘不显示’‘.’‘-’‘H’‘L’
/******************************************************/
/
延时子函数
/
/*****************************************************/
void
display_delay(uint
t)
//延时1ms左右
{
uint
i,j;
for(i=t;i>0;i--)
for(j=120;j>0;j--);
}
/******************************************************/
/*
定时器1初始化函数
/
/*****************************************************/
void
timer1_init(bit
t)
{
TMOD=0x10;
TH0=0x3c;
TL0=0xb0;
EA=1;
ET1=1;
TR1=t;
//
局部变量t为1启动定时器1,为0关闭定时器1
}
/******************************************************/
/*
定时器1中断函数
/
/*****************************************************/
void
timer1()
interrupt
{
TH0=0x3c;
//重新赋初值,定时50ms
TL0=0xb0;
num++;
//每进入一次定时器中断num加1(每50ms加1一次)
if(num<5)
{s=1;if(w==1){beer=1;led=1;}else{beer=1;led=1;}}
else
//进入4次中断,定时200ms时若报警标志位w为‘1’则启动报警,不为‘1’不启动
//实现间歇性报警功能
{s=0;if(w==1){beer=0;led=0;}else{beer=1;led=1;}}
if(num>20)
//进入20次中断,定时1s
{
num=0;
//num归0,重新定开始定时1s
s1=0;
//定时1s时间到时自动关闭报警上下限显示功能
v1=1;
//定时1s时间到时自动关闭报警上下限查看功能
}
}
/******************************************************/
/*
调整报警上下限选择函数
/
/*****************************************************/
void
selsct_1(uchar
f,uchar
k)
//消除百位的0显示,及正负温度的显示选择
{
if(f==0)
//若为正温度,百位为0则不显示百位,不为0则显示
{
if(k/100==0)
P0=temperature3[0];
else
P0=temperature1[k/100];
}
if(f==1)
//若为负温度,若十位为0,百位不显示,否则百位显示‘-’
{
if(k%100/10==0)
P0=temperature3[0];
else
P0=temperature3[2];
}
}
void
selsct_2(bit
f,uchar
k)
//消除十位的0显示,及正负温度的显示选择
{
if(f==0)
//若为正温度,百位十位均为0则不显示十位,否则显示十位
{
if((k/100==0)&&(k%100/10==0))
P0=temperature3[0];
else
P0=temperature1[k%100/10];
}
if(f==1)
//若为负温度,若十位为0,十位不显示,否则十位显示‘-’
{
if(k%100/10==0)
P0=temperature3[2];
else
P0=temperature1[k%100/10];
}
}
/******************************************************/
/*
主函数显示
/
/*****************************************************/
void
display(uchar
t,uchar
t_d)
//用于实测温度、上限温度的显示
{
uchar
i;
for(i=0;i<4;i++)
//依次从左至右选通数码管显示,实现动态显示
{
switch(i)
{
case
0:
//选通第一个数码管
wei2=1;
//关第二个数码管
wei3=1;
//关第三个数码管
wei4=1;
//关第四个数码管
wei1=0;
//开第一个数码管
if(a==0){selsct_1(f,t);}
//若a=0则在第一个数码管上显示测量温度的百位或‘-’
if(a==1)
{
P0=temperature3[3];
//若a=1则在第一个数码管上显示‘H’
}
if(a==2)
{
P0=temperature3[4];
//若a=2则在第一个数码管上显示‘L’
}
break;
case
1:
//选通第二个数码管
wei1=1;
wei3=1;
wei4=1;
wei2=0;
if(a==0){selsct_2(f,t);}
//若a=0则在第二个数码管上显示测量温度的十位或‘-’
if(a==1)
//若a=1则在第二个数码管上显示上限报警温度的百位或‘-’
{
if(s==0)
selsct_1(f_max,max);//若s=0则显示第二个数码管,否则不显示
else
P0=temperature3[0];
//通过s标志位的变化实现调节上下限报警温度时数码管的闪烁
if(s1==1)
selsct_1(f_max,max);//若s1=1则显示第二个数码管(s1标志位用于上下限查看时的显示)
}
if(a==2)
//若a=2则在第二个数码管上显示下限报警温度的百位或‘-’
{
if(s==0)
selsct_1(f_min,min);
else
P0=temperature3[0];
if(s1==1)
selsct_1(f_min,min);
}
break;
case
2:
//选通第三个数码管
wei1=1;
wei2=1;
wei4=1;
wei3=0;
if(a==0){P0=temperature2[t%10];}//若a=0则在第三个数码管上显示测量温度的个位
if(a==1)
//若a=1则在第三个数码管上显示上限报警温度的十位或‘-’
{
if(s==0)
selsct_2(f_max,max);//若s=0则显示第三个数码管,否则不显示
else
P0=temperature3[0];
if(s1==1)
selsct_2(f_max,max);//若s1=1则显示第三个数码管
}
if(a==2)
//若a=2则在第三个数码管上显示下限报警温度的十位或‘-’
{
if(s==0)
selsct_2(f_min,min);
else
P0=temperature3[0];
if(s1==1)
selsct_2(f_min,min);
}
break;
case
3:
//选通第四个数码管
wei1=1;
wei2=1;
wei3=1;
wei4=0;
if(a==0){P0=temperature1[t_d];}//若a=0则在第四个数码管上显示测量温度的小数位
if(a==1)
//若a=1则在第四个数码管上显示上限报警温度的个位
{
if(s==0)
P0=temperature1[max%10];//若s=0则显示第四个数码管,否则不显示
else
P0=temperature3[0];
if(s1==1)
P0=temperature1[max%10];//若s1=1则显示第四个数码管
}
if(a==2)
//若a=2则在第四个数码管上显示下限报警温度的个位
{
if(s==0)
P0=temperature1[min%10];
else
P0=temperature3[0];
if(s1==1)
P0=temperature1[min%10];
}
break;
}
display_delay(10);
//每个数码管显示3ms左右
}
}
/******************************************************/
/*
开机显示函数
/
/*****************************************************/
void
display1(uint
z)
//用于开机动画的显示
{
uchar
i,j;
bit
f=0;
for(i=0;i //‘z’是显示遍数的设定 { for(j=0;j<4;j++) //依次从左至右显示‘-’ { switch(j) { case 0: wei2=1; wei3=1; wei4=1; wei1=0; break; P0=temperature3[2];//第一个数码管显示 case 1: wei1=1; wei3=1; wei4=1; wei2=0;break; P0=temperature3[2];//第二个数码管显示 case 2: wei1=1; wei2=1; wei4=1; wei3=0;break; P0=temperature3[2];//第三个数码管显示 case 3: wei1=1; wei2=1; wei3=1; wei4=0;break; P0=temperature3[2];//第四个数码管显示 } display_delay(400); //每个数码管显示200ms左右 } } } #endif /******************************************************************** * 程序名; DS18B20头文件 * 说 明:用到的全局变量是:无符号字符型变量temp(测得的温度整数部分),temp_d * (测得的温度小数部分),标志位f(测量温度的标志位‘0’表示“正温度”‘1’表 * 示“负温度”),标志位f_max(上限温度的标志位‘0’表示“正温度”、‘1’表 * 示“负温度”),标志位f_min(下限温度的标志位‘0’表示“正温度”、‘1’表 * 示“负温度”),标志位w(报警标志位‘1’启动报警‘0’关闭报警)。 *********************************************************************/ #ifndef __ds18b20_h__ //定义头文件 #define __ds18b20_h__ #define uint unsigned int #define uchar unsigned char sbit DQ= P2^3; //DS18B20接口 sbit beer=P1^0; //用beer表示P1.0 sbit led=P1^1; //用led表示P1.1 uchar temp=0; //测量温度的整数部分 uchar temp_d=0; //测量温度的小数部分 bit f=0; //测量温度的标志位,0’表示“正温度” ‘1’表示“负温度”) bit f_max=0; //上限温度的标志位‘0’表示“正温度” ‘1’表示“负温度”) bit f_min=0; //下限温度的标志位‘0’表示“正温度”、‘1’表示“负温度”) bit w=0; //报警标志位‘1’启动报警‘0’关闭报警 /******************************************************/ /* 延时子函数 / /*****************************************************/ void ds18b20_delayus(uint t) //延时几μs { while(t--); } void ds18b20_delayms(uint t) //延时1ms左右 { uint i,j; for(i=t;i>0;i--) for(j=120;j>0;j--); } /******************************************************/ /* DS18B20初始化函数 / /*****************************************************/ void ds18b20_init() { uchar c=0; DQ=1; DQ=0; //控制器向DS18B20发低电平脉冲 ds18b20_delayus(80); //延时15-80μs DQ=1; //控制器拉高总线,while(DQ); //等待DS18B20拉低总线,在60-240μs之间 ds18b20_delayus(150); //延时,等待上拉电阻拉高总线 DQ=1; //拉高数据线,准备数据传输; } /******************************************************/ /* DS18B20字节读函数 / /*****************************************************/ uchar ds18b20_read() { uchar i; uchar d=0; DQ = 1; //准备读; for(i=8;i>0;i--) { d >>= 1; //低位先发; DQ = 0; _nop_(); _nop_(); DQ = 1; //必须写1,否则读出来的将是不预期的数据; if(DQ) //在12us处读取数据; d |= 0x80; ds18b20_delayus(10); } return d; //返回读取的值 } /******************************************************/ /* DS18B20字节写函数 / /*****************************************************/ void ds18b20_write(uchar d) { uchar i; for(i=8;i>0;i--) { DQ=0; DQ=d&0x01; ds18b20_delayus(5); DQ=1; d >>= 1; } } /******************************************************/ /* 获取温度函数 / /*****************************************************/ void get_temperature(bit flag) { uchar a=0,b=0,c=0,d=0; uint i; ds18b20_init(); ds18b20_write(0xcc); //向DS18B20发跳过读ROM命令 ds18b20_write(0x44); //写启动DS18B20进行温度转换命令,转换结果存入内部RAM if(flag==1) { display1(1); //用开机动画耗时 } else ds18b20_delayms(1); ds18b20_init(); ds18b20_write(0xcc); ds18b20_write(0xbe); a=ds18b20_read(); //读内部RAM (LSB) b=ds18b20_read(); //读内部RAM (MSB) if(flag==1) //局部位变量f=1时读上下线报警温度 { max=ds18b20_read(); //读内部RAM (TH) min=ds18b20_read(); //读内部RAM (Tl) } if((max&0x80)==0x80) //若读取的上限温度的最高位(符号位)为‘1’表明是负温度 {f_max=1;max=(max-0x80);} //将上限温度符号标志位置‘1’表示负温度,将上限温度装换成无符号数。 if((min&0x80)==0x80)//若读取的下限温度的最高位(符号位)为‘1’表明是负温度 {f_min=1;min=(min-0x80);} //将下限温度符号标志位置‘1’表示负温度,将下限温度装换成无符号数。 i=b; i>>=4; if (i==0) { f=0; //i为0,正温度,设立正温度标记 temp=((a>>4)|(b<<4)); //整数部分 a=(a&0x0f); temp_d=a; //小数部分 } else { f=1; //i为1,负温度,设立负温度标记 a=~a+1; b=~b; temp=((a>>4)|(b<<4)); //整数部分 a=(a&0x0f); //小数部分 temp_d=a; } } /******************************************************/ /* 存储极限温度函数 / /*****************************************************/ void store_t() { if(f_max==1) //若上限温度为负,将上限温度转换成有符号数 max=max+0x80; if(f_min==1) //若下限温度为负,将上限温度转换成有符号数 min=min+0x80; ds18b20_init(); ds18b20_write(0xcc); ds18b20_write(0x4e); //向DS18B20发写字节至暂存器2和3(TH和TL)命令 ds18b20_write(max); //向暂存器TH(上限温度暂存器)写温度 ds18b20_write(min); //向暂存器TL(下限温度暂存器)写温度 ds18b20_write(0xff); //向配置寄存器写命令,进行温度值分辨率设置 ds18b20_init(); ds18b20_write(0xcc); ds18b20_write(0x48); //向DS18B20发将RAM中2、3字节的内容写入EEPROM } //DS18B20上电后会自动将EEPROM中的上下限温度拷贝到TH、TL暂存器 /******************************************************/ /* 温度超限报警函数 / /*****************************************************/ void alarm() { //若上限值是正值 if(f_max==0) { if(f_min==0) //若下限值是正值 { if(f==0) //若测量值是正值 { if(temp<=min||temp>=max) {w=1;TR1=1;} //当测量值小于最小值或大于最大值时报警 if((temp {w=0;} //当测量值大于最小值且小于最大值时不报警 } if(f==1){w=1;TR1=1;} //若测量值是负值时报警 } if(f_min==1) //若下限值是负值 { if(f==0) //若测量值是正值 { if(temp>=max)//当测量值大于最大值时报警 {w=1;TR1=1;} if(temp {w=0;} } if(f==1) //若测量值是负值 { if(temp>=min)//当测量值大于最小值时报警 {w=1;TR1=1;} if(temp {w=0;} } } } if(f_max==1) //若下限值是负值 { if(f_min==1) //若下限值是负值 { if(f==1) //若测量值是负值 { if((temp<=max)||(temp>=min)) {w=1;TR1=1;} //当测量值小于最大值或大于最小值时报警 if((temp {w=0;} //当测量值小于最小值且大于最大值时不报警 } if(f==0){w=1;TR1=1;} //若测量值是正值时报警 } } } #endif /******************************************************************** * 程序名; 基于51单片机的温度计 * 功 能: 实时测量温度,超过上下限报警,报警温度可手动调整。K1是用来 * 进入上下限调节模式的,当按一下K1进入上限调节模式,再按一下进入下限 * 调节模式。在正常模式下,按一下K2进入查看上限温度模式,显示1s左右自动 * 退出;按一下K3进入查看下限温度模式,显示1s左右自动退出;按一下K4消除 * 按键音,再按一下启动按键音。在调节上下限温度模式下,K2是实现加1功能,* K1是实现减1功能,K3是用来设定上下限温度正负的。 *********************************************************************/ #include #include //将intrins.h头文件包含到主程序(调用其中的_nop_()空操作函数延时) #define uint unsigned int #define uchar unsigned char uchar max=0x00,min=0x00; //max是上限报警温度,min是下限报警温度 bit s=0; //s是调整上下限温度时温度闪烁的标志位,s=0不显示200ms,s=1显示1s左右 bit s1=0; //s1标志位用于上下限查看时的显示 void display1(uint z); //声明display1()函数(display.h头文件中的函数,ds18b20.h要用应先声明) #include“ds18b20.h“ #include“keyscan.h“ #include“display.h“ /******************************************************/ /* 主函数 / /*****************************************************/ void main() { beer=1; //关闭蜂鸣器 led=1; //关闭LED灯 timer1_init(0); //初始化定时器1(未启动定时器1) get_temperature(1); //首次启动DS18B20获取温度(DS18B20上电后自动将EEPROM中的上下限温度复制到TH和TL寄存器) while(1) { keyscan(); get_temperature(0); display(temp,temp_d*0.625); alarm(); } } /********************************************************************** * 程序名; ds18b20keyscan函数 * 功 能: 通过键盘设定设定上下限报警温度 **********************************************************************/ #ifndef __keyscan_H__ //定义头文件 #define __keyscan_H__ sbit key1=P2^2; sbit key2=P2^1; sbit key3=P2^0; sbit key4=P3^3; uchar i=0; //定义全局变量i用于不同功能模式的选择,‘0’正常模式,‘1’上限调节模式,‘2’下限调节模式 uchar a=0; //定义全局变量a用于不同模式下数码管显示的选择 bit k4=0; //K4按键双功能选择位,k4=0时K4按键选择消按键音的功能,k4=1时K4按键选择正负温度设定功能 bit v=0; //K2、K3按键双功能选择位,v=0时选择上下限查看功能,v=1时选择上下限温度加减功能 bit v1=0; //v1=1时定时1250ms时间到自动关闭报警上下限查看功能 bit v2=0; /消按键音功能调整位,为‘0’时开按键音,为‘1’时关按键音 /******************************************************/ /* 读键盘延时子函数 / /*****************************************************/ void keyscan_delay(uint z) //延时1ms左右 { uint i,j; for(i=z;i>0;i--) for(j=120;j>0;j--); } /******************************************************/ /* 温度调节函数 / /*****************************************************/ int temp_change(int count,bit f) //上下限温度调整 { if(key2==0) //判断K2是否按下 { if(v2==0)beer=0; //v2=0开按键音,否则消按键音 keyscan_delay(10); //延时10ms if(key2==0) //再次判断K2是否按下(实现按按键时消抖) { beer=1; //K2按下关按键音 if(f==0) //若温度为正 { count++; //每按一下K2温度上调1 if(a==1){if(count>125) count=125;}//当温度值大于125时不上调 if(a==2){if(count>125) count=125;} } if(f!=0) //若温度为负 { count++; //每按一下K2温度下调1 if(a==1){if(count>55) count=55;}//当温度值小于-55时不再下调 if(a==2){if(count>55) count=55;} } } while(key2==0); //K2松开按键时消抖 keyscan_delay(10); } if(key3==0) { if(v2==0)beer=0; keyscan_delay(10); if(key3==0) //K3按按键时消抖 { beer=1; count--; //每按一下K3温度为正时下调1,为负时上调1 if(a==1){if(count<0) count=0;}//当温度值达到0时不再调 if(a==2){if(count<0) count=0;} } while(key3==0); keyscan_delay(10); //K3松开按键时消抖 } return count; } /******************************************************/ /* 读键盘函数 / /*****************************************************/ void keyscan() { if(key1==0) { if(v2==0)beer=0; keyscan_delay(10); if(key1==0) //K1按按键时消抖 { beer=1; TR1=1; //开定时器1,通过s标志位的变化,实现在上下限温度调整时温度显示时闪烁的功能 k4=1; //在上下温度调节功能模式下选择K4的调整上下限温度正负的功能 v=1; //在上下温度调节功能模式下选择K2、K3的温度加减功能 i++; //K1按一下i加1,i=‘0’进入正常模式,i=‘1’进入调上限模式,i=‘2’进入调下限模式 if(i>2) //K1按下三次后退出调节模式 { i=0; //进入正常模式 TR1=0; //关定时器1 k4=0; //在正常模式下选择K4的消按键音功能 v=0; //在正常模式下选择K2、K3的查看上下限报警温度功能 store_t(); //存储调整后的上下限报警温度 } switch(i) //显示选择 { case 0:a=0;break; //a=0选择显示测得的温度 case 1:a=1;break; //a=1选择显示上限温度 case 2:a=2;break; //a=2选择显示下限温度 default:break; } } while(key1==0); //K1松按键时消抖 keyscan_delay(10); } if(a==1&&v==1) //a=1选择显示上限温度且v=1时选择上下限温度加功能 {led=0;max=temp_change(max,f_max);}//显示上限温度 else if(a==2&&v==1) //a=2选择显示下限温度且v=1时选择上下限温度减功能 {led=1;min=temp_change(min,f_min);} else; if(k4==1) //k4=1时K4按键选择正负温度设定功能 { if(key4==0) { if(v2==0)beer=0; keyscan_delay(5); if(key4==0) { beer=1; if(a==1) {if(max>55) f_max=0;else f_max=~f_max;}//当温度大于55度时,只能设定为正温度 if(a==2) {if(min>55) f_max=0;else f_min=~f_min;}//当温度大于55度时,只能设定为正温度 } while(key4==0); keyscan_delay(10); } } if(v==0) //v=0时选择上下限查看功能 { if(key2==0) { if(v2==0)beer=0; keyscan_delay(10); if(key2==0) { beer=1; a=1; //选择上限显示 TR1=1; //开定时器1开始定时一分钟左右 s1=1; //上限显示不闪烁,显示一分钟左右自动退出 } while(key2==0); keyscan_delay(10); } if(key3==0) { if(v2==0)beer=0; keyscan_delay(10); if(key3==0) { beer=1; a=2; //选择下限显示 TR1=1; //开定时器1开始定时1s s1=1; //下限显示不闪烁,显示1s自动退出 } while(key3==0); keyscan_delay(10); } if(v1==1) //v1=1时定时1s时间到自动关闭报警上下限查看功能 {a=0;v1=0;TR1=0;} //a=0显示实测温度,v1清零,关定时器1 if(k4==0) //k4=0时K4按键选择消按键音的功能 { if(key4==0) { if(v2==0)beer=0; keyscan_delay(10); if(key4==0) { beer=1; v2=~v2; //为‘0’时开按键音,为‘1’时关按键音 } while(key4==0); keyscan_delay(10); } } } } #endif 四、总结 单片机的学习与应用相关的总结与体会。在课设过程中,我们不仅巩固了平时所学习的单片机知识,而且通过不断查阅相关资料,学习新的知识,可以说,通过这次单片机的实践学习,我们学到了很多,而且对单片机的有关知识以及其在现实生活中的多方面应用有了更深层次的认识,这对于我们以后的学习和步入社会后参加工作都有很大的帮助。 在此次课程设计的进程中,我们遇到了很多问题,例如,一开始我们在确定课设题目后,在编写程序时,由于思路不太清晰,而且设计要求中需要使用新器件DS18B20智能测温,而其相关知识我们很模糊甚至可以说一无所知,不过后来,我们通过查找一些相关的资料书以及寻求辅导老师的帮助,又经过我们的主动思考,理清思路,终于将程序修改正确。在仿真时,由于我们有了之前的数模电课设仿真经验,所以此时我们课设进行的很顺利,并没有受到什么大的阻碍。 通过此次单片机课程设计,我们明白了很多,理论指导实践,但是理论也需要实践给予证明,不能盲目的相信书本,凡事都要通过自己的思考推敲,否则自己不会取的大的进步。而且在平时的学习生活中应该多和周围的同学相互学习,交流经验,遇到不会的东西时,切忌焦躁,首先要经过自己的独立思考,有了一定想法后,可以去查找相关的资料书刊或者找同学讨论,如果实在解释不了,再去找辅导老师,在这个遇到问题解决问题的过程中,不断加强自我的动脑能力,进而去指导动手能力,也只有这样,在思路清晰,条理顺畅的时候,再去进行软件编写和硬件操作工作,才有可能起到事半功倍的效果。 五、附录 系统硬件原理电路图 数字温度计设计器材表 单片机STC89C52 DS18B20 晶振12M 三极管8850 电容30PF 电解电容10UF/25V 小蜂鸣器 LED ø5红 电阻10k,3k,2k,1k,510,330 各5 4位一体共阴数码管 AC/DC(5V/1A)电源 IC插座40 9X15cm万用板 六、参考文献 1.1逆变电源数字化控制技术的发展 随着网络技术的发展,对逆变电源提出了更高的要求,高性能的逆变电源必须满足:高输入功率因数,低输出阻抗;暂态响应快速,稳态精度高;稳定性高,效率高,可靠性高;电磁干扰低等。要实现这些功能,离不开数字化控制技术。1.2传统逆变电源控制技术 1.2.1传统逆变电源控制技术的缺点 传统的逆变电源多为模拟控制系统。虽然模拟控制技术已经非常成熟,但其存在很多固有的缺点:控制电路的元器件比较多,电路复杂,所占的体积较大;灵活性不够,硬件电路设计好了,控制策略就无法改变;调试不方便,由于所采用器件特性的差异,致使电源一致性差,且模拟器件的工作点的漂移,导致系统参数的漂移。模拟方式很难实现逆变电源的并联,所以逆变电源数字化控制是发展的趋势,是现代逆变电源研究的一个热点。1.2.2传统逆变电源控制技术的改进 为了改善系统的控制性能,通过模拟、数字(A/D)转换器,将微处理器与系统相连,在微处理器中实现数字控制算法,然后通过输入、输出口或脉宽调制口(pulse width modulation, PWM)发出开关控制信号。微处理器还能将采集的功率变换装置工作数据,显示或传送至计算机保存。一些控制中所用到的参考值可以存储在微处理器的存储器中,并对电路进行实时监控。微处理器的使用在很大程度上提高了电路系统的性能,但由于微处理器运算速度的限制,在许多情况下,这种微处理器辅助的电路控制系统仍旧要用到运算放大器等模拟控制元件。近年来随着大规模集成电路技术的发展,一些专用心片的产生,使逆变电源的全数字控制成为现实。实时地读取逆变电源的输出,并实时地处理,使得一些先进的控制策略应用于逆变电源控制成为可能,从而可对非线性负载动态变化时产生的谐波进行动态补偿,将输出谐波达到可以接受的水平。 1.3逆变电源数字化控制技术的现状 1.3.1逆变电源控制技术数字化、智能化、网络化 随着电机控制专用芯片的出现和控制理论的普遍发展,逆变电源技术朝着全数化智能化及网络化的方向发展,逆变电源的数字控制技术发生了一次大飞跃。逆变电源数字化控制的优点在于各种控制策略硬件电路基本是一致的,要实现各种控制策略,无需变动硬件电路,只需修改软件即可,大大缩短了开发周期,而且可以应用一些新型的复杂控制策略,各电源之间的一致性很好,这样为逆变电源的进一步发展提供了基础,而且易组成可靠性高的大规模逆变电源并联运行系统。 1.3.2逆变电源数字化需要解决的一些难题 数字化是逆变电源发展的主要方向,但还是需要解决以下一些难题: a)逆变电源输出要跟踪的是一个按正弦规律变化的给定信号,它不同于一般开关电源的常值控制。在闭环控制下,给定信号与反馈信号的时间差就体现为明显的相位差,这种相位差与负载是相关的,这就给控制器的设计带来了困难。 b)逆变电源输出滤波器对系统的模型影响很大,输入电压的波动幅值和负载的性质,大小的变化范围往往比较大,这些都增加了控制对象的复杂性,使得控制对象模型的高阶性、不确定性、非线性显著增加。 c)对于数字式PWM,都存在一个开关周期的失控区间,一般是在每个开关周期的开始或上个周期之末来确定本次脉冲的宽度,即使这时系统发生了变化,也只能在下一个开关周期对脉冲宽度做出调整,所以现在逆变电源的数字化控制引起了广泛的关注。1.4逆变电源数字化的各种控制策略 逆变电源数字控制方法成为当今电源研究领域的一个热点,与数字化相对应,各种各样的离散控制方法也纷纷涌现,包括数字比例-积分-微分(PI)调节器控制、无差拍控制、数字滑变结构控制、模糊控制以及各种神经网络控制等,从而有力地推动逆变电源控制技术的发展。 1.4.1数字PI控制 数字PI控制以参数简单、易整定等特点得到了广泛应用。逆变器采用模拟数字PI控制时,如果只是输出电压的瞬时值反馈,其动态性能和非线性负载时的性能不会令人满意;如果是输出滤波电感或输出滤波电容的电流瞬时值引入反馈,其性能将得到较大改进,然而,庞大的模拟控制电路使控制系统的可靠性下降,调试复杂,不易于整定。数字信号处理芯片的出现使这个问题得以迅速解决,如今各种补偿措施及控制方式可以很方便地应用于逆变电源的数字PI控制中,控制器参数修改方便,调试简单。 但是,数字PI控制算法应用到逆变电源的控制中,不可避免地产生了一些局限性:一方面是系统的采样量化误差,降低了算法的分辨率,使得PI调节器的精度变差;另一方面,采样和计算延时使被控系统成为一个具有纯时间滞后的系统,造成PI控制器设计困难,稳定性减小,随着高速专用芯片及高速A/D的发展,数字PI控制技术在逆变电源的控制中会有进一步的应用。 1.4.2滑模变结构控制 滑模变结构控制(sliding mode variable structure control,SVSC)最显著的特点是对参数变化和外部扰动不敏感,即鲁棒性强,加上其固有的开关特性,因此非常适用于闭环反馈控制的电能变换器。 基于微处理器的离散滑模控制使逆变器输出波形有较好的暂态响应,但系统的稳态性能不是很理想。具有前馈控制的离散滑模控制系统[1],暂态性能和稳态精度得到提高,但如果系统过载时,滑模控制器的负担将变得非常重。自矫正离散滑模控制可以解决这个问题。 逆变器的控制器由参数自适应的线性前馈控制器和非线性滑模控制器组成,滑模控制器仅在负载导致输出电压变化时产生控制力,稳态的控制力主要由前馈控制器提供,滑模控制器的切换面(超平面)是根据优化准则进行设计的。1.4.3无差拍控制 无差拍控制(deadbeat control)是一种基于电路方程的控制方式,其控制的基本思想是将输出正弦参考波等间隔地划分为若干个取样周期,根据电路在每一取样周期的起始值,用电路理论算出关于取样周期中心对称的方波脉冲作用时,负载输出在取样周期末尾时的值。这个输出值的大小,与方波脉冲的极性与宽度有关,适当控制方波脉冲的极性与宽度,就能使负载上的输出在取样周期的末后与输出参考波形相重合[2]。不断调整每一取样周期内方波脉冲的极性与宽度,就能在负载上获得谐波失真小的输出。因此,即使在很低的开关频率下,无差拍控制也能够保证输出波形的质量,这是其它控制方法所不能做到的,但是,其也有局限性:由于采样和计算时间的延迟,输出脉冲的占空比受到很大限制;对于系统参数的变化反应灵敏,如电源电压波动、负载变动,系统的鲁棒性差。 对于采样和计算延时的影响,一种方法是通过修改输出脉冲方式的方法来减小计算延时造成的占空比局限;另一种方法是通过状态观测器对系统状态提前进行预测,用观测值替代实际值进行控制,从而避免采样和计算延时对系统的影响。为了提高系统的鲁棒性,一种方法是采用负载电流预测方法来减小负载变动对电源输出的影响,但实际改善的程度有限;另一种可行的方法是对系统参数进行在线辨识,从而实时确定控制器参数,以达到良好的控制效果。但是,在线系统辨识的计算复杂度和存储量都非常大,一般的微处理器很难在很短的时间内完成,因此实现的可能性不大,所以还没有一种比较好的方法来解决无差拍控制鲁棒性差的问题。正是由于无差拍控制在电源控制中的不足及局限性到目前还难以解决,使得无差拍控制在工业界的应用还有待不断的深入研究。1.4.4重复控制 逆变器采用重复控制(repetitive control)是为了克服整流型非线性负载引起的输出波形周期性的畸变,它通常与其他PWM控制方式相结合。重复控制的思想是假定前一周期出现的基波波形将在下一基波周期的同一时间重复出现,控制器根据给定信号和反馈信号的误差来确定所需的校正信号,然后在下一个基波周期的同一时间将此信号叠加到原控制信号上,以消除后面各周期中将出现的重复畸变[3]。 虽然重复控制使系统获得了很好的静态性能,且易于实现,但该技术却不能够获得好的动态性能。自适应重复控制方案成功地应用于逆变器的控制中。 模糊控制(fuzzy control)能够在准确性和简洁性之间取得平衡,有效地对复杂的电力电子系统做出判断和处理。将模糊控制应用于逆变器,具有如下优点:模糊控制器的设计不需被控对象的精确数学模型,并且有较强的鲁棒性和自适应性;查找模糊控制表只需占有处理器很少的时间,可采用较高采样率来补偿模糊规则和实际经验的偏差。 将输出电压和滤波电感电流反馈,即电压误差和电感电流作为输入模糊变量,可以实现逆变器的模糊控制,整流性负载时,其输出电压总谐波失真(total harmonic distortion,TH)小于5%,将模糊控制与无差拍控制相结合,可用来补偿由于非线性负载导致的电压降落,[5-6]。模糊控制从模仿人的思维外特性入手,模仿人的模糊信息处理能力。它对系统的控制是以人的经验为依据的,而人的经验正是反映人在思维过程中的判断、推理、归纳。理论上已经证明,模糊控制可以任意精度逼近任何线性函数,但受到当前技术水平的限制,模糊变量的分档和模糊规则都受到一定的限制,隶属函数的确定还没有统一的理论指导,带有一定的人为因素,因此,模糊控制的精度有待于进一步提高。 此外神经网络控制是一种使用人工神经网络的控制方法。因为人工神经网络是建立在强有力的数学基础上,所以它有很大的潜力,这个数学基础包括各种各样的已被充分理解的数学工具。在无模型自适应控制器中,人工神经网络也是一个重要组成部分。但由于神经网络的实现技术没有突破,还没有成功地应用于逆变电源的控制中。 第二章 推挽型逆变器的基础知识 2.1 开关型逆变器 广义地说,凡用半导体功率器件作为开关,将一种电源形态转变为另一种形态的主电路都叫做开关变换电路,这种变换可以是交流电和直流电之间的变换,也可以是电压或电流幅值的变换,或者是交流电的频率、相数等的变换。按电力电子的习惯称谓,基本的电力电子电路可以分为四大类型,即AC——DC电路、DC——AC电路、AC——AC电路、DC——DC电路。本文中的逆变电路就属DC——AC电路。开关逆变器中的开关都是在某一固定频率下工作,这种保持开关频率恒定,但改变接通时间长短(即脉冲宽度),使负载变化时,负载上电压变化不大的方法,称脉宽调制法(Pluse Width Modulation,简称为PWM)[4]。由于电子开关按外加控制脉冲而通断,控制与本身流过的电流、二端所加的电压无关,因此电子开关称为“硬开关”。凡用脉宽调制方式控制电子开关的开关逆变器,称为PWM开关型逆变器。本文是用SPWM专用产生芯片控制电子开关的通断,属硬开关技术。相对应有另一类控制技术“软开关”,它是一种使电子开关在其两端电压为零时导通电流,或使流过电子开关电流为零时关断的控制技术。软开关的开通、关断损耗理想值为零,损耗很小,开关频率可以做到很高。2.2 推挽型电路 各种变换电路按其是否具备电能回馈能力分为非回馈型和回馈型,非回馈型电路按其输出端与输入端是否电气个力分为非隔离型和隔离型。隔离型电路又分为正激型、反激型、半桥型、全桥型和推挽型。带中心抽头变压器原边两组线圈轮流工作的线路一般称为推挽线路,它不太适合离线变换器的应用。推挽型电路的一个突出优点是变压器双边励磁,在输入回路中仅有1个开关的通态压降,而半桥型电路和全桥型电路都有2个,因此在同样的条件下,产生的通态损耗较小,而且不需驱动隔离,驱动电路简单,这对很多输入电压较低的电源十分有利,因此低电压输入类电源应用推挽型电路比较合适。但是功率开关所承受的电压应大于2。 2.2.1 线路结构 图1-1 推挽型电路原理图 推挽型电路的原理图如图1-1所示。主变压器 原边绕组 接成推挽形式,副变绕组 接成全波整流形式。 2.2.2 工作原理 由于驱动电路作用,两个功率开关管、交替导通。当 导通时,加到 上,所有带“.” 端为正。功率开关管 通过变压器耦合作用承受 的电压。副边绕组 “.” 为正,电流流经、L到负载上。原边电流是负载折算至原边的电流及原边电感所定的磁化电流之和。导通期间,原边电流随时间而增加,导通时间由驱动电路决定。关断时,由于原边能量的储存和漏电感的原因,的漏极电压将升高.2.2.2推挽型逆变器的变压器设计 推挽型逆变器设计在整个电源的设计过程中具有最为重要的地位,一旦完成设计,不宜轻易改变,因此设计时对各方面问题考虑周全,避免返工,造成时间和经费的浪费。下面介绍具体设计。变压器是开关电源中的核心元件,许多其他主电路元器件的参数设计都依赖于变压器的参数,因此应该首先进行变压器的设计。高频变压器工作时的电压、电流都不是正弦波,因此其工作状况同工频变压器是很不一样的,设计公式也有所不同。需要设计的参数是电压比、铁心的形式和尺寸、各绕组匝数、导体截面积和绕组结构等,所依据的参数是工作电压、工作电流和工作频率等[5]。另外,变压器兼有储能,限流,隔离的作用.在磁心大小,原边电感,气隙大小,原,副边线圈匝数的选择,以及在磁心内直流成分和交流成分之间的相互影响都应在设计中细致考虑.第三章 基于单片机的控制系统设计 按照设计的要求,基于单片机AT89C52的设计主要实现以下功能:SA828的初始化及控制、ADC0809采样的数据的处理和输出显示电压频率。选用单片机作为主控器件,控制部分的原理框图如下: 图3-1 控制系统原理框图 3.1 系统硬件电路的设计 图3-2为控制部分的电路原理图。电路主要由AT89C52单片机、四位显示及驱动电路、AD采样电路、复位电路等组成。 图3-2 3.1.1 AT89C52单片机 AT89C52是美国ATMEL公司生产的低电压,高性能CMOS 8为单片机,片内含8k bytes 的可反复擦写的Flash只读程序存储器和256 bytes的随机存取数据存储器(RAM),器件采用ATMEL公司的高密度、非易失性存储技术生产,与标准MCS-51指令系统及8052善拼引脚兼容,片内置通用8位中央处理器(CPU)和Flash存储单元,功能强大AT89C52单片机适合于许多较为复杂控制应用场合。[6] 主要性能参数: 与MCS-51产品指令和引脚完全兼容 8k字节可充擦写Flash闪速存储器 1000次擦写周期 全静态操作:0Hz—24MHz 三级加密程序存储器 256×8字节内部RAM 32个可变成I/O口线 3个16位定时计数器 8个中断源 可编程串行UART通道 低功耗空闲和掉电模式 功能特性概述: AT89C52提供以下标准功能:8k字节Flash闪速存储器,256字节内部RAM,32个I/O口线,3个16位定时/计数器,一个6向量两极中断结构,一个全双工串行通信口,片内振荡器及时钟电路。同时,AT89C52可降至0Hz的静态逻辑操作,并支持两种软件可选的节电工作模式。空闲方式停止CPU的工作,但允许RAM,定时器/计数器,串行通信口及中断系统继续工作。掉电方式保存RAM中的内容,但振荡器停止工作并禁止其他所有部件工作直到下一个硬件复位。引脚功能: Vcc:电源电压 GND:地 P0口:P0口是一组8位漏极开路型双向I/O口,也即地址/数据总线复用口。作为输出口用时,每位能吸收电流的方式驱动8个TTL逻辑门电路,对端口P0写“1”时,可作为高阻抗输入端用。 在访问外部数据存储器或程序存储器时,这组口线分时转换地址(低8位)和数据总线复用,在访问期间激活内部上拉电阻。在Flash编程时,P0口接收指令字节,而在程序校验时,输出指令字节,校验时,要求外接上拉电阻。 P1口:P1是一个带有内部上拉电阻的8位双向I/O口,P1的输出缓冲级可驱动(吸收或输出电流)4个TTL逻辑门电路。对端口P1写“1”,通过内部的上拉电阻把端口拉到高电平,此时可作输入口。作输入口使用时,因为内部存在上拉电阻,某个引脚被外部信号拉低时会输出一个电流。 与AT89C51不同之处是,P1.0和P1.1还可分别作为定时/计数器2的外部技术输入(P1.0/T2)和输入(P1.1/T2EX)。 Flash编程和程序校验期间,P1接收低8位地址。 P2口:P2是一个带有内部上拉电阻的8位双向I/O口,P2的输出缓冲级可驱动(吸收或输出电流)4个TTL逻辑门电路。对端口P2写“1”,通过内部的上拉电阻把端口拉到高电平,此时可作输入口。作输入口使用时,因为内部存在上拉电阻,某个引脚被外部信号拉低时会输出一个电流。 在访问外部程序存储器或16位地址的外部数据存储器(例如执行MOVX @DPTR指令)时,P2口送出高8位地址数据。在访问8位地址的外部数据存储器(如执行MOVX @RI指令)时,P2口输出P2锁存器的内容。 Flash编程或校验时,P2亦接收高位地址和一些控制信号。 P3口:P3口是一组带有内部上拉电阻的8位双向I/O口。P3口输出缓冲级可驱动(吸收或输出电流)4个TTL逻辑门电路。对P3口写入“1”时,他们被内部上拉电阻拉高可作为输入端口。此时,被外部拉低的P3口将用上拉电阻输出电流。 P3口出了作为一般的I/O线外,更重要的用途是它的第二功能,如下表: 端口引脚 第二功能 P3.0 RXD(串行输入口)P3.1 TXD(串行输出口)P3.2(外中断0)P3.3(外中断1) P3.4 T0(定时/计数器0)P3.5 T1(定时/计数器1) P3.6(外部数据存储器写选通)P3.7(外部数据存储器读选通) 此外,P3口还接收一些用于Flash闪速存储器编程和程序校验的控制信号。 RST:复位输入。当振荡器工作时,RST引脚出现两个周期以上高电平将使单片机复位。XTAL1:振荡器反相放大器的及内部时钟发生器的输入端。XTAL2:振荡器反相放大器的输出端。对于本次设计的引脚使用情况如下: P1口:控制LED数码管8位段码;P3.0,P3.1,P3.4,P3.5:数码管位选通口;XTAL:接晶振;RST:接复位电路;P0: ADC0809的结果输入;SA828的控制字口;P2.0:SA828的片选;P2.7:ADC0809的片选;P3.2:外部中断0.AT89C52是一个低电压,高性能CMOS 8位单片机,片内含8KB的可反复擦写的Flash只读程序存储器和256×8位的随机存取数据存储器(RAM),3个16位定时/计数器、6个中断源、低功耗空闲和掉电方式等特点。器件采用ATMEL公司的高密度、非易失性存储技术生产,兼容标准MCS-51指令系统,片内置通用8位中央处理器和Flash存储单元,可以满足系统要求。系统采用5V电源电压,外接12M晶振。3.1.2显示电路 显示的方法分为动态显示和静态显示。所谓静态显示就是在同一时刻只显示一种字符,其显示方法简单,只需将显示段码送至段码口,并把位控字送至位控口即可。动态显示是利用人眼对视觉的残留效应,采用动态扫描显示的方法。[7]本设计采用动态显示,显示电路采用四位一体共阳极LED数码管,从P1口输出段码,位选控制端接于P3.0,P3.1,P3.4,P3.5。段驱动采用74LS245,位选驱动采用74LS244。硬件连接图如下: 图3-3 显示部分硬件连接图 3.1.3 A/D转换电路 A/D转换器采用集成电路0809完成,0809是8位MOS型A/D转换器。[] 1).主要特性 ① 8路8位A/D转换器,即分辨率8位;② 具有转换起停控制端; ③ 转换时间为100μs; ④ 单个+5V电源供电; ⑤ 模拟输入电压范围0~+5V,不需零点和满刻度校准; ⑥ 工作温度范围为-40~+85摄氏度; ⑦ 低功耗,约15mW。 2).内部结构 ADC0809是CMOS单片型逐次逼近式A/D转换器,内部结构如图所示,它由8路模拟开关、地址锁存与译码器、比较器、8位开关树型D/A转换器、逐次逼近寄存器、三态输出锁存器等其它一些电路组成。因此,ADC0809可处理8路模拟量输入,且有三态输出能力,既可与各种微处理器相连,也可单独工作。输入输出与TTL兼容。 图3-4ADC0809内部结构框图 3).外部特性(引脚功能) ADC0809芯片有28条引脚,采用双列直插式封装,如图3-5 所示。下面说明各引脚功能。 IN0~IN7:8路模拟量输入端。 2-1~2-8:8位数字量输出端。 ADDA、ADDB、ADDC:3位地址输入线,用于选通8路模拟输入中的一路。如表所示。 ALE:地址锁存允许信号,输入,高电平有效。图 3-5 ADC0809引脚图 START: A/D转换启动信号,输入,高电平有效。 EOC: A/D转换结束信号,输出,当A/D转换结束时,此端输出一个高电平(转换期间一直为低电平)。 OE:数据输出允许信号,输入,高电平有效。当A/D转换结束时,此端输入一个高电平,才能打开输出三态门,输出数字量。 CLK:时钟脉冲输入端。要求时钟频率不高于640KHZ。REF(+)、REF(-):基准电压。Vcc:电源,单一+5V。GND:地。 表3-6 ADDA、ADDB、ADDC真值表 ADC0809的工作过程是:首先输入3位地址,并使ALE=1,将地址存入地址锁存器中。此地址经译码选通8路模拟输入之一到比较器。START上升沿将逐次逼近寄存器复位。下降沿启动 A/D转换,之后EOC输出信号变低,指示转换正在进行。直到A/D转换完成,EOC变为高电平,指示A/D转换结束,结果数据已存入锁存器,这个信号可用作中断申请。当OE输入高电平时,输出三态门打开,转换结果的数字量输出到数据总线上。4).AD0809与控制电路的连接如下图: 图 3-7 AD0809的连接电路 3.1.4 SPWM波形电路 由于逆变开关管的开关时间要由载波与调制波的交点来决定。在调制波的频率、幅值和载波的频率这3项参数中.不论哪一项发生变化时,都使得载波与调制波的交点发生变化。因此,在每一次调整时,都要重新计算交点的坐标。显然,单片机的计算能力和速度不足以胜任这项任务。过去通常的作法是:对计算作一些简化,并事先计算出交点坐标.将其制成表格,使用时进行查表调用。但即使这样,单片机的负担也很重。 为了减轻单片机的负担,一些厂商推出了专用于生成三相或单相SPWM波控制信号的大规模集成电路芯片,如HEF4752、SLE4520、SA828、SA838等等。采用这样的集成电路芯片,可以大大地减轻单片机的负担,使单片机可以空出大量的机时用于检测和监控。这里详细介绍SA828三相SPWM波控制芯片的主要特点、原理和编程。3.1.5 SA828主要特点 ⑴.适用于英特尔和摩托罗拉两种总线格式,接口通用性好, 编程,操作简单,方便,快捷。⑵.应用常用的对称的双边采样法产生PWM波形, 波形产生数字化,无时漂,无温漂稳定性好。 ⑶.在外接时钟频率为12.5MHZ时载波频率可高达24KHZ,可实现静音运行。最小脉宽和死区时间通过软件设置完成,既节约了硬件成本,又使修改灵活方便。 调制频率范围宽,精度高(12位),输出正弦波频率可达4KHZ,可实现高频率高精度控制及光滑的变频.。 ⑷.在电路不变的情况下, 通过修改控制暂存器参数,就可改变逆变器性能指标,驱动不同负载或工作于不同工况。 ⑸.可通过改变输出SPWM脉冲的相序实现电机的正反转。 ⑹.独立封锁端可瞬时封锁输出PWM脉冲亦使微处理器防止突然事件的发生。3.1.6 SA828工作原理 SA828是MITEL公司推出的一种专用于三相SPWM信号发生和控制的集成芯片。它既可以单独使用,也可以与大多数型号的单片机接口。该芯片的主要特点为:全数字控制;兼容Intel系列和MOTOROLA系列单片机;输出调制波频率范围0—4kHz;12位调速分辨率;载波频率最高可达24kHz;内部ROM固化波形:可选最小脉宽和延迟时间(死区);可单独调整各相输出以适应不平衡负载。[8] SA828采用28脚的DIP和SOIC封装。其引脚如图3-8所示。各引脚的功能如下:(1)输入类引脚说明 AD0——AD7:地址或数据输入通道。 SET TRIP:通过该引脚,可以快速关断全部SPWM信号输出,高电平有效。 :硬件复位引脚,低电平有效。复位后,寄存器的、、WTE和RST各位为0。CLK:时钟输入端,SA828既可以单独外接时钟,也可以与单片机共用时钟。:片选引脚。 、、ALE:用于“ / ”模式,分别接收写、读、地址锁存指令。INTEL模式下ALE的下降沿传送地址,的上升沿给SA828写数据。在此模式下不用。 R/、AS、DS:用于“R/ ”模式,分别接收读/写、地址、数据指令。MOTOROLA模式下,AS的下降沿传送地址,当R/ 为低电平时,DS的下降沿给SA828写数据(接底电平) (2)输出类引脚说明 图3-8 RPHB、YPHB、BPHB:这些引脚通过驱动电路控制逆变桥的R、Y、B相的下臂开关管。RPHT、YPHT、BPHT:这些引脚通过驱动电路控制逆变桥的R、Y、B相的上臂开关管。 它们都是标准TTL输出.每个输出都有12mA的驱动能力,可直接驱动光偶。 :该引脚输出—个封锁状态。当SETTRIP有效时,为低电平、表示输出已被封锁。它也有12mA的驱动能力,可直接驱动一个LED指示灯。ZPPR、ZPPY、ZPPB:这些引脚输出调制波频率。WSS:该引脚输出采样波形。3.1.7内部结构及工作原理 SA828内部结构如图3-9所示。来自单片机的数据通过总线控制和译码进入初始化寄存器或控制寄存器,它们对相控逻辑电路进行控制。外部时钟输入经分频器分成设定的频率,并生成三角形载波,三角载被与片内ROM中的调制波形进行比较,自动生成SPWM输出脉冲。通过脉冲删除电路,删去比较窄的脉冲(如图3-10所示),因为这样的脉冲不起任何作用,只会增加开关管的损耗。通过脉冲延迟电路生成死区,保证任何桥臂上的两个开关管不会在状态转换期间短路。 图3-9 SA828的内部结构 片内ROM存有正弦波形。寄存器列阵包含3个8位寄存器和2个虚拟寄存器。他的虚拟寄存器R3的写操作结果是R0,R1,R2中的数据写入控制寄存器。虚拟寄存器R4的写操作结果是R0,R1,R2中的数据写入初始化寄存器。各寄存器地址如表3-11所列。 图 3-10 脉冲序列中的窄脉冲 AD2 AD1 AD0 寄存器 功能 0 0 0 R0 暂存数据 0 0 1 R1 暂存数据 0 1 0 R2 暂存数据 0 1 1 R3 传控制数据 1 0 0 R4 传初始化数据 表 3-11 其工作过程可简析如下:由于调制波形关于90度,180度,270度对称,故波形ROM中仅有0∽90度的波形瞬时幅值,采样间隔0.23度, 90度内共384组8位采样值存入ROM中,每个采样值线性的表达正弦波的瞬时值, 通过相位控制逻辑,将它组成0∽360度的完整波形.该调制波与载波比较产生三相六路双极性PWM调制波形.其经脉冲宽度取消电路,将脉冲宽度小于取消时间的脉冲去掉,再经脉冲延时电路引入死区时间,从而保证了在转换瞬间高,低端功率开关不会出现共同导通现象。图3-9中24位初始化暂存寄存器,可用来设置输出波形参数,例如载波频率,最小脉宽,脉冲取消时间计数器置”0” 图3-12 Intel总线时序 等。一经设置好,运行中不允许改变。24位控制寄存器,用来调整改变调制波频率,幅值,输出关闭,过调制选择,开机关机等.上述设置和调整均通过微处理器或微控制器发出指令,数据先存入三个8位暂存寄存器R0,R1,R2中,然后通过R3和R4分别传送给24位初始化寄存器和24位控制寄存器。初始化或调整时,端要置0。SA828由外配的微处理器通过复用MOTEL总线控制,并与外配的微处理器接口,该接口总线有自动适应英特尔和摩托罗拉两种总线格式及工作时序的能力(两种总线的工作时序如图3-12和3-13),在电路启动运行后,当AS/ALE端从低电平变为高电时,内部检测电路锁存DS/ 的状态,若检测结果为高电平则自动进入英特尔模式,若检测结果为低电平,则选择摩托罗拉模式工作,总线连接和定时信息相对所用微处理器而言,这个过程在每次AS/ALE变为高电平时要进行,实际中模式选择由系统自动设定。 图3-13 Motorola总线时序 3.1.8 SA828 初始化寄存器编程 初始化是用来设定与电机和逆变器有关的基本参数。它包括载波频率设定、调制波频率范围设定、脉冲延迟时间设定、最小删除脉宽设定、幅值控制。 初始化编程时,即设定各寄存器内容。下面分别介绍这些内容的设定。[9](1)载波频率设定 载波频率(即三角波频率)越高越好,但频率越高损耗会越大,另外,还受开关管最高频率限制,因此要合理设定。设定字由CFS0--CFS2这3位组成。载波频率 通过下式(3—1)求出。式中K为时钟频率,n值的二进制数即为载波频率设定字,可以取1,2,4,8,16或32。由于K=12MHz,当n=1时,反算得 =23.4375KHz,考虑到(max)=24KHz , <(max)当n=2时,=11.71725KHz ,故n取1,实际 =23.4375KHz。(2)调制波频率范围设定 根据调制频率范围.确定设定字。设定调制波频率范围的目的是在此范围内进行l2位分辨率的细分,这样可以提高控制精度,也就是范围越小.控制精度越高。调制被频率范围设定字是由FRS0—FRS2这3位组成。调制波频率 通过下式(3—2)求得。m值的二进制数即为调制波频率范围设定字。上面已得 =23.4375KHz,若取 =500Hz则m=8.192 ,考虑到调制波的频率为400Hz,则m=8 ,反算得 =488.28Hz。(3)脉冲延迟时间设定 该设定字是由PDY0—PDY5这6位组成。脉冲延迟时间 通过下式(3—3)求得。设脉冲延迟时间 则 =60(4)最小删除脉宽设定 最小删除脉宽设定字是由PDT0—PDT6这7位组成。最小删除脉宽 由下式(3—4)图3-14 延迟前后脉宽关系 求得。考虑到延迟(死区)的因素,在延迟时.通常的做法是在保持原频率不变的基础上,使开关管延迟开通.如图3-7所示.实际输出的脉宽=延迟前的脉宽--延迟时间。由结构图 可知.SA828的工作顺序是先删除最窄脉冲,然后再延迟.所以式(3—4)给出的 应是延迟前的最小删除脉宽。它等于实际输出的最小脉宽加上延迟时间,即 =实际输出的最小脉宽十 ,假设实际输出的最小脉宽=10 那么 =15 则 =180> =128 , =10.67 s 最小脉宽为5.67 s。(5)幅值控制 AC是幅值控制位。当AC=0时,控制寄存器中的R相的幅值就是其他两相的幅值。当AC=l时,控制寄存器中的R、Y、B相分别可以调整各自的幅值,以适应不平衡负载。 初始化寄存器通常在程序初始化时定义。这些参数专用于逆变电路中.因此,在操作期间不应该改变它们。如果一定要修改,可先用控制寄存器中的 来关断SPWM输出,然后再进行修改。 3.1.9 SA828控制寄存器编程 控制寄存器的作用包括调制波频率选择(调速)、调制波幅值选择(调压)、正反转选择、输出禁止位控制、计数器复位控制、软复位控制。控制数据仍然是通过Ro—R2寄存器输入并暂存,当向R3虚拟寄存器写操作时.将这些数据送入控制寄存器。(1)调制波频率选择 调制波频率选择字由PFS0—PFS7这8位组成。通过下式 (3-5)求得 值,它的二进制数即是调制波频率选择字。取 =400Hz , =488.28Hz ,得 =3355.45179(2)调制波幅值选择 通过改变调制波幅值来改变输出电压有效值,达到变频同时变压的目的。输出电压的改变要根据U/f曲线,随频率变化进行相应的变化。调制波幅值是借助于8位幅值选择字(RAMP、YAMP、BAMP)来实现的。每一相都可以通过计算下式 %(3-6)求出A值,它的二进制数即为幅值选择字(即RAMP或YAMP或BAMP)。式中的 就是调压比,注意,初始化寄存器的AC位决定了R相幅值是否代表另二相幅值。= =91.8=92(3)输出禁止位控制 输出禁止位。当 =0时,关断所有SPWM信号输出。(4)计数器复位控制 计数器复位位,当 =0,使内部的相计数器置为0(R相)。(5)软复位控制 RST是软复位位。它与硬复位 有相同的功能。高电平有效。 SPWM波形的产生,选择专用的芯片SA828,如前面所讲,这里不再论述。它和单片机的接口如下图所示: 3.2 系统软件的设计 3.2.1 初始化程序 系统上电时,初始化程序将数据存储区清零。3.2.2 主程序 完成定时器的初始化,开各种中断,循环调用各个子程序。包括电压显示子程序、AD转换子程序、828初始化子程序。主程序流程图见图 程序清单如下: START: SETB IT1;选择INT1为边沿触发方式 SETB EX1;开外中断1 SETB EA;开总控制中断 CLR PX1;外中断1为低优先级 SETB IT0;脉冲下降沿触发外中断0 SETB EX0;开外中断0 MOV TMOD,#01H;T0工作在定时,方式1 SETB PX0;外中断0为高优先级 MOV TH0,#00H MOV TL0,#00H ACALL KAISHI ACALL INCADC AJMP START 3.2.3 SA838初始化及控制子程序 按照单片机与SA828的接线图,P2.0作为SA828的片选控制口,因此SA828的起始地址为FE00H。系统上电复位之后首先对SA828写初始化字和控制字。具体计算如前面所述。流程图如下: 程序清单如下: CLR P2.1;禁止PWM输出 MOV A,#80H;SA828初始化寄存器 MOV DPTR,#0FE00H;SA828地址 MOVX @DPTR,A;给R0写数据 INC DPTR MOV A,#60H MOVX @DPTR,A;给R1写数据 INC DPTR MOV A,#04H MOVX @DPTR,A;给R2写数据 INC DPTR INC DPTR MOVX @DPTR,A;给初始化寄存器R4写数据 MOV A,#1BH;SA828控制寄存器 MOV DPTR,#0FE00H;SA828地址 MOVX @DPTR,A;给R0写数据 INC DPTR MOV A,#2DH MOVX @DPTR,A;给R1写数据 INC DPTR MOV A,#05CH MOVX @DPTR,A;给R2写数据 INC DPTR MOVX @DPTR,A;给控制寄存器R3写数据 SETB P2.1;允许PWM输 单片机对采样到的输出如做PI调节计算转换为电压幅值控制字后,需要重新写入控制字,其方法是相同的。 3.2.4 ADC0809的控制及数据处理子程序 单片机与ADC0809的接线图所示,P2.7作为ADC0809的片选控制口,因此ADC0809的起始地址为7F00H。如图所示,ADC0809的地址选择线接地,固定8路模拟数据输入端重IN-0为电压采样输入端。ADC0809的CLK信号是从AT89C52的ALE端经四分频器74LS74分频后得到的,工作频率为500HZ,转换时间为128us左右,据此设计一个延时时间,延时时间一到,采用查询方式进行数据传送。即用软件测试EOC(P3.1)的状态,若测试结果为1,则转换结束接着进行数据传送,否则等待,直到测试结果为1。因为ADC0809的最大输入电压为5V,其转换结果FFH对应5V。所以FFH对应的输入应大于等于5V,表示输入超过量程。本设计中FFH对应36V,其转换公式为,X=,因此程序中有二进制转换及乘14子程序,除以100处理为小数点固定显示在次低位。另外,考虑到系统存在电磁干扰,采用了中值滤波子程序进行软件抗干扰。中值滤波对于去掉由于偶然因素引起的波动或采样器不稳定而造成的误差所引起的脉动干扰比较有效。中值滤波之后将最优值存于6AH中再进行转换处理。流程图如图下面是程序清单: INCADC: MOV R0,#2CH MOV R2,#03H SAMP: MOV DPTR,#7F00H;AD0809端口地址送DPTR MOV A,#00H;输入通道0选择 MOVX @DPTR,A;启动A/D转换 MOV R7,#0FFH;延时查询方式 DELAY:DJNZ R7,DELAY LOOP1:JB P3.1,T1;查询p3.1是否为1 JNB P3.1,LOOP1 T1:MOVX A,@DPTR;读取从IN0输入的转换结果 MOV @R0,A INC R0 DJNZ R2,SAMP 以下是数字滤波程序流程图及程序清单: FILTER:MOV A,6CH CJNE A,6DH,CMP1 AJMP CMP2 CMP1:JNC CMP2 XCH A,6DH XCH A,6CH CMP2:MOV A6DH CJNE A,6EH,CMP3 MOV 6AH,A CMP3:JC CMP4 MOV 6AH,A CMP4:MOV A,6EH CJNE A,6CH,CMP5 MOV 6AH,A CMP5:JC CMP6 XCH A,6CH CMP6:MOV 6AH,A;滤波结果存于6AH RET 3.2.5 数据处理及电压显示子程序 DISPLAY: MOV A,6AH ACALL L1;十进制转换 ACALL PLAY RET PLAY:;显示程序 MOV A,R5;分离D1 ANL A,#0FH MOV 50H,A MOV A,R5;分离D2 ANL A,#0F0H SWAP A MOV 51H,A MOV A,R4;分离D3 ANL A,#0FH MOV 52H,A MOV A,R4;分离D4 ANL A,#0F0H SWAP A MOV 53H,A PLAY1: CLR P2.6 CLR P2.5 CLR P2.4 CLR P2.3 MOV R1,#50H;显示数据首地址 MOV P1,#0FFH;清除原来的数据 SETB P2.3;显示最低位 MOV A,@R1 MOV DPTR ,#TAB MOVC A,@A+DPTR MOV P1,A LCALL DL1MS;数据显示1ms CLR P2.3 MOV P1,#0FFH INC R1 SETB P2.4;显示次低位 MOV A,@R1 MOV DPTR ,#TAB MOVC A,@A+DPTR ANL A,#7FH;小数固定显示 MOV P1,A LCALL DL1MS CLR P2.4 MOV P1,#0FFH INC R1 SETB P2.5;显示次高位 MOV A,@R1 MOV DPTR ,#TAB MOVC A,@A+DPTR MOV P1,A LCALL DL1MS CLR P2.5 MOV P1,#0FFH INC R1 SETB P2.6;显示最高位 MOV A,@R1 JZ NODISPLAY;若A=0,则不显示 MOV DPTR ,#TAB MOVC A,@A+DPTR MOV P1,A LCALL DL1MS CLR P2.6 MOV P1,#0FFH NODISPLAY: MOV P1,#0FFH AJMP PLAY1 RET L1:CLR C;十进制转换 MOV R5,#00H MOV R4,#00H MOV R3,#08H NEXT1:RLC A MOV R2,A MOV A,R5 ADDC A,R5 DA A MOV R5,A MOV A,R4 ADDC A,R4 DA A MOV R4,A MOV A,R2 DJNZ R3,NEXT1 RET TAB:DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H,0FFH DL1MS: MOV R6,#14H DL1:MOV R7,#19H DL2:DJNZ R7,DL2 DJNZ R6,DL1 RET 3.2.6 输出频率测试计算及显示子程序部分 ⑴.频率测试计算子程序部分 SA828带有频率输出端口,将其与单片机的中断INT0口相接,如原理图所示。本例中所使用的中断源有2个:T0中断和 中断。中断的功能是计算ZPPR输出的调制波频率。由于调制波频率可能比较低,因此用T0溢出中断来记录一个ZPPR周期中T0溢出的次数,这个溢出次数保存到70H中。这样,在一个 中断间隔里,所用的时间(即ZPPR周期)是3个字节的数(1个字节的T0溢出次数,2个字节的T0值)。因为AT89C52使用12MHZ的时钟频率,一个机器周期是,所以调制波频率的计算公式为: =0F4240H,也是一个3字节的数,因此 是一个3字节除法运算。如果对精度要求不高,的分子分母可以舍掉最低字节来简化运算,这样就成为双字节除法运算。所以,当 中断时,只取TH0,将其存放到71H中除法运算的整数商存放到72H、73H中,小数商存放到75H中,以便频率显示程序中调用。 中断子程序及流程图如下: SUANPIN: CLR EA;关中断 CLR TR0 PUSH ACC;保存现场 PUSH B PUSH DPL PUSH DPH PUSH PSW PUSH 50H PUSH 51H PUSH 52H PUSH 53H PUSH 60H PUSH 61H PUSH 62H PUSH 63H PUSH 6AH SETB PSW.3 MOV 70H,#00H;MOV TL0,#00H;TL0清0 MOV 71H,TH0;取TH0值 MOV TH0,#00H;TH0清0 MOV A,71H;检查除数是否为0 ORL A,70H;不会溢出,高位永远为零 JZ ABC;除数为0则退出 MOV R2,#00H;输入被除数 MOV R3,#00H MOV R4,#0FH MOV R5,#42H MOV R6,70H;输入除数 MOV R7,71H LCALL NDIV;调用双字节除法子程序原来的程序,NDIV:MOV B,#16;双字节无符号数除法子程序;当条件(R2R3)〈(R6R7)满足时,;(R2R3R4R5)/(R6R7)=(R4R5),余数在(R2R3)NDVL1: CLR C MOV A,R5 RLC A MOV R5,A MOV A,R4 RLC A MOV R4,A MOV A,R3 RLC A MOV R3,A XCH A,R2 RLC A XCH A,R2 MOV F0,C CLR C SUBB A,R7 MOV R1,A MOV A,R2 SUBB A,R6 JB F0,NDVM1 JC NDVD1 NDVM1: MOV R2,A MOV A,R1 MOV R3,A INC R5 NDVD1:DJNZ B ,NDVL1 CLR F0 MOV 72H,R4;频率整数部分存于7273H中 MOV 73H,R5;调制波频率整数部分存72H MOV 75H,R2;将调制波频率小数部分(小于100)存75H MOV 70H,#00H;70H清0 ABC:POP 6AH POP 63H POP 62H POP 61H POP 60H POP 53H POP 52H POP 51H POP 50H POP PSW;恢复现场 POP DPH POP DPL POP B POP ACC SETB EA;开中断 SETB TR0 RETI ⑵.频率显示部分 本系统用一个四位一体的LED数码管显示数据,系统初始化后显示的为电压,按频率显示按钮显示频率。利用中断源 显示,它将72H、73H中的频率整数(二进制数)部分先进行二--十转换存于R3R4R5中,根据经验,转换过来的十进制数只有百位,即R3中的值为00,R4中的值为0X。因此将R4R5中的数分离分别在最高位、次高位、次低位显示,并且次低位带有小数点。将75H中的小数部分在最低位显示。至此,频率显示部分完成。 中断程序及流程图如下: DISPLAYF:PUSH ACC;保存现场 PUSH B PUSH DPL PUSH DPH PUSH PSW PUSH 50H PUSH 51H PUSH 52H PUSH 53H PUSH 60H PUSH 61H PUSH 62H PUSH 63H PUSH 6AH SETB PSW.4;使用第二工作寄存区 MOV R6,72H;频率整数部分存欲R6R7中调用双字节十进制转换程序 MOV R7,73H;;ACALL HB2;调用双字节十进制转换程序 HB2:CLR A;BCD码初始化;双字节十进制转换 MOV R3,A MOV R4,A MOV R5,A MOV R2,#10H;转换双字节二进制整数 HB3:MOV A,R7;从高端移出待转换数的一位到CY中 RLC A MOV R7,A MOV A,R6 RLC A MOV R6,A MOV A,R5;BCD码带进位自身相加,相当于乘2 ADDC A,R5 DA A;十进制调整 MOV R5,A MOV A,R4 ADDC A,R4 DA A MOV R4,A MOV A,R3 ADDC A,R3 MOV R3,A DJNZ R2,HB3 MOV A,75H;频率小数部分在最低位显示 ANL A,#0F0H SWAP A MOV 50H,A MOV A,R5;频率整数部分个位数在次低位显示 ANL A,#0FH CLR CY SUBB A,#07H MOV 51H,A MOV A,R5;频率整数部分十位数在次高位显示 ANL A,#0F0H SWAP A CLR CY SUBB A,#05H MOV 52H,A MOV A,R4;频率整数部分百位数在最高位显示 ANL A,#0FH DEC A MOV 53H,A ACALL PLAY;显示频率 POP 6AH POP 63H POP 62H POP 61H POP 60H POP 53H POP 52H POP 51H POP 50H POP PSW;恢复现场 POP DPH POP DPL POP B POP ACC AJMP DISPLAYF RETI 第四章 联机调试及结果分析 4.1 联机调试情况 系统的调试分为硬件调试和软件调试两个部分。硬件调试包括控制电路的调试和主电路的调试。调试时,应该先调控制部分。首先检查电路的焊接是否正确,然后用万用表测试或通电检测。主电路部分硬件的检测方法同控制部分。硬件检查无误后,软件调试。软件调试可以先编写显示程序并进行硬件的正确性检验,然后分别进行主程序、AD转换子程序、电压显示子程序、频率显示子程序、数字滤波子程序等子程序的编程及调试。 在联机调试前,先用伟福模拟仿真,然后利用爱思G3000在线联机调试。联机调试时出现了下面一些问题: 1).四位一体LED显示管不显示; 2).P1口没有数据输出; 3).AD转换器不工作; 4).SA828的输出波形不正确。解决的办法及处理结果: 1).检查各个数码管的位控端及代码段是否连接完好,给它加的驱动是否正确,以及各个数码管本身是否完好。经检测是我们的驱动连接有问题,重新连接后,显示正常。 2).P1口没有数据输出的原因也是我们的显示驱动出错导致,当驱动错误排除后,P1口数据输出正常。 3).和AD转换器的各个连线都联结正确,我们的焊接技术不好,出现了个别引脚虚焊,虚焊处理后,问题解决。 4).SA828的输出波形下桥臂出现一段脉宽为1us的不正常波形,按照电路设计原理,小于5.67us的波形在脉冲删除电路中是该删除掉的,由于三相下桥臂均输出这种不正常的波形,我们用到了SA828的输出禁止端SETTRIP,把此端接上高电平即可使输出禁止而不影响内部电路的正常工作,但是实验结果还能看到此不正常的波形,若其是内部电路产生,即使不能删除,在输出禁止时理论上应该是能禁止的。又考虑到可能是干扰所至,消除掉可能存在的干扰后依然存在此波形。初次使用这系列的芯片,对其资料也不完全掌握,实验最后,仍留此问题,亟待日后解决。另外,在绞尽脑汁之后,发现一个问题,原来认为不用的芯片端口可以按其功能相应的接高电平或接地,在这样做之后,芯片发烫,断开连接即恢复正常 4.2 实验验证及结果分析 1).1).从SA828的RPHT、PRHB输出的驱动脉冲信号如下图4-1所示 图4-1 PWM输出的上、下桥臂的驱动信号 2).经过TTL驱动电路,加在栅极的驱动电压信号如图4-2所示。图4-2 MOSFET栅极的驱动信号 3).仿真交流输出信号如图4-3所示 图4-3 仿真交流输出信号 4).结果分析 实验室搭建主电路进行实验和调试,获得了较好的实验效果。该系统输出正弦波的频率为400HZ。试验证明整个系统方案结构紧凑,实时性较好。4.3结论 在前面的系统硬件软件设计下,我们在实验室组成实际的线路进行了实验和调试,获得了较为良好的实验效果。该系统输出正弦波合成的频率为400HZ,试验证明整个系统结构紧凑,实时性较以完全单片机软件编程产生SPWM波的方法要好得多,而他的功能又比用HEF4752等纯硬件方法生成的SPWM波的方法完善。综上分析及实验验证,可以得到下面几点结论: 1).SA828时一个高性能的SPWM专用IC,在合适的外围条件的支持下,它可以输出较好的SPWM脉冲信号。 2).以单片机最小系统来完成SA828的外围硬件支持,可以使系统的硬件结构简化,提高可靠性,减小系统成本和体积。 3).文中介绍的以AT89C52最小系统与SA828相结合构成的全数字化SPWM脉冲形成系统,即可解决全软件编程产生SPWM脉冲波的缺陷,又可以弥补纯硬件系统完成SPWM脉冲生成方案的不足,是一种较好的方案。4).文中介绍的SPWM脉冲形成方案,不仅在开关电源的数字化制作方面是一个尝试和创新,而且在直流调速、交流调速、变频电源、电力回收领域,也具有通用性,它应用前景广阔。 1、系统设计方案 本设计采用MSC-51系列单片机ATSC51为中心器件来设计交通灯控制器, 通过89C51芯片的P1口设置红、绿、黄灯燃亮时间的功能;红绿灯循环点亮, 倒计时剩3秒时黄灯点亮[3]。交通灯显示由89C51的P2口控制, 单片机从定时数据区取得延时时间后, 由定时器TO控制延时, 在数码管上动态扫描显示剩余时间。系统总框图为: 2、系统硬件设计 交通信号控制系统设置在十字路口, 负责东西及南北方向的车辆行驶交通信号指示。系统将东西方向的交通信号灯分为一组, 而南北方向的交通信号灯为另一组[4]。每组路口分别有三种信号灯:红色信号灯禁止车辆通行, 黄色信号灯警告通行车辆, 绿色信号灯允许车辆通行。因此本系统的交通信号灯共有4种信号灯显示状态。该4种状态如表1所示: 由此可画出交通灯的硬件电路图如系统仿真中所示。其中P0口接12盏交通指示灯, P1口, P2口接二位一体的数码管, P3.2, P3.3, P3.4接拨码开关DIPSW-3, 控制四方红灯点亮[5]。当有紧急车辆通过时, 要求四个方向红灯点亮, 此时需要一个拨码开关DIPSW-3与89C51的P3.2, P3.3, P3.4连接。拨动拨码开关, 即可实现四个方向的红灯点亮。 3、系统软件设计 图2给出了基本交通的主程序流程。 4、系统仿真 仿真开始, 东西路口为绿灯, 数码管从57开始倒计时;南北方向为红灯, 数码管从60秒开始倒计时。 5、结语 本文顺利完成交通灯控制系统硬件设计。该硬件平台能为程序运行提供稳定的工作环境, 让程序加载到硬件电路上的单片机上运行, 能基本满足设计要求:设置红绿灯燃亮时间的功能;红绿灯循环点亮, 黄灯闪烁, 倒计时3秒时黄灯闪烁警示;在紧急情况下四方红灯点亮。 摘要:交通信号灯在当今社会生活中起着非常重要的作用, 随着时代的发展, 单片机的应用正在不断深入。本系统采用MSC-51系列单片机ATSC51为中心器件来设计交通灯控制器, 实现了在紧急情况下可自动将绿灯变为红灯来使紧急车辆通过的功能。本系统实用性强、操作简单、扩展功能强。 关键词:单片机,交通灯,控制,紧急情况 参考文献 [1]丁元杰..单片机原理与应用[M].机械工业出版社, 2004:2~3 [2]马家辰.MCS-51单片机原理及接口技术实验[M].哈尔滨工业大学出版社, 1997:31~34. [3]周向红.51系列单片机应用与实践教程[M].北京航空航天大学出版社, 2008:22~25 [4]郑建光, 李永.基于AT89C51单片机的交通灯系统设计[M].自动化与仪器仪表, 2008:79~84. 前言 目前,单片机在各种领域都得到了广泛的认可和应用,尤其是在智能仪表中的应用更是家常便饭,即引起了單片机的产品变革,又在很大程度上促进了设计理念的革新。智能仪表是智能系统的重要组成部分之一,其正常工作的关键在于单片机的设计。如今,设计单片机系统逐渐成为电子设计专家和设计爱好者的关注焦点。 一、电子时钟的功能 在设计电子时钟时,对电子时钟功能的最基本要求是电子时钟必须具备运行和调整两种状态:第一,运行状态。在此种状态下,需要设计K1、K2两个有效按键,在按下K1键时,电子时钟可以进入调整状态;第二,调整状态。在这种状态下,需要设计K3、K4两个有效按键,当按K1键进入调整状态后按下K3键能够对电子时钟的数字位置进行调节,按下K4将会调节闹钟开关并分别对时分秒数字加一,继续按K3则离开调节状态而进入运行状态。 1.1电子时钟的计时方案 通过计数器中断定时或AT89C51单片机内部定时,合理结合软件延时来对时分秒进行计时。这种电子时钟的设计方案能够节省硬件成本,还能通过定时提醒读者需要做的重要事情。其设计思路不仅可以刺激计数器在程序设计、使用及中断等方面的提高,还能加深对单片机指令系统的掌握,进而实现单片机技术的使用和推广。虽然单片机相比现在的嵌入式等会略逊一筹,但其目前还是应用最广泛的设计芯片。 1.2电子时钟设计原理 电子时钟的主要构成部件是译码显示器、校时电路、时分秒计数器、报时电路与振荡器,主电路系统包括时分秒计数器、校时电路、显示器、整点报时电路、译码器和秒信号发生器。其中,秒信号发生器作为整个系统时基信号,可以直接决定计时系统精确度,通常借助分频器和石英晶体振荡器的相互作用来完成。把标准秒信号输入60进制的“秒计数器”,因而每相隔60秒就会发出“分脉冲”信号,这个信号即为“分计数器”时钟脉冲。“时计数器”应该采用24进制的计时器,这样就能进行每天24小时的计时。电子时钟通常由1601液晶、89C52组成,其驱动电路为晶振电路。电路中的唯一控制键K1具有中断电路的功能,按下K1键后再按设置键K3能够对时分秒、闹钟开关和时分秒位置进行设定,继续按调节键K4可以对时分秒、闹钟开关、闹钟设定的时分秒进行加一调节[1]。 二、电子时钟的硬件与软件设计 2.1电子时钟的硬件设计 电子时钟的核心部分采用51系列单片机,硬件电路包括按键电路、AT89C51单片机、LED显示电路、音乐报时电路。其中,按键电路能够通过按键来切换电子秒表功能和电子时钟,设定电子时钟的时间对时、显示内容、闹钟定时功能,控制电子秒表计时、暂停、继续计时、清零功能。AT89C51单片机片中置有存储器为4K的E2PROM程序,不需要对程序存储器进行外扩,在单片机外侧接入上电复位电路和12MHz晶振电路。LED显示电路选择红色共阳极数码管,通过动态扫描方式显示数据,在段选控制处接限流电阻,在位选控制处利用三极管进行驱动,通过1m/s定时中断服务程序动态扫描显示各个部位。电子时钟的功能时显示按照位次依次显示星期、小时、分钟、秒、十分之一秒、百分之一秒,并且可以通过控制按键切换年月日显示[2]。音乐报时电路的设计需要选取两个不同的HL9300E音乐集成片,便于分别进行定时音乐报时和整点音乐报时。定时音乐报时和整点音乐报时需要接入不同的触发控制端,二者互相切换,进而避免两个音乐集成芯片同步放乐的干扰。在GND与5V电源的AT89C51之间设计加入470uF的电解电容,可在其旁边多并联接几个小的瓷片电容,可改善音质。音乐集成片输出端接扬声器或蜂鸣器,这样可以有效防止因继电器触点吸合而造成的系统复位,从而使由按键清除闹钟定时时间的报时音乐声。 2.2电子时钟的软件设计 把AT89C51内部定时和计数器设置为定时器工作模式是电子秒表和电子时钟的计时基准.时针定时器的中断信号为10m/s,即每经过100次中断,时钟秒位加一,秒位经60次加一后向时位进位,当时间为23时59分59秒时,秒位再加一后变为00时00分00秒。当按键切换为电子秒表功能时,秒针定时器每产生一次中断,十毫秒单元加一,其经过10次加一后,百毫秒单元加一,依次进位可实现最长为9小时59分59秒999毫秒的秒表计时,可达到分辩10m/s的计时精度。 通过K1~K4按键可对时钟加以对时,当第一次按下K1键时,显示数码管第一位闪烁,继续按键时,下一位闪烁。当某一位闪烁时,按下K2按键能够使闪烁位加一。在正常时钟显示方式下,按下K2键可以转换年、月、日的显示。按下K3键能够进入秒表状态,按下K4键能够显示闹钟定时时间[3]。 三、电子时钟的键盘设计 本设计使用单键盘的方式设计,功能较为完备,既能减少对硬盘资源的损耗,又能调节和控制时分秒,使其转换为省电模式。在按键又松开后通过屏蔽数码管显示功能达到省电目的;在按键不松开时能够累加时分秒数字,按键一次累加一分钟;在连续按键两次时,能够调节时针,同样是累加一次为一小时,在达到时间调节目的后,延缓一段时间来判断并确保按下此键,然后对键值和处理程序进行保存。 总结 综上所述,本文设计的电子时钟具有功能齐全、性价比高、电路简单、制作成本低等优点,只要接入单电源即可供电,方便于在办公室和家庭等场所使用。简单的时钟设计对增强电子专业学生的动手能力及独立设计思考能力都会有很大的提高,本片的设计思想可作为市场产品加以推广也可作为电子专业学生设计电子时钟的参考,希望本文对读者有些许帮助。 参考文献 [1]王丹丹,郑宽磊.一种新的基于层次化模式实现的SOC时钟设计方法[J].微电子学与计算机,2011,11(04):89-93. [2]陈媛媛.基于无线网络的GPS时钟同步与信息发布系统[J].科学中国人,2014,08(23):2. [3]牛国锋,朱苗苗.基于瑞萨微控制器的LED电子时钟设计与实现[J].常熟理工学院学报,2012,02(18):120-124. (作者单位:西北师范大学) 作者简介 【基于单片机交通灯设计】推荐阅读: 基于51单片机的数字频率计的设计概要12-01 基于单片机的16×16点阵LED电子显示屏的设计报告12-18 基于单片机的开题报告01-07 基于fpga的交通灯设计07-23 单片机课程设计任务01-01 单片机实验程序设计02-14 《数字电路与单片机课程设计》课程设计报告11-01 单片机课程设计报警器07-13 单片机课程设计流水灯11-23 单片机课程设计报告多功能秒表02-14基于单片机的逆变电源系统设计 篇6
基于单片机交通灯设计 篇7
基于单片机的电子时钟设计概述 篇8