找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2476|回复: 2
打印 上一主题 下一主题
收起左侧

单片机实现自行车里程表设计源码与PCB文件

[复制链接]
跳转到指定楼层
楼主

硬件原理图如下


Altium Designer画的原理图和PCB图如下:(51hei附件中可下载工程文件)


硬件原理图和PCB图
01.硬件设计.rar (615.62 KB, 下载次数: 47)

单片机程序
02.软件设计.rar (92.62 KB, 下载次数: 41)

单片机源程序如下:

  1. #include "reg52.h"
  2. #include "stdio.h"
  3. #include "LCD12864.h"
  4. #include "DS1302.h"


  5. #define                UpdataTimer(Timer)         (Timer = Timer0Count)                //刷新定时计数宏定义


  6. sbit  KEY_SET = P3^4;                  //设置键
  7. sbit  KEY_ADD = P3^5;                  //加一键
  8. sbit  KEY_DEC = P3^7;                   //减一键
  9. sbit  Speaker = P2^3;                   //蜂鸣器


  10. uchar  m_nIndexSet;                        //菜单选择项
  11. uint   m_Speed;                                //速度(0.1km/h)
  12. uint   m_Mileage;                        //总里程(0.1km)  
  13. uint   m_RideSize;                        //骑行里程(米)
  14. uchar  m_RideTime[2];                //骑行时间(秒)
  15. uchar  Set_Speed;                         //预设速度(km/h) [0]
  16. uint   Set_Girth;                           //轮胎周长(毫米) [1,2]
  17. uchar  Set_DelayTime;                //骑行停顿时间(秒)[3]
  18. bit           time500ms_flag;                 //0.5秒标志位
  19. uint   Timer0Count;                 //基准定时计数
  20. uint   Mileage_Buf[3];                 //里程计算缓存,0:毫米;1:米;2:千米         [456789]
  21. uint   RideTimer;                
  22. uint   SpeedTimeBuf[2];

  23. void  Sys_Init(void)        //系统初始化
  24. {
  25.         IT0 = 1;            //set INT0 int type (1:Falling 0:Low level)
  26.     EX0 = 1;            //enable INT0 interrupt
  27.         EA = 1;

  28.         m_nIndexSet = 0;  
  29.         Timer0Count = 0;
  30.         m_Speed = 0;
  31.         m_RideSize = 0;
  32.         m_RideTime[0] = m_RideTime[1] = 0;
  33.         RideTimer = 0;
  34.         SpeedTimeBuf[0] = SpeedTimeBuf[1] = 10000;
  35.         Set_Speed = ds1302_read(ds1302_RAM0);        //读参数
  36.         Set_Girth = ds1302_read(ds1302_RAM1);        //读参数       
  37.         Set_Girth <<= 8;
  38.         Set_Girth |= ds1302_read(ds1302_RAM2);
  39.         Set_DelayTime = ds1302_read(ds1302_RAM3);        //读参数
  40.        
  41.         Mileage_Buf[0] = ds1302_read(ds1302_RAM4);        //读参数       
  42.         Mileage_Buf[0] <<= 8;
  43.         Mileage_Buf[0] |= ds1302_read(ds1302_RAM5);
  44.         Mileage_Buf[1] = ds1302_read(ds1302_RAM6);        //读参数       
  45.         Mileage_Buf[1] <<= 8;
  46.         Mileage_Buf[1] |= ds1302_read(ds1302_RAM7);
  47.         Mileage_Buf[2] = ds1302_read(ds1302_RAM8);        //读参数       
  48.         Mileage_Buf[2] <<= 8;
  49.         Mileage_Buf[2] |= ds1302_read(ds1302_RAM9);
  50.         m_Mileage = Mileage_Buf[2]*10 + Mileage_Buf[1]/100; //0.1km        
  51. }

  52. void  Timer0Init(void)        //50毫秒@11.0592MHz
  53. {
  54.         TMOD &= 0xF0;        //设置定时器模式
  55.         TMOD |= 0x01;        //设置定时器模式
  56.         TL0 = 0x00;                //设置定时初值
  57.         TH0 = 0x4C;                //设置定时初值
  58.         TF0 = 0;                //清除TF0标志
  59.         TR0 = 1;                //定时器0开始计时
  60.         ET0 = 1;
  61.         EA  = 1;
  62. }

  63. void  Timer1Init(void)        //1毫秒@11.0592MHz
  64. {
  65.         TMOD &= 0x0F;        //设置定时器模式
  66.         TMOD |= 0x10;        //设置定时器模式
  67.         TL1 = 0x66;                //设置定时初值
  68.         TH1 = 0xFC;                //设置定时初值
  69.         TF1 = 0;                //清除TF1标志
  70.         TR1 = 1;                //定时器1开始计时
  71.         ET1 = 1;
  72.         EA  = 1;
  73. }

  74. uint  CheckTimer(uint Timer) //定时计数值检测,返回与定时器0的差值
  75. {
  76.     if(Timer0Count > Timer)
  77.     {
  78.         return(Timer0Count - Timer);
  79.     }
  80.     else
  81.     {
  82.         return ~(Timer - Timer0Count) + 1;
  83.     }
  84. }

  85. void  On_GetTimeClock(void)        //获取日历时钟0.5秒检测一遍
  86. {
  87.         static uint GetTime=0;
  88.         uchar i=10;

  89.         if(CheckTimer(GetTime)>=10)                                //0.5秒退出设置菜单         10*50=500
  90.         {
  91.                 UpdataTimer(GetTime);                                //更新时间计数
  92.                 ds1302_gettime();                                        //获取时间       
  93.         }
  94. }

  95. void  On_DisplayRun(void)        //液晶显示菜单
  96. {
  97.         static uint ShowTime=0;
  98.         uchar i,k,str_buf[16];
  99.         uint dat;

  100.         if(CheckTimer(ShowTime)<=4)                                //0.2秒显示        4*50=200
  101.         {
  102.                 return;
  103.         }
  104.         UpdataTimer(ShowTime);                                        //更新时间计数

  105.         if(m_nIndexSet==0)                                                 //运行画面
  106.         {
  107.                 str_buf[0] = '2'; str_buf[1] = '0';        //2018-02-26 15:14
  108.                 str_buf[2] = Timer.Year/10 +'0';
  109.                 str_buf[3] = Timer.Year%10 +'0';
  110.                 str_buf[4] = '-';
  111.                 str_buf[5] = Timer.Month/10 +'0';
  112.                 str_buf[6] = Timer.Month%10 +'0';
  113.                 str_buf[7] = '-';
  114.                 str_buf[8] = Timer.Day/10 +'0';
  115.                 str_buf[9] = Timer.Day%10 +'0';
  116.                 str_buf[10] = ' ';
  117.                 str_buf[11] = Timer.Hour/10 +'0';
  118.                 str_buf[12] = Timer.Hour%10 +'0';
  119.                 str_buf[13] = ':';
  120.                 str_buf[14] = Timer.Minute/10 +'0';
  121.                 str_buf[15] = Timer.Minute%10 +'0';
  122.                 DisplayString(0,0, str_buf, 16);

  123.                 memcpy(str_buf, "里程:****.*km   ", 16); //总里程:****.*km
  124.                 dat = m_Mileage/10;
  125.                 for(i=0; i<4; i++)
  126.                 {
  127.                         str_buf[8-i] = dat%10 +'0';
  128.                         dat /= 10;       
  129.                 }
  130.                 str_buf[10] = m_Mileage%10 +'0';
  131.                 k = 0;
  132.                 while(1)
  133.                 {
  134.                         if(str_buf[5]!='0' || k>=3)
  135.                                 break;
  136.                         else
  137.                         {
  138.                                 for(i=5;i<=12;i++)        str_buf[i] = str_buf[i+1];
  139.                         }
  140.                         k++;
  141.                 }
  142.                 DisplayString(0,1, str_buf, 16);

  143.                 memcpy(str_buf, "速度:  . km/h   ", 16); //速度:**.*km/h   02.6km
  144.                 str_buf[5] = (m_Speed/100)%10 +'0';
  145.                 str_buf[6] = (m_Speed/10)%10 +'0';
  146.                 str_buf[8] = m_Speed%10 +'0';
  147.                 if(m_Speed<100)
  148.                 {
  149.                         for(i=5;i<=12;i++)
  150.                                 str_buf[i] = str_buf[i+1];       
  151.                 }
  152.                 DisplayString(0,2, str_buf, 16);

  153.                 if(m_RideSize<10000)
  154.                 {
  155.                         memcpy(str_buf, "骑行:****m 01:00", 16); //骑行:****m@01:00
  156.                         dat = m_RideSize;
  157.                         k = 8;
  158.                 }
  159.                 else
  160.                 {
  161.                         memcpy(str_buf, "骑行:***km 01:00", 16); //骑行:***km@01:00
  162.                         dat = m_RideSize/1000;
  163.                         k = 7;
  164.                 }       
  165.                 for(i=k; i>=5; i--)
  166.                 {
  167.                         str_buf[i] = dat%10 +'0';
  168.                         dat /= 10;       
  169.                 }
  170.                 k=0;
  171.                 while(1)
  172.                 {
  173.                         if(str_buf[5]!='0' || k>=3)
  174.                                 break;
  175.                         else
  176.                         {
  177.                                 for(i=5;i<=9;i++)        str_buf[i] = str_buf[i+1];
  178.                         }
  179.                         k++;
  180.                 }

  181.                 str_buf[11] = m_RideTime[0]/10 +'0';
  182.                 str_buf[12] = m_RideTime[0]%10 +'0';
  183.                 str_buf[14] = m_RideTime[1]/10 +'0';
  184.                 str_buf[15] = m_RideTime[1]%10 +'0';
  185.                 DisplayString(0,3, str_buf, 16);
  186.         }
  187.         else         //设置参数画面
  188.         {
  189.                  memcpy(str_buf, "预设速度:   km/h", 16); //预设速度: **km/h       
  190.                 if(m_nIndexSet!=1 || time500ms_flag==1)         //=1
  191.                 {
  192.                         str_buf[10] = Set_Speed/10 +'0';
  193.                         str_buf[11] = Set_Speed%10 +'0';
  194.                 }
  195.                 DisplayString(0,0, str_buf, 16);

  196.                 memcpy(str_buf, "轮胎周长:    mm ", 16); //轮胎周长: ****mm       
  197.                 if(m_nIndexSet!=2 || time500ms_flag==1)         //=2
  198.                 {
  199.                         dat = Set_Girth;
  200.                         for(i=12; i>=10; i--)
  201.                         {
  202.                                 str_buf[i] = dat%10 +'0';
  203.                                 dat /= 10;       
  204.                         }
  205.                 }
  206.                 DisplayString(0,1, str_buf, 16);

  207.                 memcpy(str_buf, "停顿时间:   秒  ", 16); //停顿时间: **秒       
  208.                 if(m_nIndexSet!=3 || time500ms_flag==1)
  209.                 {
  210.                         str_buf[10] = Set_DelayTime/10 +'0';
  211.                         str_buf[11] = Set_DelayTime%10 +'0';
  212.                 }
  213.                 DisplayString(0,2, str_buf, 16);

  214.                 memcpy(str_buf, "20  -  -     :  ", 16); //2018-02-26 15:14
  215.                 if(m_nIndexSet!=4 || time500ms_flag==1)
  216.                 {
  217.                         str_buf[2] = Timer.Year/10 +'0';
  218.                         str_buf[3] = Timer.Year%10 +'0';
  219.                 }
  220.                 if(m_nIndexSet!=5 || time500ms_flag==1)
  221.                 {
  222.                         str_buf[5] = Timer.Month/10 +'0';
  223.                         str_buf[6] = Timer.Month%10 +'0';
  224.                 }
  225.                 if(m_nIndexSet!=6 || time500ms_flag==1)
  226.                 {
  227.                         str_buf[8] = Timer.Day/10 +'0';
  228.                         str_buf[9] = Timer.Day%10 +'0';
  229.                 }
  230.                 if(m_nIndexSet!=7 || time500ms_flag==1)
  231.                 {
  232.                         str_buf[11] = Timer.Hour/10 +'0';
  233.                         str_buf[12] = Timer.Hour%10 +'0';
  234.                 }
  235.                 if(m_nIndexSet!=8 || time500ms_flag==1)
  236.                 {
  237.                         str_buf[14] = Timer.Minute/10 +'0';
  238.                         str_buf[15] = Timer.Minute%10 +'0';
  239.                 }
  240.                 DisplayString(0,3, str_buf, 16);
  241.         }
  242. }

  243. void  On_SetKey(void)  //设置按键处理
  244. {
  245.         if(KEY_SET==0)
  246.         {
  247.                 Delay_ms(10);         //去抖动
  248.                 if(KEY_SET==0)       
  249.                 {
  250.                         m_nIndexSet++;
  251.                         if(m_nIndexSet>8)
  252.                                 m_nIndexSet = 0;

  253.                         while(KEY_SET==0);
  254.                 }
  255.         }
  256. }

  257. void  On_AddDecKey(void)  //加减按键处理
  258. {
  259.         if(KEY_ADD==0)
  260.         {
  261.                 Delay_ms(10); //去抖动
  262.                 if(KEY_ADD==0)       
  263.                 {
  264.                         if(m_nIndexSet==1)
  265.                         {
  266.                                 Set_Speed++;
  267.                                 if(Set_Speed>99) Set_Speed=99;
  268.                                 ds1302_write(0x8e,0x00);                                          //允许写操作
  269.                                 ds1302_write(ds1302_RAM0, Set_Speed);                //写入1302
  270.                                 ds1302_write(0x8e,0x80);                                          //写保护,禁止写操作               
  271.                         }
  272.                         else if(m_nIndexSet==2)
  273.                         {
  274.                                 Set_Girth++;
  275.                                 if(Set_Girth>999) Set_Girth=999;
  276.                                 ds1302_write(0x8e,0x00);                                          //允许写操作
  277.                                 ds1302_write(ds1302_RAM1, Set_Girth/256);        //写入1302
  278.                                 ds1302_write(ds1302_RAM2, Set_Girth%256);        //写入1302
  279.                                 ds1302_write(0x8e,0x80);                                          //写保护,禁止写操作
  280.                         }
  281.                         else if(m_nIndexSet==3)
  282.                         {
  283.                                 Set_DelayTime++;
  284.                                 if(Set_DelayTime>99) Set_DelayTime=99;
  285.                                 ds1302_write(0x8e,0x00);                                          //允许写操作
  286.                                 ds1302_write(ds1302_RAM3, Set_DelayTime);        //写入1302
  287.                                 ds1302_write(0x8e,0x80);                                          //写保护,禁止写操作
  288.                         }
  289.                         else //45678
  290.                         {
  291.                                 ds1302_SetTime(m_nIndexSet-3, 1);
  292.                                 ds1302_SetTime(6, 1);
  293.                         }
  294.                         if(m_nIndexSet<=3)
  295.                         {
  296.                                  Delay_ms(150);       
  297.                         }
  298.                         else
  299.                         {
  300.                                 while(KEY_ADD==0);
  301.                         }
  302.                         time500ms_flag = 1;
  303.                 }
  304.         }
  305.        
  306.         if(KEY_DEC==0)
  307.         {
  308.                 Delay_ms(10);
  309.                 if(KEY_DEC==0)       
  310.                 {
  311.                         if(m_nIndexSet==1)
  312.                         {
  313.                                 Set_Speed--;
  314.                                 if(Set_Speed>200) Set_Speed=0;
  315.                                 ds1302_write(0x8e,0x00);                                          //允许写操作
  316.                                 ds1302_write(ds1302_RAM0,Set_Speed);                //写入1302
  317.                                 ds1302_write(0x8e,0x80);                                          //写保护,禁止写操作
  318.                         }
  319.                         else if(m_nIndexSet==2)
  320.                         {
  321.                                 Set_Girth--;
  322.                                 if(Set_Girth>50000) Set_Girth=0;
  323.                                 ds1302_write(0x8e,0x00);                                          //允许写操作
  324.                                 ds1302_write(ds1302_RAM1, Set_Girth/256);        //写入1302
  325.                                 ds1302_write(ds1302_RAM2, Set_Girth%256);        //写入1302
  326.                                 ds1302_write(0x8e,0x80);                                          //写保护,禁止写操作
  327.                         }
  328.                         else if(m_nIndexSet==3)
  329.                         {
  330.                                 Set_DelayTime--;
  331.                                 if(Set_DelayTime>200) Set_DelayTime=0;
  332.                                 ds1302_write(0x8e,0x00);                                          //允许写操作
  333.                                 ds1302_write(ds1302_RAM3, Set_DelayTime);        //写入1302
  334.                                 ds1302_write(0x8e,0x80);                                          //写保护,禁止写操作       
  335.                         }
  336.                         else
  337.                         {
  338.                                 ds1302_SetTime(m_nIndexSet-3, 0);
  339.                                 ds1302_SetTime(6, 0);
  340.                         }
  341.                         if(m_nIndexSet<=3)
  342.                         {
  343.                                  Delay_ms(150);       
  344.                         }
  345.                         else
  346.                         {
  347.                                 while(KEY_DEC==0);
  348.                         }
  349.                         time500ms_flag = 1;
  350.                 }
  351.         }               
  352. }

  353. void  On_AutoQuitSet(void) //自动退出设置菜单
  354. {
  355.         static uint KeyTime=0;         //按键时间计时(秒)

  356.         if(KEY_SET==0 || KEY_ADD==0 || KEY_DEC==0)         //有按键按下
  357.         {
  358.                 UpdataTimer(KeyTime);                //更新时间计数
  359.         }

  360.         if(CheckTimer(KeyTime)<=400)        //20秒退出设置菜单        400*50 = 20000
  361.         {
  362.                 return;
  363.         }
  364.         UpdataTimer(KeyTime);                        //更新时间计数
  365.         m_nIndexSet = 0;                                //运行模式
  366. }

  367. void  On_SaveMileage(void) //存储里程
  368. {
  369.         static uint m_buf[3]={0,0,0};

  370.         if(Mileage_Buf[2]>=6000)
  371.         {
  372.                 Mileage_Buf[2] = 0;
  373.                 Mileage_Buf[1] = 0;
  374.                 Mileage_Buf[0] = 0;
  375.         }
  376.         if(m_buf[0]!=Mileage_Buf[0])
  377.         {
  378.                 ds1302_write(0x8e,0x00);                                                  //允许写操作
  379.                 ds1302_write(ds1302_RAM4, Mileage_Buf[0]/256);        //写入1302
  380.                 ds1302_write(ds1302_RAM5, Mileage_Buf[0]%256);        //写入1302
  381.                 ds1302_write(0x8e,0x80);                                                  //写保护,禁止写操作
  382.                 m_buf[0] = Mileage_Buf[0];
  383.         }
  384.         if(m_buf[1]!=Mileage_Buf[1])
  385.         {
  386.                 ds1302_write(0x8e,0x00);                                                  //允许写操作
  387.                 ds1302_write(ds1302_RAM6, Mileage_Buf[1]/256);        //写入1302
  388.                 ds1302_write(ds1302_RAM7, Mileage_Buf[1]%256);        //写入1302
  389.                 ds1302_write(0x8e,0x80);                                                  //写保护,禁止写操作
  390.                 m_buf[1] = Mileage_Buf[1];
  391.         }
  392.         if(m_buf[2]!=Mileage_Buf[2])
  393.         {
  394.                 ds1302_write(0x8e,0x00);                                                  //允许写操作
  395.                 ds1302_write(ds1302_RAM8, Mileage_Buf[2]/256);        //写入1302
  396.                 ds1302_write(ds1302_RAM9, Mileage_Buf[2]%256);        //写入1302
  397.                 ds1302_write(0x8e,0x80);                                                  //写保护,禁止写操作
  398.                 m_buf[2] = Mileage_Buf[2];
  399.         }
  400.         m_Mileage = Mileage_Buf[2]*10 + Mileage_Buf[1]/100; //0.1km
  401. }

  402. void  On_RideHandle(void) //骑行处理
  403. {
  404.         uint buf;

  405.         buf = (Set_DelayTime*1000)/50; //10000/50=200
  406.         if(CheckTimer(RideTimer)>=buf)
  407.         {
  408.                 UpdataTimer(RideTimer);       
  409.                 m_RideSize = 0;
  410.                 m_RideTime[0] = m_RideTime[1] = 0;
  411.         }
  412. }

  413. void  On_SpeedHandle(void) //骑行速度处理
  414. {
  415.         static uint speed_timer=0;
  416.         static uint SpeedBuf[10]={0,0,0,0,0,0,0,0,0};
  417.         uchar i;
  418.        
  419.         if(CheckTimer(speed_timer)>=4)                        //0.2秒到
  420.         {
  421.                 UpdataTimer(speed_timer);                        //更新时间计数

  422.                 for(i=0;i<9;i++)                                    //软件滑动滤波算法
  423.                 {
  424.                          SpeedBuf[i] = SpeedBuf[i+1];       
  425.                 }
  426.                 SpeedBuf[9]  = Set_Girth*36;
  427.                 SpeedBuf[9] /= SpeedTimeBuf[1];
  428.                 if(SpeedBuf[9]>=999) SpeedBuf[9] = 999;
  429.                 if(SpeedTimeBuf[0]>=500)                        //0.5s
  430.                         SpeedBuf[9] = 0;
  431.                
  432.                 for(m_Speed=0,i=0;i<10;i++)
  433.                 {
  434.                          m_Speed += SpeedBuf[i];
  435.                 }
  436.                 m_Speed /= 10;
  437.         }

  438.         if((m_Speed/10)>=Set_Speed)                                //速度超速
  439.                 Speaker = 0;                                                  //打开报警器
  440.         else
  441.                 Speaker = 1;                                                //关闭报警器
  442. }

  443. void  main()  //主函数
  444. {
  445.         Timer0Init();                        //50毫秒@11.0592MHz
  446.         Timer1Init();                        //10毫秒@11.0592MHz
  447.         LCD12864_Init();                //液晶初始化
  448.         ds1302_Init();                         //设置1302的初始时间
  449.         Sys_Init();                                //系统初始化

  450.         while(1)
  451.         {
  452.                    On_GetTimeClock();        //获取日历时钟0.5秒检测一遍
  453.                 On_DisplayRun();        //液晶显示
  454.                 On_AutoQuitSet();        //自动退出设置菜单
  455.                 On_SaveMileage();         //存储里程
  456.                 On_RideHandle();        //骑行处理
  457.                 On_SpeedHandle();         //骑行速度处理

  458.                 On_SetKey();                  //设置按键处理
  459.                 On_AddDecKey();         //加减按键处理       
  460.         }
  461. }


  462. void  EXINT0_Interrupt() interrupt 0        //外部中断0服务函数
  463. {
  464.         Mileage_Buf[0] += Set_Girth;            // 1256/1000 = 1   256
  465. ……………………

  466. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏2 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:253767 发表于 2018-7-16 08:41 | 只看该作者
谢谢分享!!!
回复

使用道具 举报

板凳
ID:538392 发表于 2019-12-11 14:03 | 只看该作者
非常感谢!!!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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