以智能速度里程表为主的多功能系统设计.docx
《以智能速度里程表为主的多功能系统设计.docx》由会员分享,可在线阅读,更多相关《以智能速度里程表为主的多功能系统设计.docx(24页珍藏版)》请在冰豆网上搜索。
以智能速度里程表为主的多功能系统设计
《单片机原理及应用》课程设计报告
课题:
以智能速度里程表为主的多功能系统设计
班级电气3072学号**********
学生姓名虞光远
指导教师李洪海严石段卫平
淮阴工学院
电子与电气工程学院
一、课程设计目的
二、设计要求
1、总体要求
2、具体要求
3、具体课题:
三器件介绍
四、设计步骤
4.1硬件初步设计
4.2硬件原理电路图
4.3单元电路设计
五、软件初步设计
5.1主程序流程图
5.2各模块流程图
六详细完整的程序清单及注释
一、课程设计目的
《单片机原理及应用》课程设计是一项重要的实践性教育环节,是学生在校期间必须接受的一项工程训练。
在课程设计过程中,在教师指导下,运用工程的方法,通过一个简单课题的设计练习,可使学生通过综合的系统设计,熟悉应用系统的设计过程、设计要求、完成的工作内容和具体的设计方法,了解必须提交的各项工程文件,也达到巩固、充实和综合运用所学知识解决实际问题的目的。
通过课程设计,应能加强学生如下能力的培养:
(1)独立工作能力和创造力;
(2)综合运用专业及基础知识,解决实际工程技术问题的能力;
(3)查阅图书资料、产品手册和各种工具书的能力;
(4)工程绘图的能力;
(5)编写技术报告和编制技术资料的能力。
二、设计要求
1、总体要求
(1)独立完成设计任务
(2)绘制系统硬件总框图
(3)绘制系统原理电路图
(4)制定编写设计方案,编制软件框图,完成详细完整的程序清单和注释;
(5)制定编写调试方案,编写用户操作使用说明书
(6)写出设计工作小结。
对在完成以上文件过程所进行的有关步骤如设计思想、指标论证、方案确定、参数计算、元器件选择、原理分析等作出说明,并对所完成的设计作出评价,对自己整个设计工作中经验教训,总结收获和今后研修方向。
2、具体要求
本次工程实践主要以单片机为基础,进行单片机软件编程,目的是为了提高学生的软件编程和系统设计能力,整个设计系统包括两个部分,硬件及软件部分,硬件部分已经制作成功,学生只需要掌握其原理和焊接相应的元器件,掌握元器件的辨别和元器件的作用以及应用场所即可,另外对所焊接的电路还需要进行仔细的检查,判断是否有焊接错误的地方或者短路的地方,对出现的异常情况要能够根据现象判别原因,并具备解决问题的能力,从而切实提高学生的硬件电子电路的分析、判断能力。
软件编程是本次工程实践的重要环节。
在为期两周的工程实践中,将占据主要时间,学生要完成的软件编程任务主要包括以下几点:
1)、熟悉KeilC51编程平台及Proteus仿真;
2)、编写、调试蜂鸣器、继电器动作、方波程序并进行软硬件联调;
3)、编写、调试LED流水灯(循环显示)程序并进行软硬件联调;
4)、编写、调试键盘扫描子程序并进行软硬件联调;
5)、编写、调试数码管动态扫描程序并进行软硬件联调。
3、具体课题:
本题属于多功能任务设计,基于本实验室所提供的电路模板,具体题目为:
以智能速度里程表为主的多功能任务设计;
课题名字的多功能任务的含义是:
要求所设计的电路和程序必须实现4个功能,电路提供四个按键,要求同学们能编写、调试对应的键盘扫描子程序,从而实现,当按下A按键,实现蜂鸣器或继电器动作,当按下B按键,实现LED流水灯(循环显示),当按下C按键,实现数码管动态扫描显示(显示内容可以自己确定),前3个功能,对于每个课题都是相同,只有最后一个按键不同,其功能取决于所选课题名称,即当按下D按键,要求实现相应课题的最主要的功能,例如,对于“以智能温度计为主的多功能任务设计”的课题,当按下该课题所对应的D按键,就要实现显示温度的功能,其余类似。
4所做题目的意义
汽车是现代生活中不可或缺的一种重要交通工具,传统的指针式的里程表伴随着汽车的诞生就一直为人们接受,不过,新生事物不会因传统的存在而停止它前进的步伐,数码科技在今天已渗透到工业,农业,民用等产品的点点滴滴。
新概念的车速里程表最直观的变化就是用大屏幕的液晶取代指针式表盘,直接用数字显示时速,里程,以及其他一些诸如油耗、时钟、环境温度等参数。
直观的呈现给使用者。
由于单片机体积小,可以把它做到产品的内部,取代老式机械零件,缩小产品体积,增强功能,实现智能化。
因此广泛的被用在智能产品中。
Intel公司的MCS-51系列单片机在近年来广泛流行。
本文即介绍一种基于MCS-51单片机的里程表的设计与实现。
5本人所做工作以及系统的主要功能
本人主要负责对程序的编写及调试
本系统由信号采集处理模块、单片机STC89C52RC、数码管显示模块、系统软件组成。
其中信号采集处理模块以中断信号为主,将不同的转速信号转换成相应的脉冲信号,并送到单片机的T1引脚;对单片机进行设置,使内部的定时器/计数器timer0工作在定时状态,timer1工作在计数状态,利用内部定时器T0对脉冲输入引脚T1进行控制,这样就能精确地检测到设定时间内加到T1引脚的脉冲数,一个脉冲即代表着车子前进一个轮长,对脉冲数进行处理就可得到里程和速度的数据;将数据送到数码管模块进行显示。
三器件介绍
1、STC89C52RC
STC89C52RC是由宏晶公司推出的一种小型单片机,是电子工程师常用器件。
其主要特点为采用Flash存贮器技术,降低了制造成本,其软件、硬件与MCS-51完全兼容,且采用高密度非易失存储器制造技术制造,将多功能8位CPU和闪烁存储器组合在单个芯片中,可以很快被中国广大用户接受。
其程序的电可擦写特性,使得开发与试验比较容易,为很多嵌入式控制系统提供了一种灵活性高且价廉的方案。
STC89C52RC引脚功能
1电源:
①VCC-芯片电源,接+5V;
②VSS-接地端;
2.时钟:
XTAL1、XTAL2-晶体振荡电路反相输入端和输出端。
3.控制线:
控制线共有4根:
ALE/PROG:
地址锁存允许/片内EPROM编程脉冲
①ALE功能:
用来锁存P0口送出的低8位地址
②PROG功能:
片内有EPROM的芯片,在EPROM编程期间,此引脚输入编程脉冲。
PSEN:
外ROM读选通信号。
RST/VPD:
复位/备用电源。
①RST(Reset)功能:
复位信号输入端。
②VPD功能:
在Vcc掉电情况下,接备用电源。
EA/Vpp:
内外ROM选择/片内EPROM编程电源。
①EA功能:
内外ROM选择端。
②Vpp功能:
片内有EPROM的芯片,在EPROM编程期间,施加编程电源Vpp。
4.I/O口线:
P0、P1、P2、P3共四个八位口。
P0口是三态双向口,通称数据总线口,因为只有该口能直接用于对外部存储器的读/写操作。
P0口也用以输出外部存储器的低8位地图1址。
由于是分时输出,故应在外部加锁存器将此地址数据锁存,地址锁存,信号用ALE。
P1口是专门供用户使用的I/O口,是准双向口。
P2口是从系统扩展时作高8位地址线用。
不扩展外部存储器时,P2口也可以作为用户I/O口线使用,P2口也是准双向口。
P3口是双功能口,该口的每一位均可独立地定义为第一I/O功能或第二I/O功能。
作为第一功能使用时操作同P1口。
四、设计步骤
4.1硬件初步设计
STC89C52RC
图1硬件总框图
4.1.1按键控制扫描模块:
按键用于控制数码显示、LED显示、扬声器等模块的工作。
通过扫描按键是否按下,来设定上述各模块的工作情况,使各模块可以在按键的控制下,有序地进行工作。
4.1.2扬声器模块:
本设计是通过P3.7口控制扬声器发出连续,断续的声音。
当按键1按下时,则由P3.7口输出方波信号,使扬声器发出声音。
4.1.3LED显示模块:
根据流水灯的形式,建立流水灯显示程序。
本设计中通过P2口控制流水灯的显示,8个LED共阳极,故P2口低电平有效。
4.1.4数码显示模块:
根据实际确定字形码表,建立显示子程序。
本设计中采用四位共阳极数码管,通过单片机STC89C52RC的P1口控制其位选,以达到动态显示的效果,再通过P0口控制其段选以显示相应的数值。
数码管有共阳和共阴之分,可用静态显示,也可用动态显示。
静态显示,原理简单,容易编程,但电路复杂占用的资源较多。
动态显示电路,控制较难,但电路简单,在资源紧张时是首选。
这里用的是动态显示。
数码管动态显示接口是单片机中应用最为广泛的一种显示方式之一,动态驱动是将所有数码管的8个显示笔划"a,b,c,d,e,f,g,dp"的同名端连在一起。
字型
共阳极段码
字型
共阳极段码
0
C0H
5
92H
1
F9H
6
82H
2
A4H
7
F8H
3
B0H
8
80H
4
99H
9
90H
表1数码管动态显示接口地址
4.2硬件原理电路图
图2硬件原理电路图
本设计中所用的单片机型号为AT89C52RC,其主要特性为:
1)有CHMOS工艺的节能运行方式
2)兼容MCS51指令系统
3)3个16位可编程定时/计数器中断
4)2个串行中断
5)2个外部中断源
6)2个读写中断口线
7)低功耗空闲和掉电模式
8)8k可反复擦写(>1000次)FlashROM
9)256x8bit内部RAM
10)时钟频率0-24MHz
11)可编程UART串行通道
12)共6个中断源,3级加密位
13)软件设置睡眠和唤醒功能
4.3单元电路设计
3.3.1按键电路
图3按键电路
由于本系统中按键数量较少,且单片机的I/O口相对富余,使用独立式键盘。
同样,由于单片机高电平输出能力比低电平输出能力弱,使用如图所示的按键电路。
读按键前,先将端口设置为高电平。
此时,单片机内部由一个MOS管作为上拉电阻,在按键没被按下时,单片机端口人保持高电平;当按键被按下后,单片机I/O口被强行接地,变为低电平。
按键电路中由于单片机内部MOS管有微弱的上拉作用,所以外部硬件可以不接上拉电阻。
3.3.2流水灯电路
流水灯由单片机的P1口控制。
考虑到单片机I/O口高电平驱动能力弱而低电平驱动能力强的特点以及系统功耗大小,采用如图所示的电路。
现由P1口低电平驱动发光二极管发光。
图4流水灯显示电路
图中D1-D8为发光二极管,R13-R20为限流电阻。
发光二极管在电流范围
内都能正常发光。
则限流电阻
,一般发光二极管
取
,假设单片机低电平输出能力足够强,即
,则
。
按实际器材条件,选择限流电阻为
。
3.3.3蜂鸣器电路
SPEAK(P3.7)信号控制器件开通关断,使得蜂鸣器发声或不发声。
图5蜂鸣器电路
3.3.4数码显示电路
显示电路是系统人机接口的重要组成部分。
该系统中采用动态显示的方法来驱动四位数码管显示。
数码管为共阳型,所以字形段码为阴码。
显示驱动电路如图所示。
Rf=330Ω
图6数码管显示电路
按照单片机输出端口与数码显示管的连接关系,对应着显示内容的形状,计算字形编码如下表所示。
显示
字形
A
(Px.7)
F
(Px.6)
B
(Px.5)
G
(Px.4)
C
(Px.3)
Dp
(Px.2)
D
(Px.1)
E
(Px.0)
阴码
0
L
L
L
H
L
H
L
L
0x14
1
H
H
L
H
L
H
H
H
0xD7
2
L
H
L
L
H
H
L
L
0x4C
3
L
H
L
L
L
H
L
H
0x45
4
H
L
L
L
L
H
H
H
0x87
5
L
L
H
L
L
H
L
H
0x25
6
L
L
H
L
L
H
L
L
0x24
7
L
H
L
H
L
H
H
H
0x57
8
L
L
L
L
L
H
L
L
0x04
9
L
L
L
L
L
H
L
H
0x05
°
L
L
L
L
H
H
H
H
0x0F
E
L
L
H
L
H
H
L
L
0x2C
r
H
H
H
L
H
H
H
L
0xEE
Null
H
H
H
H
H
H
H
H
0xFF
备注
L为低电平,对应显示段亮;H为高电平,对应显示段灭。
表2显示字形对应驱动阴码计算表
只要在段码输入端输入对应的阴码,再从DR1-DR4的位码信号中给出要显示内容的数码管的选择信号,便可在对应的数码管中按对应段码显示内容。
R13-R20为限流电阻。
三极管饱和开通时,集电极-发射极之间电压
,数码管的压降
,数码管的工作电流
。
则限流电阻可这样计算获得:
。
现取
。
五、软件初步设计
5.1主程序流程图
图7主程序流程图
5.2各模块流程图
图8扬声器程序
图9彩灯循环显示流程图
图10数码管动态显示流程图
图11里程表程序流程图
5.3各模块软件设计
5.3.1扬声器电路的设计
本次设计中,设计扬声器产生简单的“嘟嘟”声。
只需在P3.7口输出方波即可。
当KEY1按下后,单片机则会发出10个方波信号,频率约为1960HZ。
信号结束后,调用0.5秒延时,如此就会使扬声器发出“嘟嘟”声。
5.3.2彩灯循环显示的设计
设计中,由单片机的P2.0~P2.7控制8个发光管。
当KEY2按下后,每隔0.5秒就将对应发光管的P2.X口清零,使发光管一次点亮,如此往复。
5.3.3数码管动态显示的设计
设计中,由P1.0~P1.3口控制数码管的片选,由P0口控制数码管的段选。
当KEY3按下后,分别让4个数码管显示“1”,“2”,“3”,“4”,即当P1.0~P1.3分别为高电平时,将“F9H”、“A4H”、“B0H”、“99H”分别赋给P0口,显示的时间间隔是2毫秒。
对于人来说,已经无法分辨数码是否是轮流点亮的。
5.3.4智能速度里程表的设计
本次设计中,假设车轮周长为一米,再P3.2口加一个方波信号,模拟车轮滚动。
当产生一个下降沿(车轮滚动一圈),就产生一次外部中断。
30H~34H记录的是里程,分别对应米,十米,百米,千米,万米。
当产生一次外部中断,里程数就加一。
40H~43H记录的是单位时间内所走过的里程,即速度。
当产生一次外部中断,里程数加一。
当产生一秒的时间中断,就把40H~43H的内容赋给20H~23H锁存。
显示电路中,首先判断速度里程切换按钮是否按下,没按下则由数码管显示31H~34H的内容,即里程数。
若按下,则显示20H~23H的内容,即速度。
五、硬件系统参数选择
在本次设计中,各端口设置如下:
P0:
数码管段选位
P1:
低四位为数码管片选位
高四位为开关控制位
P2:
流水灯控制位
P3:
P3.2为外部中断0入口位
P3.3为速度里程切换显示开关位
P3.7为扬声器控制位
六、软件设计
在主程序中用到了五条汇编语言指令:
CLR、ACALL、SETB、LJMP、END。
CLR:
是将其后面指定的位清为0,程序中使对应端口输出低电平
CALL:
是子程序调用指令,程序中调用了DELAY延时子程序
SETB:
是将其后面指定的位置成1,程序中使对应端口输出高电平
JMP:
是跳转指令,意思是:
跳转到指定的标号处继续运行
END:
是程序结束的伪指令,意思是告诉编译器,程序到此结束。
伪指令只告诉编译器此程序到此有何要求或条件,它不参与和影响程序的执行。
详细完整的程序清单及注释
#include
#include
voidTimer1Init(void);
voiddelay_ms(unsignedcharx);
voidw1();
voidw2();
voidw3();
sbitWx=P2^7;//位选
sbitDx=P2^6;//段选
sbitkey4=P3^7;
sbitkey1=P3^4;
sbitkey2=P3^5;
sbitkey3=P3^6;
sbitfm=P2^3;
unsignedintcnt=0;//秒计数
unsignedcharaa,bb,numdu,numwe;
unsignedcharcodetablew[]={0x71,0x06,0x5b,0x4f,0x66,0x6d,0x7d};//F,211314
unsignedcharcodetablewe[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf};
unsignedcharcodetable[]={0x3f,0x06,0x5b,0x4f,//主功能数组定义
0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,
0x79,0x71};
/*--------------------------------------
按键控制蜂鸣器过程
----------------------------------------*/
voidw1()
{
if(!
key1)
{
delay_ms(300);//延时防抖,松手检测
if(key1)
{
fm=!
fm;
}
}
}
/*--------------------------------------
按键控制流水灯过程
----------------------------------------*/
voidw2()
{
loop1:
P1=0xff;
if(!
key2)
{
delay_ms(300);
if(key2)
{
aa=0xfe;//赋初值11111110
while
(1)//大循环
{
P1=aa;
delay_ms(100);//延时100毫秒
aa=_crol_(aa,1);//将aa循环左移1位后再赋给aa//相应的cror是循环右移一位
if(!
key2)
{
delay_ms(300);
if(key2)
gotoloop1;
}
}
}
}
}
/*--------------------------------------
按键控制数码管过程
----------------------------------------*/
voidw3()
{
loop2:
Wx=1;
P0=0xff;
if(!
key3)
{
delay_ms(300);
if(key3)
{
numdu=0;
numwe=0;
while
(1)
{
numdu++;
if(numdu==7)
numdu=1;
Dx=1;//开段锁存器
P0=tablew[numdu];//送段码
Dx=0;//锁存段码
Wx=1;//开位锁存器
P0=tablewe[numwe];//送位码
Wx=0;//锁存位码
numwe++;
if(numwe==6)
numwe=0;
delay_ms(500);
if(!
key3)
{
delay_ms(300);
if(key3)
gotoloop2;
}
}
}
}
}
/*==============================================
【函数名】:
delay_ms(unsignedx)
【参数】:
ms
【功能】:
毫秒级延时函数
================================================*/
voiddelay_ms(unsignedcharx)
{
unsignedcharj;
while(x--)
{
for(j=0;j<100;j++);
}
}
/*==============================================
【函数名】:
main()
【功能】:
主函数,从000~999显示,定时器实现
================================================*/
voidmain()
{
//unsignedcharled[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//P0口输出时,0~9
unsignedcharled[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
unsignedcharWeima[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf};//位选,从个位开始
//unsignedinti;
unsignedchartemp[3];//显示计数缓存
unsignedintKeyData=0;
//Timer1Init();
while
(1)
{
while(!
key1)w1();
while(!
key2)w2();
while(!
key3)w3();
if(!
key4)
{
delay_ms(300);
if(key4)
{
KeyData++;
if(KeyData==1000){KeyData=0;}
}
}
temp[0]=KeyData/100;//百位显示值
temp[1]=(KeyData%100)/10;//十位显示值
temp[2]=KeyData%10;//个位显示
Wx=1;
P0=Weima[3];
Wx=0;
Dx=1;
P0=led[temp[0]];
delay_ms
(1);
P0=0;//关显示,消隐
//delay_ms
(1);
Dx=0;