打印

MSP430G2553制作的自行车测度系统

[复制链接]
1934|11
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
一,功能介绍:
                  本系统主要用于安装在自行车上测量自行车的运行速度和行驶距离。然后将速度和距离信息显示在显示在LCD显示屏上。                  (1) 处理器选用的是TI的MSP430G2553 单片机
                  (2)测速装置选用的是霍尔器件,在车圈上固定一个磁铁,然后430连接霍尔器件,通过输入捕获功能测量车轮的转动输出的脉冲的周期 在加上事先计算出车轮的直径就可计算                           出车子的运行速度和行驶距离
                  (3)显示屏选用的是NOKIA5110 LCD的显示屏,此显示屏的成本比较低,可以满足我的显示要求。
                  (4)整个系统有两个按键,一个是距离清零按键,按下该按键可以将显示的距离清零,这样方便测量起始地和目的地的距离,另外一个按键是用于打开LCD的背光的,用于夜晚                      使用。当夜晚光线比较暗时,按下该按键LCD的背光打开,方便看清楚显示的东西。在按一下背光熄灭。
                   (5)整个系统的供电的用到2节7号电池供电,当平常车子没有运行的时候,430处于低功耗状态。耗电比较少,现在测速系统已将安装在我车子上正常工作3个月了

         
二,系统框图
图1
                              图1是整个系统的框图:LCD显示屏和MSP430G2553的连接采用的SPI接口,霍尔传感器和按键和430之间是IO口连接。

三,系统原理图



图2

               图2是整个系统的原理图
四,程序代码
//******************************************************************************
#include <msp430.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

unsigned char Count, First_Time;
unsigned int REdge1, REdge2, FEdge;
unsigned char MST_Data, SLV_Data;
#define DC P2OUT = P2OUT|(1<<5)
#define SCE P2OUT = P2OUT|(1<<4)

#define CLK_H  P1OUT=P1OUT|(1<<5)

#define CLK_L  P1OUT=P1OUT&(~(1<<5))

#define Data_H  P1OUT=P1OUT|((1<<7))

#define Data_L  P1OUT=P1OUT&(~(1<<7))

#define u8 unsigned char
#define u16 unsigned int
typedef struct
{
        u8 x;
        u8 y;
}point;

/*------5110屏幕尺寸和功能宏定义------*/
#define DATA        1                                                                                                                                //数据
#define CMD 0                                                                                                                                        //命令
#define LCD_X        84                                                                                                                        //液晶屏横坐标宽度
#define LCD_ROW LCD_X                                                                                                        //液晶屏列宽度

