当前位置:文档之家› 基于单片机的电动车里程记录仪的设计

基于单片机的电动车里程记录仪的设计

目录第 1 章绪论....................................................................... 错误!未定义书签。

1.1课题背景........................................................................... 错误!未定义书签。

1.2设计的整体思路 (2)第 2 章硬件的设计 (4)2.1 AT89C52系列单片机的介绍 (4)2.2存储电路 (5)2.3时钟电路 (6)2.4复位电路 (7)2.5显示电路 (8)2.6报警电路 (9)第 3 章软件的设计与调试 (9)3.1子程序与主函数的设计 (9)3.2 Protues仿真过程........................................................... 错误!未定义书签。

参考文献. (14)附录一硬件设计原理图 (15)附录二程序清单 (16)第 1 章绪论单片机现在渗透到我们生活的各个领域,几乎很难找到哪个领域没有单片机的踪迹。

导弹的导航装置,飞机上各种仪表的控制,计算机的网络通讯与数据传输,工业自动化过程的实时控制和数据处理,广泛使用的各种智能IC卡,民用豪华轿车的安全保障系统,录像机、摄像机、全自动洗衣机的控制,以及程控玩具、电子宠物等等,这些都离不开单片机。

更不用说自动控制领域的机器人、智能仪表、医疗器械以及各种智能机械了。

1.1课题背景本题目根据车速、里程的测量原理,以MCS-51系列单片机为核心器件,组成点阵式的液晶显示屏,通过编程显示车速、里程。

按照设计要求熟悉系统硬件电路、接口电路,完成硬件电路的电路板的设计,完成该系统的程序设计,提交程序设计框图及程序设计清单。

1.2设计的整体思路设计包括硬件设计和软件设计,其中硬件是基础软件是核心,软件的数据通过硬件进行处理和控制,最终实现用户的功能。

一、硬件介绍本设计的硬件包括:AT89C52芯片:程序的处理和控制中心。

数字码盘:模拟霍尔传感器,向芯片外部中断提供脉冲。

RESPACK8八位排阻:将P0口拉成高电平。

1602液晶显示屏:显示速度和路程数据。

24C02C:存储总里程数据二、主要技术指标1、计算速度和路程。

2、存贮历史里程数据。

3、量程记满时清除历史里程数据。

4、显示及时速度。

5、超速报警三、设计原理框图如下:1.2软件设计流程图第 2 章硬件电路的设计2.1 AT89C52系列单片机的介绍AT89C52是美国ATMEL公司生产的低电压,高性能CMOS 8位单片机,片内含8K bytes 的可反复擦写的只读程序存储器(PEROM)和256 bytes 的随机存取数据存储器(RAM),器件采用ATMEL公司的高密度,非易失性存储技术生产,与标准MCS-51指令系统及8052产品引脚兼容,片内置通用8位中央处理器(CPU)和Flash存储单元,功能强大AT89C52单片机适合于许多较为复杂控制应用场合。

功能特性概述:AT89C52提供以下标准功能:8K 字节Flash闪速存储器,256字节内部RAM,32个I/O口线,3个16位定时/计数器,一个6向量两级中断结构,一个全双工串行通信口,片内振荡器及时钟电路。

同时,AT89C52可降至0Hz的静态逻辑操作,并支持两种软件可选的节电工作模式。

空闲方式停止CPU的工作,但允许RAM,定时/计数器,串行通信口及中断系统继续工作。

掉电方式保存RAM中的内容,但振荡器停止工作并禁止其它所有部件工作直到下一个硬件复位。

引脚如图2.1所示。

振荡器反相放大器如图2.2所示。

图2.1 AT89C52引脚图XTAL1:振荡器反相放大器的及内部时钟发生器的输入端。

XTAL2:振荡器反相放大器的输出端。

中断:AT89C52共有6个中断向量:两个外中断(INT0和INT1),3个定时器中断(定时器0,1,2)和串行口中断。

所有这些中断源可通过分别设置专用寄存器IE的置位或清0来控制每一个中断的允许或禁止。

IE也有一个总禁止位EA,它能控制所有中断的允许或禁止。

2.2存储电路SCK串行时钟:AT24C02串行时钟输入管脚用于产生器件所有数据发送或接收的时钟。

SDA 串行数据/地址:CAT24WC02双向串行数据/地址管脚用于器件所有数据的发送或接收,是一个开漏输出管脚可与其它开漏输出或集电极开路输出进行线或(wire-OR )。

