机械社区

 找回密码
 注册会员

QQ登录

只需一步,快速开始

搜索
查看: 73358|回复: 203

DIY自行车速度里程表

  [复制链接]
发表于 2011-8-1 19:28:57 | 显示全部楼层 |阅读模式
本帖最后由 1五湖四海1 于 2011-8-1 20:38 编辑

   上班以后,路程比较远就很少骑车了,最近单位发了一台自行车。周末休息时上公园骑了几圈。回来后想如果有个速度表就好了,看看自己能骑到多少Km/h。自己是个爱制作DIY的电子爱好者,坐着想了一个设计方案。这个要有里程表有速度显示和行驶时间显示。这些功能只要一个功能强大的单片机就可以完成要求。
   功能上采用6个数码管做显示,打开后左边三位显示里程数单位为Km,右边两位显示速度单位为Km/h。当按下转换按钮后,显示内容切换到显示行驶时间,左边两位显示小时,右边两位显示分钟,秒信号用中间小数点闪烁显示。再次按下转换按钮时,所以数码管关闭以节省电能,再按下转换按钮回到显示里程速度。
  那天坐公交车,汽车突然启动时,这时有个加速度到匀速行驶。这让我想起水银开关,利用水银开关成45度角放置在垂直平面水银开关头朝后。这样就可以完成加速度检测了。如果车停止或匀速前进时水银开关闭合。一旦汽车启动或加速后水银开关断开,等到匀速后水银开关再次闭合。只有计算出从闭合到断开再到闭合的时间就可以知道加速度大小了。同样原理可以制成减速检测。我利用这一原理将加速度检测加到了自行车速度里程表。我还利用555制作了一个1KHz的频率信号输入到扬声器做提示音,如果超速时发出提示音。
  我制作这个自行车速度里程表出于自己对DIY单片机兴趣爱好,我认为在实用性上也很方便可以测速度,里程,行驶时间和加速度而且还带扬声器超速时提示,用起来蛮好的。
   自行车速度里程表由硬件和软件组成,硬件是由单片机最小系统加六位扫描数码管和霍尔速度传感器构成。软件用C语言编写的下面是源程序还有单片机原理图
8952.jpg PIC110801162634.jpg PIC110801162524.jpg
///////////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[4]={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[7];
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[0]=hour/10;
disp[1]=hour%10;
disp[2]=min/10;
disp[3]=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[disp[e]];
delay(4);
scan>>=1;
}
}
void lidisp()
{
d=a/7;

P1=xsjs[y/10000];    P2=0xdf;delay(1);
P1=xsjs[y%10000/1000];     P1_7=0;     P2=0xef;      delay(1);
P1=xsjs[y%1000/100];          P2=0xf7;delay(1);
P1=xsjs[10];            P2=0xfb;delay(1);
P1=xsjs[d/10];         P2=0xfd;delay(1);
P1=xsjs[d%10];       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[0]=x; V[1]=x; V[2]=x; V[3]=x; V[4]=x; V[5]=x; V[6]=x;
     j++;
    }
   if(0<j<=7)
    {
     V[j]=x;
     j++;
    }
   if(j>7)
    {
     j=0;V[j]=x;
     j++;  
    }     
    a=V[0]+V[1]+V[2]+V[3]+V[4]+V[5]+V[6];


    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[she/10];  P2=0xfd;delay(5);
    P1=xsjs[she%10];  P2=0xfe;delay(5);
   }  
}
}
//;==================================================================================
void t0() interrupt 1 using 0      //T0中断服务
{
    T0count++;                      //P34口的脉冲进行计数
}
//;==================================================================================
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;}  }

点评

还做了印刷板,这个成本有点高了吧。。。  发表于 2011-9-10 20:46

评分

参与人数 3威望 +22 收起 理由
wzx^-^ + 1 \(^o^)/~,HM
tigerguo1975 + 1 赞一个!
老鹰 + 20 NB

查看全部评分

回复

使用道具 举报

发表于 2011-8-1 19:52:56 | 显示全部楼层
楼主的东西真让我羡慕

可惜我是玩纯机械的,我认为在前车轮辐条上放上个东西,检测车轮转动的圈数!
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2011-8-1 20:09:21 | 显示全部楼层
tntk 发表于 2011-8-1 19:52
楼主的东西真让我羡慕

可惜我是玩纯机械的,我认为在前车轮辐条上放上个东西,检测车轮转动的圈数!

tntk 网友你好:
       你说的对,我用的是霍尔接近开关固定在车架上,在车轮辐条上安装一个小圆磁钢。车轮每转一圈输出一个信号,根据单位时间1s检测的脉冲数就可以测出速度了。
回复 支持 反对

使用道具 举报

发表于 2011-8-1 20:12:49 | 显示全部楼层
准不准
回复 支持 反对

使用道具 举报

发表于 2011-8-1 20:15:19 | 显示全部楼层
呵呵呵,有点意思啊这个~~~
回复 支持 反对

使用道具 举报

 楼主| 发表于 2011-8-1 20:21:07 | 显示全部楼层
wrzshud 发表于 2011-8-1 20:12
准不准

wrzshud网友你好:
            这个是拿单片机内定时器资源制作的,精密计时精度一般,用于测速精度还是挺高的。
回复 支持 反对

使用道具 举报

发表于 2011-8-1 20:26:27 | 显示全部楼层
直接买个自行车的码表就可以,楼主的动手能力很强大,佩服
回复 支持 反对

使用道具 举报

 楼主| 发表于 2011-8-1 20:33:42 | 显示全部楼层
245037744 发表于 2011-8-1 20:26
直接买个自行车的码表就可以,楼主的动手能力很强大,佩服

你好:
      制作过程是个享受,会遇到想不到的困难,去解决问题带来快乐。制作完安装在车上体验制作带来的乐趣。

点评

不错  发表于 2011-8-1 21:48
回复 支持 反对

使用道具 举报

发表于 2011-8-1 21:15:10 | 显示全部楼层
嫉妒死了,喜欢骑车,但是不会电啊!呜呜呜……
回复 支持 反对

使用道具 举报

发表于 2011-8-1 21:41:58 | 显示全部楼层
楼主搞的东西一直是我向往的,可是一直找不到门路,自己动手搞的东西很有成就感,那种感觉想想就爽
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

小黑屋|手机版|Archiver|机械社区 ( 京ICP备10217105号-1,京ICP证050210号,浙公网安备33038202004372号 )

GMT+8, 2024-11-26 15:02 , Processed in 0.068214 second(s), 25 queries , Gzip On.

Powered by Discuz! X3.4 Licensed

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表