打印

【MCU方案】MSP430G2553制作的自行车测度系统

[复制链接]
2601|27
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 qingfeng08 于 2015-6-30 11:42 编辑

                                                                        MSP430G2553制作的自行车测度系统
一,功能介绍:
                  本系统主要用于安装在自行车上测量自行车的运行速度和行驶距离。然后将速度和距离信息显示在显示在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                                                                                                        //液晶屏列宽度



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

}



1223.png (33.59 KB )

1223.png

相关帖子

沙发
dirtwillfly| | 2015-6-23 21:18 | 只看该作者
good!

使用特权

评论回复
板凳
冰河w| | 2015-6-24 12:50 | 只看该作者
楼主这个实现了吗,我正在找这方面的资料呢,刚好

使用特权

评论回复
地板
lwsn| | 2015-6-24 16:05 | 只看该作者
赞一个,21ic的大神很多啊

使用特权

评论回复
5
qingfeng08|  楼主 | 2015-6-25 11:46 | 只看该作者
本帖最后由 qingfeng08 于 2015-6-25 11:48 编辑
冰河w 发表于 2015-6-24 12:50
楼主这个实现了吗,我正在找这方面的资料呢,刚好

实现了,下面是实物图,因为是自己做的,所以没画pcb,用的的万用板焊接的
   
              图1                                                                  图2
图1第一行显示的是速度,第二行显示的距离,一个按键用于背光开/关,另外一个按键用于距离清零。
图2 是安装在轮子上的霍尔传感器和磁铁,磁铁在辐条上安装着,是那个红色的“复原乳”里面包裹着呢。






使用特权

评论回复
6
JY-DX-JY| | 2015-6-25 16:41 | 只看该作者
厉害。

使用特权