unsigned char  const ASCII_6_8[][6] =
{
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // 20 (空格)
,{0x00, 0x00, 0x00, 0x5f, 0x00, 0x00} // 21 !
,{0x00, 0x00, 0x07, 0x00, 0x07, 0x00} // 22 "
,{0x00, 0x14, 0x7f, 0x14, 0x7f, 0x14} // 23 #
,{0x00, 0x24, 0x2a, 0x7f, 0x2a, 0x12} // 24 $
,{0x00, 0x23, 0x13, 0x08, 0x64, 0x62} // 25 %
,{0x00, 0x36, 0x49, 0x55, 0x22, 0x50} // 26 &
,{0x00, 0x00, 0x05, 0x03, 0x00, 0x00} // 27 '
,{0x00, 0x00, 0x1c, 0x22, 0x41, 0x00} // 28 (
,{0x00, 0x00, 0x41, 0x22, 0x1c, 0x00} // 29 )
,{0x00, 0x14, 0x08, 0x3e, 0x08, 0x14} // 2a *
,{0x00, 0x08, 0x08, 0x3e, 0x08, 0x08} // 2b +
,{0x00, 0x00, 0x50, 0x30, 0x00, 0x00} // 2c ,
,{0x00, 0x08, 0x08, 0x08, 0x08, 0x08} // 2d -
,{0x00, 0x00, 0x60, 0x60, 0x00, 0x00} // 2e .
,{0x00, 0x20, 0x10, 0x08, 0x04, 0x02} // 2f /
,{0x00, 0x3e, 0x51, 0x49, 0x45, 0x3e} // 30 0
,{0x00, 0x00, 0x42, 0x7f, 0x40, 0x00} // 31 1
,{0x00, 0x42, 0x61, 0x51, 0x49, 0x46} // 32 2
,{0x00, 0x21, 0x41, 0x45, 0x4b, 0x31} // 33 3
,{0x00, 0x18, 0x14, 0x12, 0x7f, 0x10} // 34 4
,{0x00, 0x27, 0x45, 0x45, 0x45, 0x39} // 35 5
,{0x00, 0x3c, 0x4a, 0x49, 0x49, 0x30} // 36 6
,{0x00, 0x01, 0x71, 0x09, 0x05, 0x03} // 37 7
,{0x00, 0x36, 0x49, 0x49, 0x49, 0x36} // 38 8
,{0x00, 0x06, 0x49, 0x49, 0x29, 0x1e} // 39 9
,{0x00, 0x00, 0x36, 0x36, 0x00, 0x00} // 3a :
,{0x00, 0x00, 0x56, 0x36, 0x00, 0x00} // 3b ;
,{0x00, 0x08, 0x14, 0x22, 0x41, 0x00} // 3c <
,{0x00, 0x14, 0x14, 0x14, 0x14, 0x14} // 3d =
,{0x00, 0x00, 0x41, 0x22, 0x14, 0x08} // 3e >
,{0x00, 0x02, 0x01, 0x51, 0x09, 0x06} // 3f ?
,{0x00, 0x32, 0x49, 0x79, 0x41, 0x3e} // 40 @
,{0x00, 0x7e, 0x11, 0x11, 0x11, 0x7e} // 41 A
,{0x00, 0x7f, 0x49, 0x49, 0x49, 0x36} // 42 B
,{0x00, 0x3e, 0x41, 0x41, 0x41, 0x22} // 43 C
,{0x00, 0x7f, 0x41, 0x41, 0x22, 0x1c} // 44 D
,{0x00, 0x7f, 0x49, 0x49, 0x49, 0x41} // 45 E
,{0x00, 0x7f, 0x09, 0x09, 0x09, 0x01} // 46 F
,{0x00, 0x3e, 0x41, 0x49, 0x49, 0x7a} // 47 G
,{0x00, 0x7f, 0x08, 0x08, 0x08, 0x7f} // 48 H
,{0x00, 0x00, 0x41, 0x7f, 0x41, 0x00} // 49 I
,{0x00, 0x20, 0x40, 0x41, 0x3f, 0x01} // 4a J
,{0x00, 0x7f, 0x08, 0x14, 0x22, 0x41} // 4b K
,{0x00, 0x7f, 0x40, 0x40, 0x40, 0x40} // 4c L
,{0x00, 0x7f, 0x02, 0x0c, 0x02, 0x7f} // 4d M
,{0x00, 0x7f, 0x04, 0x08, 0x10, 0x7f} // 4e N
,{0x00, 0x3e, 0x41, 0x41, 0x41, 0x3e} // 4f O
,{0x00, 0x7f, 0x09, 0x09, 0x09, 0x06} // 50 P
,{0x00, 0x3e, 0x41, 0x51, 0x21, 0x5e} // 51 Q
,{0x00, 0x7f, 0x09, 0x19, 0x29, 0x46} // 52 R
,{0x00, 0x46, 0x49, 0x49, 0x49, 0x31} // 53 S
,{0x00, 0x01, 0x01, 0x7f, 0x01, 0x01} // 54 T
,{0x00, 0x3f, 0x40, 0x40, 0x40, 0x3f} // 55 U
,{0x00, 0x1f, 0x20, 0x40, 0x20, 0x1f} // 56 V
,{0x00, 0x3f, 0x40, 0x38, 0x40, 0x3f} // 57 W
,{0x00, 0x63, 0x14, 0x08, 0x14, 0x63} // 58 X
,{0x00, 0x07, 0x08, 0x70, 0x08, 0x07} // 59 Y
,{0x00, 0x61, 0x51, 0x49, 0x45, 0x43} // 5a Z
,{0x00, 0x00, 0x7f, 0x41, 0x41, 0x00} // 5b [
,{0x00, 0x02, 0x04, 0x08, 0x10, 0x20} // 5c \ //
,{0x00, 0x04, 0x02, 0x01, 0x02, 0x04} // 5e ^
,{0x00, 0x40, 0x40, 0x40, 0x40, 0x40} // 5f _
,{0x00, 0x00, 0x01, 0x02, 0x04, 0x00} // 60 `
,{0x00, 0x20, 0x54, 0x54, 0x54, 0x78} // 61 a
,{0x00, 0x7f, 0x48, 0x44, 0x44, 0x38} // 62 b
,{0x00, 0x38, 0x44, 0x44, 0x44, 0x20} // 63 c
,{0x00, 0x38, 0x44, 0x44, 0x48, 0x7f} // 64 d
,{0x00, 0x38, 0x54, 0x54, 0x54, 0x18} // 65 e
,{0x00, 0x08, 0x7e, 0x09, 0x01, 0x02} // 66 f
,{0x00, 0x0c, 0x52, 0x52, 0x52, 0x3e} // 67 g
,{0x00, 0x7f, 0x08, 0x04, 0x04, 0x78} // 68 h
,{0x00, 0x00, 0x44, 0x7d, 0x40, 0x00} // 69 i
,{0x00, 0x20, 0x40, 0x44, 0x3d, 0x00} // 6a j
,{0x00, 0x7f, 0x10, 0x28, 0x44, 0x00} // 6b k
,{0x00, 0x00, 0x41, 0x7f, 0x40, 0x00} // 6c l
,{0x00, 0x7c, 0x04, 0x18, 0x04, 0x78} // 6d m
,{0x00, 0x7c, 0x08, 0x04, 0x04, 0x78} // 6e n
,{0x00, 0x38, 0x44, 0x44, 0x44, 0x38} // 6f o
,{0x00, 0x7c, 0x14, 0x14, 0x14, 0x08} // 70 p
,{0x00, 0x08, 0x14, 0x14, 0x18, 0x7c} // 71 q
,{0x00, 0x7c, 0x08, 0x04, 0x04, 0x08} // 72 r
,{0x00, 0x48, 0x54, 0x54, 0x54, 0x20} // 73 s
,{0x00, 0x04, 0x3f, 0x44, 0x40, 0x20} // 74 t
,{0x00, 0x3c, 0x40, 0x40, 0x20, 0x7c} // 75 u
,{0x00, 0x1c, 0x20, 0x40, 0x20, 0x1c} // 76 v
,{0x00, 0x3c, 0x40, 0x30, 0x40, 0x3c} // 77 w
,{0x00, 0x44, 0x28, 0x10, 0x28, 0x44} // 78 x
,{0x00, 0x0c, 0x50, 0x50, 0x50, 0x3c} // 79 y
,{0x00, 0x44, 0x64, 0x54, 0x4c, 0x44} // 7a z
,{0x00, 0x00, 0x08, 0x36, 0x41, 0x00} // 7b {
,{0x00, 0x00, 0x00, 0x7f, 0x00, 0x00} // 7c |
,{0x00, 0x00, 0x41, 0x36, 0x08, 0x00} // 7d }
,{0x00, 0x10, 0x08, 0x08, 0x10, 0x08} // 7e ~
,{0x00, 0x78, 0x46, 0x41, 0x46, 0x78} // 7f (delete)
};

