DIY自行车速度里程表
本帖最后由 1五湖四海1 于 2011-8-1 20:38 编辑上班以后,路程比较远就很少骑车了,最近单位发了一台自行车。周末休息时上公园骑了几圈。回来后想如果有个速度表就好了,看看自己能骑到多少Km/h。自己是个爱制作DIY的电子爱好者,坐着想了一个设计方案。这个要有里程表有速度显示和行驶时间显示。这些功能只要一个功能强大的单片机就可以完成要求。 功能上采用6个数码管做显示,打开后左边三位显示里程数单位为Km,右边两位显示速度单位为Km/h。当按下转换按钮后,显示内容切换到显示行驶时间,左边两位显示小时,右边两位显示分钟,秒信号用中间小数点闪烁显示。再次按下转换按钮时,所以数码管关闭以节省电能,再按下转换按钮回到显示里程速度。那天坐公交车,汽车突然启动时,这时有个加速度到匀速行驶。这让我想起水银开关,利用水银开关成45度角放置在垂直平面水银开关头朝后。这样就可以完成加速度检测了。如果车停止或匀速前进时水银开关闭合。一旦汽车启动或加速后水银开关断开,等到匀速后水银开关再次闭合。只有计算出从闭合到断开再到闭合的时间就可以知道加速度大小了。同样原理可以制成减速检测。我利用这一原理将加速度检测加到了自行车速度里程表。我还利用555制作了一个1KHz的频率信号输入到扬声器做提示音,如果超速时发出提示音。我制作这个自行车速度里程表出于自己对DIY单片机兴趣爱好,我认为在实用性上也很方便可以测速度,里程,行驶时间和加速度而且还带扬声器超速时提示,用起来蛮好的。 自行车速度里程表由硬件和软件组成,硬件是由单片机最小系统加六位扫描数码管和霍尔速度传感器构成。软件用C语言编写的下面是源程序还有单片机原理图///////////2010.08.09.21:00///////////////////#include<reg52.h> #include<absacc.h> #include <intrins.h> #define uint unsigned int #define uchar unsigned char #define shum P1//数码#define saom P2 //数码扫描unsigned char code xsjs[]={~0x3F,~0x06,~0x5B,~0x4F,~0x66,~0x6D,~0x7D,~0x07,~0x7F,~0x6F ,~0x00};char disp={0,0,0,0};uchar T0count; //从T0的计数单元中读取计数的数值 uchar timecount; // bit flag;bit d_05s=0;uchar set=0;uchar sp=30; //标志位 unsigned long x;unsigned long z;unsigned long y; unsigned long a; unsigned long d;uchar hour=0,min=0,sec=0;uchar xPos,yPos; uchar i;uchar she=30;V;uint j=0;sbit P0_1=P0^1;sbit P2_1=P2^1;sbit P1_7=P1^7;sbit P3_1=P3^1;sbit P3_2=P3^2;sbit P3_4=P3^4;sbit P3_5=P3^5;sbit P3_6=P3^6;sbit P3_7=P3^7;void delay(uint k){uint i,j;for(i=0;j<k;i++){ for(j=0;j<121;j++);}}void scan_key(){delay(1);if(P3_2==0)set++;if(set>=3)set=0;if(set==1)flag=0x55;F0:if(P3_2==0)goto F0;}void display_led()//数码管模块{char e,scan;disp=hour/10;disp=hour%10;disp=min/10;disp=min%10;P0=0xff;scan=0xdf;for(e=0;e<4;e++){shum=0xff;saom=scan;if(d_05s==1){if(e==1)P1_7=0;else P1_7=1;}
P1=xsjs];delay(4);scan>>=1;}}void lidisp(){d=a/7;
P1=xsjs; P2=0xdf;delay(1);P1=xsjs; P1_7=0; P2=0xef; delay(1);P1=xsjs; P2=0xf7;delay(1);P1=xsjs; P2=0xfb;delay(1);P1=xsjs; P2=0xfd;delay(1);P1=xsjs; P2=0xfe;delay(1);}
void main(void) {
TMOD=0x15; //T0工作为16位计数器(方式1),T1工作方式为16位定时器 TH0=0; //计数为65536 TL0=0; // TH1=(65536-12000)/256; //定时器采用定时4ms.初值为12000 TL1=(65536-12000)%256; TR1=1; //TR1=1,控制开关闭合,计数脉冲进入T1计数器,启动定时 TR0=1; //TR0=1,控制开关闭合,计数脉冲进入T1计数器,启动计数 ET0=1; //定时器0开中断 ET1=1; //定时器1开中断 EA=1; //CPU开中断 y=0;while(1) {if(P3_1==1){
if(P3_2==0)scan_key(); switch(set) { case 0: lidisp(); break; case 1: display_led(); break; case 2: P1=0xff;break; default:break; }
if(flag==1) // { flag=0; //清标志位 z=2*(T0count*65536+TH0*256+TL0); //取得时间宽度参数 x=z*36/10; y=z+y;
if(j==0)
{ V=x; V=x; V=x; V=x; V=x; V=x; V=x; j++; } if(0<j<=7) { V=x; j++; } if(j>7) { j=0;V=x; j++; } a=V+V+V+V+V+V+V;
timecount=0; T0count=0; TH0=0; TL0=0; TR0=1; //TR0=1,控制开关闭合,计数脉冲进入T1计数器,启动计数 } }else {if(P3_6==0)she++;if(P3_5==0)she--; P1=xsjs;P2=0xfd;delay(5); P1=xsjs;P2=0xfe;delay(5); }} } //;================================================================================== void t0() interrupt 1 using 0 //T0中断服务 { T0count++; //对P3。4口的脉冲进行计数 } //;================================================================================== void t1(void) interrupt 3 using 0 //T1中断服务 { TH1=(65536-12000)/256; //计数初值重装载 TL1=(65536-12000)%256; timecount++; if(timecount==250) { sec++; TR0=0; timecount=0; flag=1; // 置标志 } if(timecount<=125)d_05s=0; else d_05s=1; if(sec==60){min++;sec=0;} if(min==60){hour++;min=0;} if(hour==24){hour=0;}}
楼主的东西真让我羡慕
可惜我是玩纯机械的,我认为在前车轮辐条上放上个东西,检测车轮转动的圈数! tntk 发表于 2011-8-1 19:52 static/image/common/back.gif
楼主的东西真让我羡慕
可惜我是玩纯机械的,我认为在前车轮辐条上放上个东西,检测车轮转动的圈数!
tntk 网友你好:
你说的对,我用的是霍尔接近开关固定在车架上,在车轮辐条上安装一个小圆磁钢。车轮每转一圈输出一个信号,根据单位时间1s检测的脉冲数就可以测出速度了。
准不准 呵呵呵,有点意思啊这个~~~ wrzshud 发表于 2011-8-1 20:12 static/image/common/back.gif
准不准
wrzshud网友你好:
这个是拿单片机内定时器资源制作的,精密计时精度一般,用于测速精度还是挺高的。
直接买个自行车的码表就可以,楼主的动手能力很强大,佩服 245037744 发表于 2011-8-1 20:26 static/image/common/back.gif
直接买个自行车的码表就可以,楼主的动手能力很强大,佩服
你好:
制作过程是个享受,会遇到想不到的困难,去解决问题带来快乐。制作完安装在车上体验制作带来的乐趣。
嫉妒死了,喜欢骑车,但是不会电啊!呜呜呜…… 楼主搞的东西一直是我向往的,可是一直找不到门路,自己动手搞的东西很有成就感,那种感觉想想就爽