《基于单片机的自行车里程表、测速仪》单片机大作业09电子2班薛强学号:423目录摘要第一章系统设计1.1 设计任务和要求1.1.1设计任务1.1.2 基本要求1.2 总体设计方案1.2.1系统总体设计思路1.2.2方案设计与讨论1.3功能描述1.4操作说明1.5结构框图1.6原理说明第二章硬件设计2.1 硬件电路2.2 主要元件介绍第三章软件设计3.1 系统主程序流程图3.2 仿真截图3.3 源程序代码基于80C51单片机的自行车里程表、测速仪摘要:本文介绍了一种基于单片机控制的简易自动自行车速度以及里程计算系统,包括自行车里程表的硬件构成,软件逻辑以及程序代码。
该里程测速系统以AT89C51作为系统控制核心,采用光电传感器来检测信号,通过一定时间间隔内对信号的采集,结合自行车本身车轮参数,经过单片机对采集信号进行分析计算,最终在LCD以及LED上显示车辆行驶里程、平均速度和瞬时速度,并且具有超速报警功能。
关键词:自行车测速;单片机;光电传感器,LCD/LED显示一、系统设计1.1 设计任务和要求1.1.1设计任务设计一个自行车里程表、测速仪,可以将自行车一段时间内的行驶里程,瞬时速度,平均速度在LCD上显示出来,有一个能用LCD显示的腕式自行车里程显示器,传感器采用霍尔元器件,安装在自行车的车轮上;1.1.2 基本要求能实时显示当前的车速和行驶里程;能去除或保留原先的里程数;电池供电。
1.2 总体设计方案1.2.1系统总体设计思路本系统实现自行车运行过程中对行驶里程、当前瞬时速度、平均速度进行测量和显示。
总体设计思路如图1所示。
系统包括控制器模块、信号检测采集模块、显示模块、电源模块四部分。
号输入)传输给单片机,单片机计数器统计脉冲个数,定时器记录相应时间长度,经过运算,将行驶里程、平均速度送给LCD显示,当前(瞬时)速度送给7段数码管显示。
1.2.2方案设计与讨论速度测量原理测量自行车的速度的原理有两种:测量一定时间间隔t里自行车车轮转过的圈数q。
假设车轮周长为c,则速度V=c*q/t测量自行车车轮转过一圈的时间t,则速度V=c/t本里程表是根据第一个原理计算速度的。
传感器的选择红外光电传感器。
把红外对管分别安装在自行车车轮的两侧,当车轮转动时,辐条会阻挡红外对管的光路,接收管输出低电平,单片机根据此信号可计算里程、速度等。
红外对管的优点是测量精度高,缺点是安装比较复杂和容易受外来光线、灰尘等的影响。
开关型霍尔传感器。
霍尔传感器是利用霍尔效应把磁输入信号转换成电信号的器件。
把开关型霍尔传感器安装在自行车贴近车轮的支架上,磁钢安装在辐条上,当磁钢靠近霍尔传感器的时候,传感器输出一个无抖动的低电平,单片机根据此信号可计算里程、速度等。
霍尔传感器的优点是稳定和安装简易,缺点是成本较高。
干簧管。
干簧管是一种磁敏的有触点无源电子开关元件,应用在里程表上的原理与开关型霍尔传感器类似,把干簧管安装在自行车贴近车轮的支架上,磁钢安装在辐条上,当磁钢靠近霍尔传感器的时候,干簧管闭合,单片机根据此信号可计算里程、速度等。
干簧管的优点是成本低廉和安装简易,缺点是比较脆弱和不够稳定。
本里程表选用开关型霍尔传感器,稳定、安装简易。
显示模块的选择动态扫描LED数码管显示。
里程表的显示内容以数字为主,利用LED数码管可基本满足使用要求,且成本较低。
但是用动态扫描的方式驱动数码管,亮度太低,在阳光下几乎看不见显示内容,失去使用价值。
串行静态LED数码管显示。
把单片机的串行口设置为方式0(同步移位寄存器),输出显示信息,可实现LED数码管的静态显示,其亮度令人满意。
但由于要使用74HC164/74LS164串并转换芯片驱动LED数码管,因此会带来体积大、成本高、功耗高等的缺点。
LCD液晶显示模块。
液晶显示模块具有体积小、功耗低、显示内容丰富等特点,现在字符型液晶显示模块已经是单片机应用设计中最常用的信息显示器件了。
本里程表使用1602 LCD作为显示模块。
外加四个七段管LED用来显示5秒内的当前速度(近似瞬时速度)【功能描述】以AT89C51型单片机为核心,实时测量并显示自行车行驶过程中的各项参数,包括当前行驶累计时间、当前行驶累计里程(m)、当前速度(m/s)、平均速度(m/s)、当前行驶时间等,各参数分屏显示。
本里程表具有时钟功能,不安装在自行车上时也可作为时钟使用,实用性高。
【操作说明】本例子所采用的是27#比赛公路自行车,换算成公制,外径700mm,半径为350mm,探测器安装在距离轴心200mm处,探测到一次,车轮转动2.15m,轮胎具体规格700*28C,28是指车胎的横断面的宽度为28mm,则周长2150mm。
【结构框图】系统由霍尔元件传感器、显示模块、LED报警模块、供电模块和单片机小系统构。
【工作原理】里程、速度等都是由霍尔元器件测量。
通过频率计或者按钮输出脉冲,代表车轮转动圈数,已知自行车轮胎的周长为2.15m,轮子每转动一圈,安装在车轮辐条上的磁钢接近霍尔传感器一次,传感器送一个脉冲信号给单片机的外部中断计数器T1,产生一次中断,圈数加一。
圈数*2.15即为车前进距离,而通过单片机T0定时器记录时间,间隔5秒,5秒内的前进距离除以时间5秒,得到5秒内的当前速度。
而总里程L除以总时间t得到平均速度。
处理速度数据时同时刷新平均速度、当前速度、运行里程。
若速度大于25km/h(6.95m/s)则P3.7输出低电平,LED警示灯亮,提示速度过大。
单片机定时器0定时时间为50ms,每20次刷新系统时钟及计算累计行驶时间。
【具体电路图】【相关元器件及其简介】(1)AT89C51单片机简介AT89C51是一种低功耗、高性能CMOS 8位微控制器,具有2K 在系统可编程Flash 存储器。
使用Atmel 公司高密度非易失性存储器技术制造,与工业80C51 产品指令和引脚完全兼容。
片上Flash允许程序存储器在系统可编程,亦适于常规编程器。
在单芯片上,拥有灵巧的8 位CPU 和在系统可编程Flash,使得AT89C51为众多嵌入式控制应用系统提供高灵活、超有效的解决方案。
AT89C51具有以下标准功能:4k字节Flash,128字节RAM,32 位I/O 口线,看门狗定时器,2 个数据指针,2个16 位定时器/计数器,一个6向量2级中断结构,全双工串行口,片内晶振及时钟电路。
另外,AT89C51 可降至0Hz 静态逻辑操作,支持2种软件可选择节电模式。
空闲模式下,CPU停止工作,允许RAM、定时器/计数器、串口、中断继续工作。
掉电保护方式下,RAM 内容被保存,振荡器被冻结,单片机一切工作停止,直到下一个中断或硬件复位为止。
(2)1602LCD液晶显示模块液晶显示模块具有体积小、功耗低、显示内容丰富等特点,现在字符型液晶显示模块已经是单片机应用设计中最常用的信息显示器件了。
本里程表使用常见的1602字符型LCD模块。
1602可以显示2行16个字符,有8位数据总线D0-D7,和RS、R/W、E三个控制端口,工作电压为5V,并且带有字符对比度调节和背光。
(3)霍尔元件霍尔传感器是利用霍尔效应把磁输入信号转换成电信号的器件。
把开关型霍尔传感器安装在自行车贴近车轮的支架上,磁钢安装在辐条上,当磁钢靠近霍尔传感器的时候,传感器输出一个无抖动的低电平,单片机根据此信号可计算里程、速度等。
霍尔传感器的优点是稳定和安装简易,缺点是成本较高。
附录程序流程图及程序代码主程序流程图:中断服务子程序流程图:仿真截图:用频率计输入频率为5HZ的信号,得到速度10.75m/s手动按钮,得到当前速度7.74m/s全部运行结果(含超速报警)全部运行结果(未超速,报警灯未亮)程序代码:#include<reg52.h>#include<intrins.h> //包含_nop_();函数定义的头文件void timer0_int();sbit LED=P3^7;sbit E=P3^2; //1602使能引脚sbit RW=P3^1; //1602读写引脚sbit RS=P3^0; //1602数据/命令选择引脚unsigned char hour,minute,second;unsigned char n,count;unsigned long lengthbuf,lengthvalue;unsigned char code Table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//0~9的共阴极七段管代码unsigned char code Table1[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};//0~9的共阴极七段管代码,带小数点void Delay0(int Times);void Display();void delay() //延时5US{_nop_();_nop_();_nop_();_nop_();_nop_();}bit Busy(void) //读状态函数,判断液晶模块的忙碌状态{bit busy_flag = 0;RS = 0;RW = 1;E = 1;delay();busy_flag = (bit)(P0 & 0x80);E = 0;return busy_flag;}void wcmd(unsigned char del) //将模式设置指令或显示地址写入液晶模块{while(Busy());RS = 0;RW = 0;E = 0;delay();P0 = del;delay();E = 1;delay();E = 0;}void wdata(unsigned char del) ///将数据(字符ASCII码)写入液晶模块{while(Busy());RS = 1;RW = 0;E = 0;delay();P0 = del;delay();E = 1;delay();E = 0;}void L1602_init(void) //初始化液晶模块{wcmd(0x38); //功能设置,8位字长,2行,5*7点阵wcmd(0x0c); //显示设置,显示屏右移wcmd(0x06); //显示设置,光标右移,字符不移wcmd(0x01); //清屏命令}void L1602_string(unsigned char hang,unsigned char lie,unsigned char p) //将数据写入液晶模块{unsigned char a;if(hang == 1) a = 0x80; //显示在第一行if(hang == 2) a = 0xc0; //显示在第一行a = a + lie -1;wcmd(a);wdata(p);}void timer0_int() interrupt 1 using 3 //中断,用于构成时钟{n++;if(n==100){n=0;count++;second++;if(second>=60){second=0;minute++;if(minute>=60){minute=0;hour++;if(hour>=24) hour=0;}}}if(count==5){count=0;lengthvalue=(TL1+TH1*256)*215-lengthbuf;lengthbuf=(TL1+TH1*256)*215;}TH0=0xd8;TL0=0xf0;}int timer() //以秒为单位计算运行总时间{unsigned char a=100;unsigned char b;b=second+minute*60+hour*60*60;return b;}void Delay0(int Time) //延时子程序{int i;unsigned char j;for(i=0;i<Time;i++){for(j=0;j<150;j++){}}}void Display(unsigned int x) //在LED七段管中显示最高速度{unsigned char slc;unsigned char a,b,c,d;slc=0xef; //LED七段管选通a= x/1000;b=( x-a*1000)/100;c=( x-a*1000-b*100)/10;d= x%10;{P2=slc; //分别将最大速度的各个位扫描显示slc=slc<<1;P1=Table[a];Delay0(10);P2=slc;slc=slc<<1;P1=Table1[b];Delay0(10);P2=slc;slc=slc<<1;P1=Table[c];Delay0(10);P2=slc;slc=slc<<1;P1=Table[d];Delay0(10);}return;}void main(){unsigned char i=0 ;unsigned int v=0; //运行速度unsigned int vnow; //当前速度unsigned int a,b,c,d; //分别显示速度的十位,个位,十分位,百分位unsigned long quanshu; //定义车轮转动圈数unsigned long length,length1,length2,length3,length4,length5,length6; //定义运行长度以及长度的各个进位,unsigned int second1,second2,minute1,minute2,hour1,hour2;L1602_init();TMOD=0x51; //定时器T0,计数器T1,允许外部中断,T1工作方式01,T0工作方式01TH1=0x00; //计数器T1高位装初值TL1=0x00; //计数器T1低位装初值ET1=1; //计数器0开中断TR1=1; //计数器0开始工作TH0=0XD8; //T0设置时间常数TL0=0XF0;ET0=1;EA=1;TR0=1;IT1=1; //外部中断1请求触发方式EX1=1;P1=0X00; //P1、P2口装初值,用于LED七段管显示用P2=0xff;while(1){quanshu=TL1+TH1*256; //计算车轮旋转圈数length=quanshu*215; //骑行距离//计算里程各个进位length1=length/100000;length2=(length-length1*100000)/10000;length3=(length-length1*100000-length2*10000)/1000;length4=(length-length1*100000-length2*10000-length3*1000)/100;length5=(length-length1*100000-length2*10000-length3*1000-length4 *100)/10;length6=length%10;if(timer()>0)v=length/timer(); //计算速度vnow=lengthvalue/5; //计算当前速度(5秒内)if(vnow>=695) LED=0;else LED=1; //速度超过 6.95m/s(即25km/h),则报警灯亮Display(vnow); //在LED七段管上显示当前速度(5秒内)速度Delay0(20);a=(v/1000); //计算速度的各个进位b=(v-a*1000)/100;c=(v-a*1000-b*100)/10;d=v%10;second1=second/10; //计算分秒时的十位与个位second2=second%10;minute1=minute/10;minute2=minute%10;hour1=hour/10;hour2=hour%10;L1602_string(1,1,'s'); //在LCD相应位置显示变量或者常量L1602_string(1,2,'p');L1602_string(1,3,'e');L1602_string(1,4,'e');L1602_string(1,5,'d');L1602_string(1,6,' ');L1602_string(1,7,'L');L1602_string(1,8,'=');L1602_string(1,9,length1+48);L1602_string(1,10,length2+48);L1602_string(1,11,length3+48);L1602_string(1,12,length4+48);L1602_string(1,13,'.');L1602_string(1,14,length5+48);L1602_string(1,15,length6+48);L1602_string(1,16,'m');L1602_string(2,1,a+48);L1602_string(2,2,b+48);L1602_string(2,3,'.');L1602_string(2,4,c+48);L1602_string(2,5,d+48);L1602_string(2,6,'m');L1602_string(2,7,'/');L1602_string(2,8,'s');L1602_string(2,9,hour1+48);L1602_string(2,10,hour2+48);L1602_string(2,11,':');L1602_string(2,12,minute1+48);L1602_string(2,13,minute2+48);L1602_string(2,14,':');L1602_string(2,15,second1+48);L1602_string(2,16,second2+48);while(i<2) //LCD显示延迟{delay();i++; }i=0;}}。