WP 写保护:如果WP 管脚连接到Vcc 所有的内容都被写保护,只能读。

当WP 管脚连接到Vss 或悬空,允许器件进行正常的读/写操作。

本次设计采用的24C02是为了防止掉电时里程数据的丢失,由于24C02C 的数据线和地址线是复用的,采用串口的方式传输数据,所以只用两根线SCK 和SDA 与单片机传输数据。

在软件编程时采用2E PROM 程序包来控制24C02C 发送或接受数据。

2.3 时钟电路时钟是单片机的心脏,单片机各功能部件的运行都是以时钟频率为基准,有条不紊地一拍一拍地工作。

因此,时钟频率直接影响单片机的速度,时钟电路的质量也直接影响单片机系统的稳定性。

AT89C52片内由一个反相放大器构成振荡器,可以由它产生时钟。

常用的时钟电路有两种方式,一种是内部时钟方式,另一种为外部时钟方式。

本设计采用前者。

单片机内部有一个用于构成振荡器的高增益反相放大器,该高增益反相放大器的输入为芯片引脚XTAL1,输出端为引脚XTAL2。

这两个引脚跨接石英晶体振荡器和电容,就构成一个稳定的自激振荡器。

电路中的电容C1和C2常选择为30P 左右。

对外接电容的值虽然没有严格的要求,但电容的大小会影响振荡器的高低、振荡器的稳定性、起振的快速性和温度的稳定性。

而外接晶体的振荡频率的大小,主要取决于单片机的工作频率范围,每一种单片机都有自己的最大工作频率,外接的晶体振荡频率不大于单片机的最大工作频率即可。

此外,如果单片机有串行通信,则应该选择振荡频率除以串行通信频率可以除尽的晶体。

本设计晶振采用12MHz ,则计数周期为6111210112T Hz ==⨯⨯μ()S 2.4 复位电路AT89C52单片机的复位输入引脚RET 为AT89C52提供了初始化的手段。

有了它可以使程序从指定处开始执行,即从程序存储器中的0000H 地址单元开始执行程序。

在89C52的时钟电路工作后,只要在RET引脚上出现两个机器周期以上的高电平时,单片机内部则初始复位。

只要RET保持高电平,则89C52循环复位。

只有当RET由高电平变成低电平以后,89C52才从0000H地址开始执行程序。

本系统的复位电路是采用按键复位的电路,如图2.12所示,是常用复位电路之一。

单片机复位通过按动按钮产生高电平复位称手动复位。

上电时,刚接通电源,电容C相当于瞬间短路,+5V立即加到RET/VPD端,该高电平使89C52全机自动复位,这就是上电复位;若运行过程中需要程序从头执行,只需按动按钮即可。

按下按钮,则直接把+5V加到了RET/VPD端从而复位称为手动复位。

复位后,P0到P3并行I/O口全为高电平,其它寄存器全部清零,只有SBUF寄存器状态不确定。

工作原理:通电瞬间,RC电路充电,RST引脚出现高电平,只要RST端保持10ms以上高电平,就能使单片机有效地复位。

2.5显示电路1602液晶显示模块可以和单片机AT89C51直接接口,1602的驱动程序11条指令,(1)void Clear_display(); //清显示屏指令(2)void Return_home(); //光标归位指令(3)void Entry_mode_set(); //输入模式设置指令(4)void Display_on_or_off(); //显示屏的开关控制指令(5)void Cursor_or_Display_shift(); //设定显示屏或光标移动方向指令(6)void Function_set(); //功能设定指令(7)void Set_character_address(); //设定CGRAM地址指令(8)void Set_display_address(); //设定DDRAM地址指令(9)void Read_busy_flag(); //读取忙信号或AC地址指令(10)void Write_data(); //将数据写入DDRAM或CGRAM指令(11)void Read_data(); //从CGRAM或DDRAM读出数据的指令2.6报警电路当速度超过30时,蜂鸣器报警,速度可以设定第 3 章软件的设计与调试3.1子程序和主函数的设计一、子程序的设计设汽车轮子半径为r,脉冲数为n,t=50毫秒,一个脉冲的时间为time,速度为v(km/h),路程为s(km),pi=3.14。

子程序按模块化的思路编写。

各子程序如下:1.初始化:设置 T0计时器工作方式1,输入口为p3.2 开总中断。

打开外中断0中断控制位.设置外部中断0优先级控制位。