评论回复
7
292351696| | 2015-6-26 22:00 | 只看该作者
怎么我程序调试的时候出现错误的啊?兄弟能帮忙看一下吗?

)V[QLHM[Q0~M{M17HGGWPXF.png (143.51 KB )

)V[QLHM[Q0~M{M17HGGWPXF.png

)XPUJ2~4}FV6P8}8V5U5[79.jpg (425.42 KB )

)XPUJ2~4}FV6P8}8V5U5[79.jpg

使用特权

评论回复
8
qingfeng08|  楼主 | 2015-6-28 14:58 | 只看该作者
本帖最后由 qingfeng08 于 2015-6-28 15:02 编辑
292351696 发表于 2015-6-26 22:00
怎么我程序调试的时候出现错误的啊?兄弟能帮忙看一下吗?你的那个ASCII_6_8是个一维数组还是二维数组?要是二维数组,应该写成aaa(ASCII_6_8[c],1)

cc.png (9.75 KB )

cc.png

使用特权

评论回复
9
qingfeng08|  楼主 | 2015-6-28 15:06 | 只看该作者
292351696 发表于 2015-6-26 22:00
怎么我程序调试的时候出现错误的啊?兄弟能帮忙看一下吗?

你的那个ASCII_6_8是个一维数组还是二维数组?要是二维数组,应该写成下面的格式

使用特权

评论回复
10
qingfeng08|  楼主 | 2015-6-28 15:12 | 只看该作者
292351696 发表于 2015-6-26 22:00
怎么我程序调试的时候出现错误的啊?兄弟能帮忙看一下吗?

不好意思,这个网页做的有问题,不能输入二维数组,刚才发现了,我在下面给你回复二维数组,只能输入一维数组,后面的第二个参数就被网站屏蔽了,所以我给你截图了,看下面的图片。不好意思让你代码出错了。让你看下我的代码的截图

使用特权

评论回复
11
292351696| | 2015-6-29 11:19 | 只看该作者
qingfeng08 发表于 2015-6-28 15:12
不好意思,这个网页做的有问题,不能输入二维数组,刚才发现了,我在下面给你回复二维数组,只能输入一维 ...

程序改好了,谢谢啊,但是你的原理图怎么不太看的懂啊?如果我直接用launchpad来接线,是不是可以去掉那个 电源电路 了,还有你在原理图里都没有 显示屏 的接线的,显示屏的接线是不是看程序来接的?

使用特权

评论回复
12
292351696| | 2015-6-29 17:28 | 只看该作者
qingfeng08 发表于 2015-6-28 15:12
不好意思,这个网页做的有问题,不能输入二维数组,刚才发现了,我在下面给你回复二维数组,只能输入一维 ...

还有你用的是什么型号的霍尔传感器啊?

使用特权

评论回复
13
shenmu2012| | 2015-6-29 20:17 | 只看该作者
qingfeng08 发表于 2015-6-25 11:46
实现了,下面是实物图,因为是自己做的,所以没画pcb,用的的万用板焊接的
   
              图1         ...

这个做的非常不错的,,动手能力不错。

使用特权

评论回复
14
vivilzb1985| | 2015-6-29 20:31 | 只看该作者
这个是二维数组的啦。。

使用特权

评论回复
15
qingfeng08|  楼主 | 2015-6-30 11:09 | 只看该作者
本帖最后由 qingfeng08 于 2015-6-30 11:59 编辑
292351696 发表于 2015-6-29 11:19
程序改好了,谢谢啊,但是你的原理图怎么不太看的懂啊?如果我直接用launchpad来接线,是不是可以去掉那 ...

不好意思,LCD显示屏我没往原理图上画,接口这样的 :
DC  P2.5
SCE  P2.4
CLK  P1.5
Data  P1.7
RST  P1.4Black P1.0 (背光)
要是launchpad,就不用原理图上的电源那块了。要是2节干电池供电也可以不用那个稳压芯片,直接供电。我第一次用的是3.7v的充电电池供电的,所以用了一个3.3v的稳压芯片。后来改成干电池了就没用到那个稳压芯片。我回头修改下原理图,这个是我第一版的图。

使用特权

评论回复
16
292351696| | 2015-6-30 11:42 | 只看该作者
qingfeng08 发表于 2015-6-30 11:09
不好意思,LCD显示屏我没往原理图上画,接口这样的 :
DC  P2.5
SCE  P2.4

如果你有详细的原理图和PCB图的话,请给一份来看看,最好是有元件清单292351696@qq.com

使用特权

评论回复
17
qingfeng08|  楼主 | 2015-6-30 11:53 | 只看该作者
本帖最后由 qingfeng08 于 2015-6-30 11:55 编辑
292351696 发表于 2015-6-29 17:28
还有你用的是什么型号的霍尔传感器啊?

我买的是那种模块,直接在上面把比较器做好了,这样也方便430采集波形,也不是很贵。上面的型号是3144


使用特权

评论回复
18
gaoyang9992006| | 2015-6-30 16:34 | 只看该作者
这种户外应用不建议LCD,最好LED段码显示比较好。

使用特权

评论回复
19
292351696| | 2015-7-1 12:06 | 只看该作者
qingfeng08 发表于 2015-6-30 11:53
我买的是那种模块,直接在上面把比较器做好了,这样也方便430采集波形,也不是很贵。上面的型号是3144

谢谢啊,我也是买的这个传感器模块,等明天到货了,装上去试试看看,真的是太谢谢了

使用特权

评论回复
20
292351696| | 2015-7-3 19:03 | 只看该作者
今天元器件到了,我装了一下,发现好像不怎么得啊,有可能是我这个程序没有改好的好,有很多的感叹号的?请大神指导一下,这是我QQ292351696,加Q帮一下忙我

LBD4`}T~T(@)OJ7A]X1(`M0.png (73.57 KB )

LBD4`}T~T(@)OJ7A]X1(`M0.png

使用特权

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

本版积分规则

3

主题

28

帖子

0

粉丝