void LCD_write_byte(unsigned char dat, unsigned char command);
void LCD_init(void);
void LCD_init(void);
void LCD_set_XY(unsigned char X, unsigned char Y);
void LCD_clear(void);
void LCD_write_char(unsigned char c);
void LCD_write_String(unsigned char X,unsigned char Y,unsigned char *s);

void LCD_write_byte(unsigned char dat, unsigned char command)
{
   unsigned int i;
        // LCD_SCE = 0;                                  //5110片选有效,允许输入数据
   P2OUT &=~BIT4;
   if (command == 0)                          //写命令
        // LCD_DC = 0;
           P2OUT &=~BIT5;
   else // LCD_DC = 1;
           P2OUT |=BIT5;//写数据
   for  (i=0;i<8;i++)
   {
           CLK_L;//spi_clk=0;
                if((dat & 0x80)==0x80)
                {
                        Data_H;
                }
                else
                {
                        Data_L;
                }
                CLK_H; // spi_clk=1;
                dat=(dat<<1);
   }
   P2OUT |=BIT4;
}


void LCD_init(void)
  {
        P2OUT &=~BIT4;
          P1OUT &= ~BIT4;
          P1OUT |= BIT4;
    LCD_write_byte(0x21, 0);        // LCD模式设置:芯片活动,水平寻址,使用扩展指令
    LCD_write_byte(0xc8, 0);        // 设置液晶偏置电压
    LCD_write_byte(0x06, 0);        // 温度校正
    LCD_write_byte(0x13, 0);        // 1:48
    LCD_write_byte(0x20, 0);        // 使用基本命令,V=0,水平寻址
    LCD_clear();                   // 清屏
    LCD_write_byte(0x0c, 0);        // 设定显示模式,正常显示
    P2OUT |=BIT4;
  }

