自行车里程表设计论文附程序_第1页
自行车里程表设计论文附程序_第2页
自行车里程表设计论文附程序_第3页
自行车里程表设计论文附程序_第4页
自行车里程表设计论文附程序_第5页
已阅读5页,还剩16页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

.z自行车里程表设计论文【摘要】以AT89S52型单片机为核心,实时测量并显示自行车行驶过程中的各项参数。【关键词】单片机LCD干簧管累计里程速度【作品要求】设计一个可以适用自行车的轻便、省电、全天候野外使用的自行车里程表。〔1〕基计要求总里程〈999.99km;可以轮流显示或选择显示〔用十进制数〕:里程——当前行驶里程;速度——当前平均速度km/h;最大速度——本次行驶中的最大速度;时间——当前行驶累计时间,时、分、秒;电源不高于5V,体积小、构造可靠,便于安装及使用。〔2〕发挥局部可以显示最大加速度;用可编程器件实现;用单片机实现【方案设计与讨论】速度测量原理测量自行车的速度的原理有两种:测量一定时间间隔t1里自行车车轮转过的圈数qs。假设车轮周长为tc,则速度V=tc*qs/t1测量自行车车轮转过一圈的时间t2,则速度V=tc/t2本里程表是根据原理2计算速度的。传感器的选择红外对管。把红外对管分别安装在自行车车轮的两侧,当车轮转动时,辐条会阻挡红外对管的光路,接收管输出低电平,单片机根据此信号可计算里程、速度等。红外对管的优点是测量精度高,缺点是安装比拟复杂和容易受外来光线、灰尘等的影响。开关型霍尔传感器。霍尔传感器是利用霍尔效应把磁输入信号转换成电信号的器件。把开关型霍尔传感器安装在自行车贴近车轮的支架上,磁钢安装在辐条上,当磁钢靠近霍尔传感器的时候,传感器输出一个无抖动的低电平,单片机根据此信号可计算里程、速度等。霍尔传感器的优点是稳定和安装简易,缺点是本钱较高。干簧管。干簧管是一种磁敏的有触点无源电子开关元件,应用在里程表上的原理与开关型霍尔传感器类似,把干簧管安装在自行车贴近车轮的支架上,磁钢安装在辐条上,当磁钢靠近霍尔传感器的时候,干簧管闭合,单片机根据此信号可计算里程、速度等。干簧管的优点是本钱低廉和安装简易,缺点是比拟脆弱和不够稳定。本里程表选用干簧管作为传感器。给干簧管套上废弃笔杆,可克制其脆弱的缺点;软件防抖可克制其不够稳定的缺点。显示模块的选择动态扫描LED数码管显示。里程表的显示内容以数字为主,利用LED数码管可根本满足使用要求,且本钱较低。但是用动态扫描的方式驱动数码管,亮度太低,在阳光下几乎看不见显示内容,失去使用价值。串行静态LED数码管显示。把单片机的串行口设置为方式0〔同步移位存放器〕,输出显示信息,可实现LED数码管的静态显示,其亮度令人满意。但由于要使用74HC164/74LS164串并转换芯片驱动LED数码管,因此会带来体积大、本钱高、功耗高等的缺点。LCD液晶显示模块。液晶显示模块具有体积小、功耗低、显示内容丰富等特点,现在字符型液晶显示模块已经是单片机应用设计中最常用的信息显示器件了。本里程表使用1602LCD作为显示模块。【功能描述】以AT89S52型单片机为核心,实时测量并显示自行车行驶过程中的各项参数,包括当前行驶累计时间、当前行驶累计里程〔m/km自动调整〕、当前速度〔km/h〕、最大速度〔km/h〕、平均速度〔km/h〕、加速度〔m/s2〕、当前时间等,各参数分屏显示。可更改自行车轮胎直径,适应不同的自行车,通用性好。本里程表具有时钟功能,不安装在自行车上时也可作为时钟使用,实用性高。【操作说明】里程表板面如上图所示,包括电源2pin排针、干簧管3pin排针、液晶显示器、液晶背光开关、电源开关、电源LED指示灯、功能按钮SW1-SW5、Reset按钮。接通电源或按Reset后,显示欢送画面:DigitalBikeMeterWele….2秒后进入时钟设置画面:SetTime00:00:00按SW1-SW3调整时钟后,按SW4确认。接着进入自行车轮胎半径设置画面:SetBikeTireL=55cm默认设置为55cm,对应22英寸自行车轮胎半径。附:轮胎直径大小英寸与厘米对照表英寸1618202224262828.5厘米40cm45cm50cm55cm61cm66cm71cm72cm按SW1、SW2调整轮胎直径后,按SW4确认,里程表开场工作。各项参数分成四屏选择显示,按动SW5〔Disp〕按以下次序进展切换:SS000.0mTime00:00:00V00.00km/hVm000.00km/hVa00.00km/ha0.00m/s2TimeNow00:00:00S::当前行驶累计里程〔单位自动调整〕S<1000m,格式***.*m,S>1000m,格式***.**km〕Time:当前行驶累计时间V:当前速度〔km/h〕Vm:最大速度〔km/h〕Va:平均速度〔km/h〕a:加速度〔m/s2〕TimeNow当前时间【构造框图】LCD显示LCD显示蜂鸣器4*AA电池组开关功能选择干簧管89S52单片机系统由干簧管、设置选择模块、显示模块、蜂鸣器模块、供电模块和单片机小系统构成。由设置选择模块选择显示模式后,单片机实时采集、处理后显示。【具体硬件电路及工作原理】里程、速度、加速度等都是由干簧管测量。自行车轮胎的直径tl,轮子每转动一圈,安装在车轮辐条上的磁钢接近干簧管一次,干簧管闭合,送一个下降沿信号给单片机的外部中断0,产生一次中断,圈数qs加1。两个相邻的下降沿信号的时间由单片机定时器1计时〔设为ssj〕,则计算累计里程S和当前速度V的公式为:S=tl*3.14*qsV=tl*3.14/ssj假设速度大于28.8km/h〔8m/s〕则P2.4输出低电平,蜂鸣器报警,提示速度过大。处理速度数据时同时刷新最大速度及计算Vm、平均速度Va、加速度a。单片机定时器0定时时间为50ms,每20次刷新系统时钟及计算累计行驶时间。【相关元器件及其简介】〔1〕AT89S52单片机简介AT89S52是一种低功耗、高性能CMOS8位微控制器,具有8K