设置外部中断0触发方式为边沿触发方式。

打开T0中断允许。

2.外部中断:当P3.2口有脉冲时进入外部中断0。

time=sec+t*0.05,记一个脉冲的时间。

tab_v[5]=0.9*pi*r/time,计算速度并放入数组中。

高低速的判断,当V>=5时为高速,并用flag = 0,记高速标志位,flag=1,记低速标志位;for(i = 0;i<6;i++)tab_v[i] = tab_v[i+1]; //数组移数据关闭T0,给T0赋50毫秒初值。

开启T0 ,当来一个脉冲n++;当n == 50000时,n清零n = 0;3.定时器0中断:当来一个脉冲进入定时器0中断,给T0定时器赋50毫秒初值,当记满50毫秒t++。

4.处理函数:计算速度分高速和低速。

速度计算公式:tab_v[5]=0.9*pi*r/time;(单位km/h)低速时:v=tab_v[5],即显示第五个速度值。

高速时:v+=tab_v[i];计算五个速度之和。

v=v/5;求得平均速度。

路程公式:s=0.00025*pi*r*n,随着脉冲n的增加s不断累加。

3.2PROTEUS仿真过程一、电路原理图如下图:图3.1车速里程表原理图二、生成HEX文件如下图4.2。

图3.2生成文件三、编译结果如下图4.3。

图3.3编译结果仿真结果没有错误和警告,编译通过。

四、仿真结果如下图仿真结果一表示:速度为0,路程也为0。

仿真结果二表示:速度为16km/h,行驶里程为4公里。