void LCD_set_XY(unsigned char X, unsigned char Y)
  {
      LCD_write_byte(0x80 | X, 0);        // X     行(横坐标)
          LCD_write_byte(0x40 | Y, 0);                  // column         列(纵坐标)
  }
/*------------------------------------------
//LCD_clear: LCD清屏函数
--------------------------------------------*/
void LCD_clear(void)
{
        unsigned char t;
        unsigned char k;
        LCD_set_XY(0,0);
        for(t=0;t<6;t++)
        {
                for(k=0;k<84;k++)
                {
                        LCD_write_byte(0x00,1);

                }
        }
}

void LCD_write_char(unsigned char c)
{
    unsigned char i;
         c-=0x20;                //ASCII码减去 0x20

    for (i=0; i<6; i++)
        LCD_write_byte(ASCII_6_8[c], 1);
}
void LCD_write_String(unsigned char X,unsigned char Y,unsigned char *s)
{
        LCD_set_XY(X,Y);
        while (*s)                          //等效*s!='\0'
        {
                LCD_write_char(*s);
                s++;
        }
}
static float speed;
static unsigned char display[10];
static unsigned char display2[10];
static unsigned int temp ;
static unsigned int distance=0;
static float Period;

static float Distance_km;
int main(void)
{
        volatile unsigned int i;
        unsigned char  lcd_buf[6][84];
        WDTCTL = WDTPW + WDTHOLD;                 // Stop watchdog timer
        P1DIR |= BIT0;                            // P1.0/LED Output
        P1OUT &= ~BIT0;                           // LED off

        if (CALBC1_8MHZ==0xFF)                                        // If calibration constant erased
        {
                while(1);                               // do not load, trap CPU!!
        }

        DCOCTL = 0;                               // Select lowest DCOx and MODx settings
        BCSCTL1 = CALBC1_8MHZ;                    // Set DCO to 8MHz
        DCOCTL = CALDCO_8MHZ;
        P1DIR &= ~BIT2;                        
        P1SEL |= BIT2;                          
        P2DIR &= ~BIT2;
        P2DIR &= ~BIT1;
        P2IES |=BIT2+BIT1;
        P2IE |=BIT2+BIT1;
        P1DIR |= BIT0;
        P1DIR|=BIT4|BIT5|BIT7;
        TA0CCTL1 = CAP + CM_3 + CCIE + SCS + CCIS_0;
        TA0CTL |= TASSEL_1 + MC_2 + TACLR;        // ACLK, Cont Mode; start timer
        Count = 0x0;
        First_Time = 0x01;
        P2OUT = 0x00;
        P2DIR  |=BIT5+BIT4 ;
        P1DIR  |=BIT4 ;
        _EINT();
        P1OUT &= ~BIT4;                           // Now with SPI signals initialized,
    P1OUT |= BIT4;                            // reset slave
    LCD_init();  //初始化LCD模块
           LCD_clear(); //清屏幕
           LCD_write_String(0,1,"Speed:");
           LCD_write_String(60,1,"km/h");
           LCD_write_String(0,3,"Dista:");

   while(1)
  {
           __bis_SR_register(LPM0_bits+GIE);   // Enter LPM0

      Period = REdge2 - REdge1;             // Calculate Period

     speed =  1.0362*(32768/Period)*3.6;
      memset(display,0,sizeof(display));
      sprintf((char*)display,"%4.1f",speed);
      LCD_write_String(36,1,"        ");
      LCD_write_String(36,1,display);
      LCD_write_String(60,1,"km/h");
      LCD_write_String(50,3,"        ");
      Distance_km=(float)distance*2.073656/1000.0;

      if(Distance_km<1)
      {
        LCD_write_String(34,3,"            ");
        Distance_km=Distance_km*1000;
        sprintf((char*)display2,"%d",(int)Distance_km);
        LCD_write_String(44,3,display2);

      }
      else
      {
         LCD_write_String(36,3,"          ");
       sprintf((char*)display2,"%6.3f",Distance_km);
        LCD_write_String(34,3,display2);
          LCD_write_String(72,3,"km");



      }

  }
}