在系统可编程Flash

存储器。使用Atmel

公司高密度非易失性存储器技术制造,与工业80C51

产品指令和引脚完全兼容。片上Flash允许程序存储器在系统可编程,亦适于常规编程器。在单芯片上,拥有灵巧的8

位CPU

和在系统可编程Flash,使得AT89S52为众多嵌入式控制应用系统提供高灵活、超有效的解决方案。AT89S52具有以下标准功能:

8k字节Flash,256字节RAM,32

位I/O

口线,看门狗定时器,2

个数据指针,三个16

位定时器/计数器,一个6向量2级中断构造,全双工串行口,片内晶振及时钟电路。另外,AT89S52

可降至0Hz

静态逻辑操作,支持2种软件可选择节电模式。空闲模式下,CPU停顿工作,允许RAM、定时器/计数器、串口、中断继续工作。掉电保护方式下,RAM内容被保存,振荡器被冻结,单片机一切工作停顿,直到下一个中断或硬件复位为止。〔2〕1602LCD液晶显示模块液晶显示模块具有体积小、功耗低、显示内容丰富等特点,现在字符型液晶显示模块已经是单片机应用设计中最常用的信息显示器件了。本里程表使用常见的1602字符型LCD模块。1602可以显示2行16个字符,有8位数据总线D0-D7,和RS、R/W、E三个控制端口,工作电压为5V,并且带有字符比照度调节和背光。〔3〕干簧管干式舌簧管简称干簧管,是利用磁场信号来控制的一种线路开关元件。干式舌簧管以其构造固有的特点,目前已被广泛应用到各种自动化和微型化的自动控制零件及通讯检测设备中,作为灵敏而快速的开闭及转换电路的执行工件。在本里程表中,干簧管安装在自行车贴近辐条的支架上,磁钢安装在辐条上。当磁钢远离干簧管时,干簧管断开,单片机外部中断0〔P3.2〕保持高电平。当磁钢靠近干簧管时,干簧管闭合,送一个下降沿信号给单片机的外部中断0,产生一次中断。【系统调试过程简述】自行车里程表的原理比拟简单,我编好一个比拟简单但是核心的程序〔只计算里程和速度〕在KeilC上仿真,经过短暂的调试就成功了,这证明我关于里程表的最核心的想法是正确的,这给了我后面的制作和调试很大的信心。紧接着是在单片机上搭建硬件,重点是按键防抖动。我的模式选择按钮是接到单片机的外部中断的,一开场我按照普通按钮的防抖动的方法测试,没有成功。于是在中断效劳程序的开场关闭中断,末尾再开中断,还是不行。后来在中断效劳程序的末尾加了这样一句:IE1=0;其作用就是去除中断标志。因为即使单片机的外部中断是关闭的,但只要在中断效劳程序执行期间按键抖动,中断标志又会置1,假设没有去除中断标志,退出中断效劳程序后又会执行一次效劳程序,这样按一次按键就会执行两次中断效劳程序。我的里程表的最初版本是利用串行LED数码管显示作为显示模块的〔简介请参阅附录二〕。但制成后发现体积太大,而且功耗比拟高,不适合用于要求小巧、巩固、耐用的自行车里程表上。后来改用1602LCD,里程表体积大幅度减小,经测试,背光开启时电流为45mA左右,背光关闭时为25mA左右,2500mahAA×4的电池组供电最多可达100小时,可以满足使用要求。附录程序流程图及程序代码开场开场显示欢送信息检测按钮处理时钟设置刷新累计行驶时间及时钟初始化设置特殊存放器、置定时常数、开中断、清屏等等待中断检测按钮处理直径设置刷新里程、速度等改变屏幕显示内容INT0INT1T0程序代码*include<reg52.h>*define ucharunsignedchar/****************************************************************引脚定义:P20=SW1时钟设置时更改“时〞,直径设置时更改十位P21=SW2 时钟设置时更改“分〞的十位,直径设置时更改个位P22=SW3时钟设置时更改“分〞的个位P23=Enter确认更改设置P32=Disp正常工作时更改显示模式****************************************************************************/sbitP20=P2^0;sbitP21=P2^1;sbitP22=P2^2;sbitP23=P2^3;sbitP32=P3^2;sbitRS=P3^7;sbitRW=P3^6;sbitE=P3^5;sbitbusy=P1^7;/****************************************************************变量定义:i延时变量qsls圈数临时变量,用于判断里程显示选用m还是km作为单位qs圈数sj累计行驶时间,单位为秒totallc 累计里程pjsd平均速度ssji定时器T120ms中断次数,用于计算速度等sji 本次速度对应的20ms中断次数sjiold 上次速度对应的20ms中断次数aa 加速度sd2 当前速度m*sd用于更新最大速度m*sd2最大速度对应的20ms次数tc 轮胎周长*s 字符串显示子程序字符指针line 字符串显示子程序列数row 字符串显示子程序行数 写控制字dat 显示码字gw 累计里程、当前速度、累计时间、最大速度、平均速度、加速度的个位sw 累计里程、当前速度、累计时间、最大速度、平均速度、加速度的十位bw 累计里程、当前速度、累计时间、最大速度、平均速度、加速度的百位qw 累计里程、当前速度、累计时间、最大速度、平均速度、加速度的千位ww 累计里程、累计时间的万位sww 累计里程、累计时间的十万位ssj定时器T050ms中断次数,每20次sj加1cgw 当前时间〔时钟〕的个位csw 当前时间〔时钟〕的十位cbw 当前时间〔时钟〕的百位cqw 当前时间〔时钟〕的千位cww 当前时间〔时钟〕的万位csww 当前时间〔时钟〕的十万位cww2 当前时间〔时钟〕的辅助万位MODE 显示模式tr1 轮胎设置变量1〔十位〕tr2 轮胎设置变量2〔个位〕****************************************************************************/unsignedinti,qsls;unsignedlongqs,sj,totallc,pjsd,ssji,sji,sjiold,aa,sd2,m*sd,m*sd2,tc;uchar*s,line,row,,dat,gw,sw,bw,qw,ww,sww,ssj,cgw,csw,cbw,cqw,cww,csww,cww2,MODE,tr1,tr2;/***********************************voidwait()*****************************该函数的作用是对LCD进展检测,看LCD是否处于忙的状态.当bflag=1时表示忙,此时不可以向LCD进展读写操作.而当busy=0时,表示可以向它读写数据.****************************************************************************/voidwait(){P1=0*ff;RW=1;RS=0;do{E=0;E=1;}while(busy==1);}/**************************************voiddispone()*******************************该函数的作用是向LCD写入数据并显示出来.***********************************************************************************/voiddispone(dat){P1=dat;RW=0;RS=1;E=0;E=1;wait();}/**********************************voidwr()*******************************该函数的作用是向LCD写入控制字.******************************************************************************/voidwr(){P1=;RW=0;RS=0;E=0;E=1;wait();}/***************************************voidinit_LCD()*******************************该函数的作用是初始化LCD.*****************************************************************************************/voidinit_LCD(){wr(0*01);wr(0*06);wr(0*38);wr(0*0c);}/****************************************voiddispmore()********************************该函数的作用是向LCD写入一串数据,并把数据串显示出来.******************************************************************************************/voiddispmore(line,row,uchardat[],i)//格式为dispmore(第几行,第几列,开场要显示的字符地址,显示几个字符〕;{uchar;s=dat;if(line==1){=0*80+row-1;wr();while((i--)!=0&&<=0*8f) {dispone(*s);++; s++; }}else{=0*c0+row-1;wr();while((i--)!=0&&<=0*cf) {dispone(*s); ++; s++; }}}/****************************************voidttimep()********************************累计行驶时间数据处理及显示子程序******************************************************************************************/voidttimep(){sww=sj/36000;ww=sj%36000/3600;qw=sj%3600/600;bw=sj%600/60;sw=sj%60/10;gw=sj%10;wr(0*c1); dispone('T'); dispone('i'); dispone('m'); dispone('e');dispone('');dispone(''); dispone(sww+0*30);dispone(ww+0*30);dispone(':'); dispone(qw+0*30);dispone(bw+0*30);dispone(':'); dispone(sw+0*30);dispone(gw+0*30);}/****************************************voidtimer1()********************************T1中断效劳子程序,每20ms中断一次,ssji加1,根据公式S=tc*qs和V=tc/ssj计算累计里程和******************************************************************************************/voidtimer1()interrupt3 { ssji++;TH1=0*b1;TL1=0*df;}/****************************************voidlcp()********************************累计里程数据处理和显示子程序,假设<999m则单位为m,假设>999m则单位为km******************************************************************************************/ voidlcp() {qsls=100000/tc; if(qs>qsls){sww=qs*tc/10000000;ww=qs*tc%10000000/1000000;qw=qs*tc%1000000/100000;bw=qs*tc%10000000/10000;sw=qs*tc%10000/1000;wr(0*81);dispone('S');dispone('');dispone('');dispone('');dispone('');dispone(sww+0*30);dispone(ww+0*30);dispone(qw+0*30);dispone('.');dispone(bw+0*30);dispone(sw+0*30);dispone('');dispone('k');dispone('m');}else{qw=qs*tc%100000/10000;bw=qs*tc%10000/1000;sw=qs*tc%1000/100;gw=qs*tc%100/10;wr(0*81); dispone('S'); dispone('');dispone('');dispone('');dispone('');dispone('');dispone('');dispone(qw+0*30);dispone(bw+0*30);dispone(sw+0*30);dispone('.');dispone(gw+0*30);dispone('');dispone('m');}}/****************************************voidpjsdp()********************************平均速度数据处理及显示子程序******************************************************************************************/voidpjsdp() {pjsd=qs*tc*36/sj;qw=pjsd%100000/10000;bw=pjsd%10000/1000;sw=pjsd%1000/100;gw=pjsd%100/10;wr(0*82);dispone('V');dispone('a');dispone('');dispone('');dispone(qw+0*30);dispone(bw+0*30);dispone('.');dispone(sw+0*30);dispone(gw+0*30);dispone('');dispone('k');dispone('m');dispone('/');dispone('h');}/****************************************voidsdp()********************************当前速度数据处理及显示子程序******************************************************************************************/voidsdp() {if(sji!=0)sd2=tc*1800/sji;elsesd2=0;qw=sd2%100000/10000;bw=sd2%10000/1000;sw=sd2%1000/100;gw=sd2%100/10;wr(0*82);dispone('V');dispone('');dispone('');dispone('');dispone(qw+0*30);dispone(bw+0*30);dispone('.');dispone(sw+0*30);dispone(gw+0*30);dispone('');dispone('k');dispone('m');dispone('/');dispone('h');}/****************************************voidm*sdp()********************************最大速度数据处理及显示子程序******************************************************************************************/voidm*sdp() {if(m*sd!=0)m*sd2=tc*1800/m*sd;elsem*sd2=0;qw=m*sd2%100000/10000;bw=m*sd2%10000/1000;sw=m*sd2%1000/100;gw=m*sd2%100/10;wr(0*c2);dispone('V');dispone('m');dispone('');dispone('');dispone(qw+0*30);dispone(bw+0*30);dispone('.');dispone(sw+0*30);dispone(gw+0*30);dispone('');dispone('k');dispone('m');dispone('/');dispone('h');}/****************************************voidclkp()********************************当前时间〔时钟〕数据处理及显示子程序******************************************************************************************/voidclkp(){wr(0*c4);dispone(csww+0*30);dispone(cww+0*30);dispone(':');dispone(cqw+0*30);dispone(cbw+0*30);dispone(':');dispone(csw+0*30);dispone(cgw+0*30);}/****************************************voidapfz()********************************加速度数据处理及显示子程序辅助程序******************************************************************************************/voidapfz(){wr(0*c2);dispone('a');wr(0*c6);dispone(qw+0*30);dispone(bw+0*30);dispone('.');dispone(sw+0*30);dispone(gw+0*30);dispone('');dispone('m');dispone('/');dispone('s');dispone('2');}/****************************************voidap()********************************加速度数据处理及显示子程序******************************************************************************************/voidap(){if(sjiold==sji){gw=sw=bw=qw=0;apfz();}elseif(sjiold<sji){aa=360*tc*(sji-sjiold)/sji/sjiold/(sji+sjiold); qw=aa/1000; bw=aa%1000/100; sw=aa%100/10; gw=aa%10; wr(0*c5); dispone('-'); apfz();}elseif(sjiold>sji){aa=360*tc*(sjiold-sji)/sji/sjiold/(sji+sjiold); qw=aa/1000; bw=aa%1000/100; sw=aa%100/10; gw=aa%10; wr(0*c5); dispone(''); apfz();}}/****************************************voidint0()********************************外部中断0〔干簧管〕中断效劳程序*****************************************************************************************/voidint0()interrupt0 {E*0=0; qs++; //圈数+1TR1=0;sjiold=sji; //停顿T1计时sji=ssji;if(m*sd!=0) //更新最大速度{if(sji<m*sd)m*sd=sji; }elsem*sd=sji; TH1=0*b1; //重置T1定时常数TL1=0*df;ssji=0;TR1=1; //T1重新开场计时switch(MODE){case0:wr(0*01);lcp();ttimep();break;case1:wr(0*01);sdp();m*sdp();break;case2:wr(0*01);pjsdp();ap();break;case3:wr(0*01);dispmore(1,5,"TimeNow",8);clkp();break;default:break;}for(i=0;i<32000;i++);IE0=0;E*0=1;}/****************************************voidint1()********************************显示模式选择按钮(Disp)中断效劳子程序******************************************************************************************/voidint1()interrupt2 {E*1=0;if(++MODE>3)MODE=0;switch(MODE){case0:wr(0*01);lcp();ttimep();break;case1:wr(0*01);sdp();m*sdp();break;case2:wr(0*01);pjsdp();ap();break;case3:wr(0*01);dispmore(1,5,"TimeNow",8);clkp();break;default:break;}for(i=0;i<32000;i++);IE1=0;E*1=1;}/****************************************vvoidtimer0()********************************T0中断效劳子程序,主要用于计算累计行驶时间,50ms一次中断,每20次sj++,更新累计行驶时间〔单位秒〕*******************************************************************************************/voidtimer0()interrupt1 { TH0=0*3c;TL0=0*b0;if(++ssj>19){sj++;ssj=0;cgw++;if(cgw>9){cgw=0;csw++;if(csw>5){csw=0;++cbw; if(cbw>9){cbw=0;++cqw; if(cqw>5){cqw=0; cww2++;if(cww2>23)cww2=0;csww=cww2/10;cww=cww2%10; } } } }if(MODE==0){lcp();ttimep();}if(MODE==3)clkp();}}/****************************************voidmain()********************************主程序,初始化LCD,显示欢送信息,更改时钟、直径设置,开中断、计时器等******************************************************************************************/voidmain(){init_LCD();dispmore(1

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论