图3.4仿真结果一图3.5仿真结果二参考文献[1] 万福君,潘松峰,刘芳,吴贺荣,王秀梅.MCS-51单片机原理、系统应用[M].清华大学出版社,2008.[2] 张迎新.单片机原理及应用(第二版)[M].电子工业出版社,2009.[3] 宋文绪,杨帆.自动检测技术(第三版)[M].高等教育出版社,2008.[4] 郭天祥.新概念51单片机C语言教程[M].电子工业出版社,2009.[5] 陈忠平,曹巧媛曹琳琳,刘琼,申晓龙.单片机原理及接口[M].清华大学出版社,2007.附录一硬件设计原理图附录二程序清单//速度超过30KM/H报警#include<reg52.h>#include<stdio.h>#include<intrins.h>#define uint unsigned int#define uchar unsigned charuint zd;uchar b,i,count,temp2;unsigned long time;uint speed,c,allc; //速度里程总里程#define L 50sbit beep=P3^7;//speak 端口//-----------24c02----------------------#define C02_write 0xa0 //写#define C02_read 0xa1 //读sbit SCL=P1^4; //时钟sbit SDA_EEPROM=P1^5; //数据bit ack;bit dd;uchar New[2]=""; //使用者密码uchar Old[2]=""; //IIC密码//------------24c02---------------------sbit S1 = P3^0;//Pin4/***********************************************************************/ void delay1(uchar MS);unsigned char ReadTemperature(void);void Init_DS18B20(void);unsigned char ReadOneChar(void);void WriteOneChar(unsigned char dat);/************************************************************************/sbit RS = P2^4;//Pin4sbit RW = P2^5; //Pin5sbit E = P2^6;//Pin6sbit out = P1^0;//Pin6#define Data P0 //数据端口char data TimeNum[]=" ";char data Test1[]=" ";void Delay(uint z){uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}/******************************************************************//* 函数声明*//******************************************************************//*********** ****************************************************/void DelayUs(unsigned char us)//delay us{unsigned char uscnt;uscnt=us>>1;/* Crystal frequency in 12MHz*/while(--uscnt);}/******************************************************************/void DelayMs(unsigned char ms)//delay Ms{while(--ms){DelayUs(250);DelayUs(250);DelayUs(250);DelayUs(250);}}void WriteCommand(unsigned char c){DelayMs(5);//short delay before operationE=0;RS=0;RW=0;_nop_();E=1;Data=c;E=0;}/****************************************************************/ void WriteData(unsigned char c){DelayMs(5); //short delay before operationE=0;RS=1;RW=0;_nop_();E=1;Data=c;E=0;RS=0;}/*********************************************************************/ void ShowChar(unsigned char pos,unsigned char c){unsigned char p;if (pos>=0x10)p=pos+0xb0; //是第二行则命令代码高4位为0xcelsep=pos+0x80; //是第二行则命令代码高4位为0x8WriteCommand (p);//write commandWriteData (c); //write data}/*************************************************************************/ void ShowString (unsigned char line,char *ptr){unsigned char l,i;l=line<<4;for (i=0;i<16;i++)ShowChar (l++,*(ptr+i));//循环显示16个字符}/*********************************************************************/ void InitLcd(){DelayMs(15);WriteCommand(0x38); //display modeWriteCommand(0x38); //display modeWriteCommand(0x38); //display modeWriteCommand(0x06); //显示光标移动位置WriteCommand(0x0c); //显示开及光标设置WriteCommand(0x01); //显示清屏}////////////////////2402/////////////////////////////////////--------------------------------------------------------- void delay_ms(uchar i){uchar j;for(;i>0;i--)for(j=124;j>0;j--);}void I2C_start(void){SDA_EEPROM=1;SCL=1;_nop_();_nop_();_nop_();_nop_();_nop_();SDA_EEPROM=0;_nop_();_nop_();_nop_();_nop_();_nop_();SCL=0;_nop_();_nop_();}void I2C_stop(void){SDA_EEPROM=0;_nop_();_nop_();_nop_();_nop_();_nop_();SDA_EEPROM=1;_nop_();_nop_();_nop_();_nop_();_nop_();SCL=0;_nop_();_nop_();}void I2C_ackownledge(void) {SDA_EEPROM=0;_nop_();_nop_();SCL=1;_nop_();_nop_();_nop_();_nop_();_nop_();SCL=0;_nop_();_nop_();}void I2C_no_ackownledge(void){SDA_EEPROM=1;_nop_();_nop_();SCL=1;_nop_();_nop_();_nop_();_nop_();_nop_();SCL=0;_nop_();_nop_();_nop_();}void I2C_sendB(uchar byte){uchar counter;for(counter=0;counter<8;counter++){if(byte&0x80) SDA_EEPROM=1;else SDA_EEPROM=0;_nop_();SCL=1;_nop_();_nop_();_nop_();_nop_();_nop_();SCL=0;_nop_();_nop_();byte<<=1;}_nop_();_nop_();SDA_EEPROM=1;_nop_();_nop_();_nop_();SCL=1;_nop_();_nop_();_nop_();if(SDA_EEPROM==0) ack=1;else ack=0;SCL=0;_nop_();_nop_();}uchar I2C_receiveB(void){uchar temp;uchar counter;temp=0;SDA_EEPROM=1;_nop_();_nop_();for(counter=0;counter<8;counter++){_nop_();_nop_();_nop_();_nop_();_nop_();SCL=1;_nop_();_nop_();if(SDA_EEPROM==1) t emp=(temp<<1)|0x01;else temp=temp<<1;_nop_();_nop_();SCL=0;_nop_();_nop_();_nop_();}_nop_();_nop_();return(temp);}/*bit I2C_write_byte(uchar byte,uchar address){I2C_sendB(address);if(ack=0){I2C_stop();return(0);}else I2C_sendB(byte); *///存UserPasswordbit I2C_send_string(uchar no,uchar address) {uchar counter;for(counter=0;counter<no;counter++){I2C_start();I2C_sendB(C02_write);if(ack==0) return(0);I2C_sendB(address+counter);if(ack==0) return(0);I2C_sendB(New[counter]);I2C_stop();delay_ms(20);}return(1);}//读EEPROMPasswordbit I2C_receive_string(uchar no,uchar address) {uchar counter;for(counter=0;counter<no;counter++){I2C_start();I2C_sendB(C02_write);if(ack==0) return(0);I2C_sendB(address+counter);if(ack==0) return(0);I2C_start();I2C_sendB(C02_read);if(ack==0) return(0);Old[counter]=I2C_receiveB();I2C_no_ackownledge();I2C_stop();}}//-----------------------------------------------------------////////////////////2402/////////////////////////////////////////////*中断开始*//*********延时K*1ms,12.000mhz**********/void int0_isr(void) interrupt 0 /*外部中断0,接P3.2口*/{unsigned int temp;zd++; //中断次数time=count; //中断次数TR0=0; //关定时器temp=TH0; //定时器高temp=((temp << 8) | TL0); //定时器值TH0=0x3c; //定时器0 15535 65535-15535 =50000 us TL0=0xaf; //定时器0 15535 65535-15535 =50000 us count=0; //0TR0=1; //启动定时器time=time*50000+temp; //中断次数*50000+temp 总的时间。

相关主题