// TA0_A1 Interrupt vector
#pragma vector = TIMER0_A1_VECTOR
__interrupt void TIMER0_A1_ISR (void)
{

        switch(__even_in_range(TA0IV,0x0A))
  {
      case  TA0IV_NONE: break;              // Vector  0:  No interrupt
      case  TA0IV_TACCR1:                   // Vector  2:  TACCR1 CCIFG
            // distance++;
        if (TA0CCTL1 & CCI)                 // Capture Input Pin Status
        {

          distance++;
            if (!Count)
            {
                   
                    REdge1 = TA0CCR1;
                Count++;
            }
            else
            {
                REdge2 = TA0CCR1;
                Count=0x0;


                __bic_SR_register_on_exit(LPM0_bits +GIE);  // Exit LPM0 on return to main
            }
            if (First_Time)
                First_Time = 0x0;
        }
        else
        {
            if(!First_Time)
            {
                FEdge = TA0CCR1;
            }
        }
        break;
      default:         break;
  }
}

#pragma vector=PORT2_VECTOR
__interrupt void PORT2 (void)
{
        unsigned int i;


        for(i=0;i<20000;i++);
        if(P2IFG&BIT1)
        {
                 distance=0;
                 while(!(P2IN&BIT1));

        }

        if(P2IFG&BIT2)
        {
                P1OUT=P1OUT^BIT0;
                 while(!(P2IN&BIT2));

        }
        P2IFG=0x00;
         __bic_SR_register_on_exit(LPM0_bits +GIE);  // Exit LPM0 on return to main




}


cesu.png (32.94 KB )

cesu.png

相关帖子

沙发
dirtwillfly| | 2015-6-23 17:27 | 只看该作者
感谢分享,请按照活动要求更改标题

使用特权

评论回复
板凳
qingfeng08|  楼主 | 2015-6-23 20:00 | 只看该作者
dirtwillfly 发表于 2015-6-23 17:27
感谢分享,请按照活动要求更改标题

已经修改好了。这个是连接 https://bbs.21ic.com/icview-976412-1-1.html

使用特权

评论回复
地板
FireRiver9| | 2015-6-24 14:28 | 只看该作者
赞一个

使用特权

评论回复
5
米尔豪斯| | 2015-6-24 15:22 | 只看该作者
mark,学习了

使用特权

评论回复
6
firstblood| | 2015-7-15 21:54 | 只看该作者
自行车测速的设计,重点是霍尔传感器信号的采集与处理的。

使用特权

评论回复
7
firstblood| | 2015-7-15 21:54 | 只看该作者
还一个就是信号的传输的也不能忽略的。

使用特权

评论回复
8
lwsn| | 2015-7-16 23:14 | 只看该作者
自行车测速的设计,重点是霍尔传感器信号的采集与处理的。

赞同,网上有卖山地车里程表的,就是这样的

使用特权

评论回复
9
smilingangel| | 2015-7-18 15:27 | 只看该作者
整个系统有两个按键,一个是距离清零按键,按下该按键可以将显示的距离清零,这样方便测量起始地和目的地的距离,另外一个按键是用于打开LCD的背光的。

使用特权

评论回复
10
beautify| | 2016-6-6 10:34 | 只看该作者
想咨询楼主几个问题,第一,你的霍尔传感器电路出来的信号不需要做处理吧,其次你的计算两次上升沿差值的时候没有考虑溢出的问题,实际当中可行吗?第二,我使用干簧管做出来的测速会出现速度值固定出现在0,4,7,11,14,18,22这些数当中,原因是不是没能及时运算完?感觉有点捋不清了。

使用特权

评论回复
11
mmbs| | 2016-6-7 22:29 | 只看该作者
这个测量还光电传感器的。

使用特权

评论回复
12
mmbs| | 2016-6-7 22:30 | 只看该作者
2553的成本比较低。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

3

主题

28

帖子

0

粉丝