打印

msp430超声波测距(msp430g2553,顶一呗)

[复制链接]
6372|19
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
xiaoliping1945|  楼主 | 2013-8-22 10:21 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 xiaoliping1945 于 2013-8-22 10:34 编辑

#include<msp430g2553.h>
#include"lcd1602.h"


unsigned char  table[]="0123456789";
unsigned int  result1_start,result1_end;
unsigned char index=0;
unsigned int  temp;
double   distance;
unsigned char name[]="the juli";
unsigned char juli_cm[]="000.0cm";

/*==================================TA的初始化设置=========================================
函数名称: void CAP_Init()
函数功能:定时器A捕获设置,用于捕获上升下降沿
函数参数:
=========================================================================================*/
void CloseWDTCTL()
{
    WDTCTL=WDTPW+WDTHOLD;
}
void ClockInit()
{
    BCSCTL1=CALBC1_1MHZ;
    DCOCTL=CALDCO_1MHZ;
}
void PortInit()
{
        P1DIR &=~BIT2;          //P1.2,为输入引脚
        P1SEL |= BIT2;   // P1.2 = (InputDirection + TA0.1) = CCIxA.1 --> CCR1,P1.2作为输入,CCI1A,指定输入
        P2DIR|=BIT0;
}
void Timer1Init()
{
        TACCTL1 = CAP + CCIS_0 + CM_3 + CCIE+SCS;     // Capture CCIxA, both edge, interrupt enable.CCI1A->p1.2
        TACTL |=TASSEL_2 + ID_0 + MC_2+ TAIE+TACLR ;//选择1M-SMCLK时钟,continuous mode
        TACCR1=0;
        //TACTL&=~CCIFG;
}
void send_15us()//超声波发送15us的高电平
{
         P2OUT&=~BIT0;
         delay_us(20);
         P2OUT|=BIT0;
         delay_us(15);
         P2OUT&=~BIT0;
}
void main(void)
{
        CloseWDTCTL();
        ClockInit();
        init_lcd();
        PortInit();
    Timer1Init();
    write_com(0x01) ;                     // 清屏
    lcd_1602(first,0,name);
        _EINT();
        // LPM0;                             //也可进入睡眠,下面的发送高电平,就先在睡眠前发一次,以后就在中断里面下降沿结束,以及数据处理完后再给它发,或者你干脆把TX接高电平好得很,一直发送,省事
    while(1)
    {
            send_15us();
            delay(100);
    }
}
/*==================================TA的中断服务程序=========================================
函数名称: Timer_AISR
函数功能: 定时器A中断服务子函数,捕获待测信号上升沿,下降沿
函数参数:这里注释下吧,CCR0单独的占用了个中断,好像是TIMER0_A0_VECTOR,其他的合着用,所以进入中断后要判断是CCR1,还是CCR2产生的中断,也就是TAOIV或者TA1IV对应case  :2 和4,另外如果你不访问TAIV这个寄存器,那你产生的一些标志位就要你手动的软件复位了,反之是硬件自己复位。由于捕获是硬件捕获的,测距比较准。
=========================================================================================*/
#pragma vector=TIMER0_A1_VECTOR

__interrupt void TAIV_ISR(void)
{

         switch(TA0IV)
                {
                 case 2:                    //ccr1中断向量
                         if (TACCTL1&CCI)    //上升沿触发
                                {
                                     result1_start=CCR1;//记录初始值
                                     index=0;
                                     break;
                                }
                         else
                           {
                                   unsigned juli;
                                          result1_end=CCR1;          //记录结束值
                                    if(result1_end>result1_start)//结果比开始数值肖,表示溢出了一次或者几次,但是一般从0开始计数的话是不溢出的,这超声波实际测不了那么远,最多有个4米,5米的样子已经很好了
                                                                               //TACTL|=TACLR;//这句貌似不需要
                                       temp=result1_end-result1_start;
                                    else
                                        temp=result1_end+index*65535-result1_start;
                                    distance=temp*0.0172;
                                    juli=distance*10+0.5;            //取一位小数,四舍五入
                                    juli_cm[0]=table[juli/1000];
                                    juli_cm[1]=table[juli%1000/100];
                                    juli_cm[2]=table[juli%100/10];
                                    juli_cm[4]=table[juli%10];
                                    lcd_1602(second,0,juli_cm);        //显示
                                    index=0;         //溢出清零
                                    break;
                           }
                 case 4: break;
                 case 10: index++;break;           //溢出中断向量,其实就2,4,10号向量有用那些手册里也没说,用不到
                 default :break;
                }
        // TACCTL1&=~COV;//有时候要这句,但是没用好像也行
}

/************************lcd1602串行显示头文件,需要74HC595或者164进行串转并才得行,自己在板子上焊一个座子,爽的很******************/
#ifndef LCD1602_H_
#define LCD1602_H_


#define CPU_F ((double)1000000)  //万能延时函数,修改这里的对应MCLK频率即可,如用CPU是8M的MCLK,你是就该为8000000吧
#define delay_us(x)   __delay_cycles((long)(CPU_F*(double)x/1000000.0))
#define delay(x)      __delay_cycles((long)(CPU_F*(double)x/1000.0))

#define uint  unsigned int
#define uchar unsigned char
//#define datadir P1DIR
//#define P1      P1OUT
#define Ctrl_data_Dir  P2DIR
#define  first  0x00
#define  second  0x40

#define ds_0  P2OUT&=~BIT3           //数据线
#define ds_1  P2OUT|=BIT3

#define rs_0 P2OUT&=~BIT5
#define rs_1 P2OUT|=BIT5

#define en_0 P2OUT&=~BIT4
#define en_1 P2OUT|=BIT4

#define rclk_0  P2OUT&=~BIT4
#define rclk_1  P2OUT|=BIT4

#define sclk_0  P2OUT&=~BIT5
#define sclk_1  P2OUT|=BIT5


void init_lcd();
void write_595(uchar date);
void write_com(uchar com) ;
void write_data(uchar date );
void lcd_1602(uchar x,uchar y ,uchar *p);
void zuoyi();               //从右往左整屏移动

void write_595(uchar date)
{
        uchar i;
        for(i=0;i<8;i++)
         {
          sclk_0;
          if(date&0x80)
                  ds_1;
          else
                  ds_0;
          delay(4);
          sclk_1;
          date<<=1;                 //sclk给一个上升沿脉冲即可读走一位
         }
}
/*-----------lcd写指令-------------------------------*/
void write_com(uchar com)
{
           write_595(com);
           rs_0;
           delay(3);
           //rw=0;
           rclk_1;
           delay(3);
           rclk_0;
}
/*-----------lcd写数据-------------------------------*/
void write_data(uchar date )
{
           write_595(date);                //写入数据
           rs_1;
           delay(3);
           rclk_1;
           delay_us(10);
           rclk_0;                                //令595输出,并用en输出一个高脉冲
}
void init_lcd()
{
         Ctrl_data_Dir|=0x38;         //定义的三个使能端为输出端
     en_0;
     delay(1);
     write_com(0x38);
       delay(3);
     write_com(0x38);
       delay(3);
     write_com(0x38);
       delay(3);
     write_com(0x0c);//开显示
       delay(3);
     write_com(0x06);
       delay(3);
    // write_com(0x01);//清屏
    //   delay(5);
}
void lcd_1602(uchar x,uchar y,uchar *p)//lcd第一行显示
{
           init_lcd();
           delay(5);
       //write_com(0x01);//清屏
           write_com(0x80+x+y);
           while(*p!='\0')
                  {
                    write_data(*p++);
                    delay(5);
                  }
}
void zuoyi()
{
          uchar num;
         for(num=0;num<16;num++)
                    {
                          write_com(0x18);//左移
                          delay(500);      //0.5秒移动一个
                        }
}

#endif /* LCD1602_H_ */
评分
参与人数 1威望 +2 收起 理由
地瓜patch + 2 赞一个!

相关帖子

沙发
地瓜patch| | 2013-8-22 10:57 | 只看该作者
顶一个贴

使用特权

评论回复
板凳
godblessxiang| | 2014-2-17 12:00 | 只看该作者
顶下,如果有详细的注解更加好

使用特权

评论回复
地板
veryjc| | 2014-2-20 15:24 | 只看该作者
顶一个

使用特权

评论回复
5
daocaorenchao| | 2014-2-21 11:08 | 只看该作者
顶一下...

使用特权

评论回复
6
yang958| | 2014-2-23 21:11 | 只看该作者
好东东,学习啦

使用特权

评论回复
7
mfketggo| | 2014-2-24 14:04 | 只看该作者
学习了  正好搞超声波测距

使用特权

评论回复
8
风中的雪| | 2014-2-26 13:51 | 只看该作者
不错!

使用特权

评论回复
9
hawkswing| | 2014-2-26 14:58 | 只看该作者
顶下,如果有详细的注解更加好

使用特权

评论回复
10
zhuhai126818| | 2014-5-7 10:45 | 只看该作者
好东西。

使用特权

评论回复
11
1160769413| | 2014-7-19 17:15 | 只看该作者
大神  顶一个

使用特权

评论回复
12
gyl94611| | 2014-7-24 13:06 | 只看该作者
顶一下

使用特权

评论回复
13
amidew3278| | 2014-7-25 10:41 | 只看该作者
谢谢 ,正在学习中

使用特权

评论回复
14
amidew3278| | 2014-7-25 14:11 | 只看该作者
程序提示有错误,connot open “LCD602.h”
怎么办?大家

使用特权

评论回复
15
ysjqq520| | 2014-8-9 07:37 | 只看该作者
不错!

使用特权

评论回复
16
21通行证| | 2014-8-13 10:53 | 只看该作者
好东西就要分享,怎么赚积分。

使用特权

评论回复
17
andsk88| | 2015-4-24 11:33 | 只看该作者
我根据楼主的代码,将1602显示改成了Nokia5110,现在显示出来.....cm  定时器A没有进入中断  我想知道问题出在哪里了  急急急,毕业设计
#include <msp430g2553.h>

#include<stdio.h>
#include<math.h>
unsigned int result1_start,result1_end;
unsigned char index=0;
unsigned int temp;
float distance;
unsigned char juli0_cm;
unsigned char juli1_cm;
unsigned char juli2_cm;
unsigned char juli4_cm;

unsigned char font6x8[][6] = {     
{0x00,0x00,0x60,0x60,0x00,0x00},//.(0)
{0x00,0x3E,0x51,0x49,0x45,0x3E},//0(1)
{0x00,0x00,0x42,0x7F,0x40,0x00},//1(2)
{0x00,0x42,0x61,0x51,0x49,0x46},//2(3)
{0x00,0x21,0x41,0x45,0x4B,0x31},//3(4)
{0x00,0x18,0x14,0x12,0x7F,0x10},//4(5)
{0x00,0x27,0x45,0x45,0x45,0x39},//5(6)
{0x00,0x3C,0x4A,0x49,0x49,0x30},//6(7)
{0x00,0x01,0x71,0x09,0x05,0x03},//7(8)
{0x00,0x36,0x49,0x49,0x49,0x36},//8(9)
{0x00,0x06,0x49,0x49,0x29,0x1E},//9(10)
{0x00,0x38,0x44,0x44,0x44,0x20},//c(11)
{0x00,0x7E,0x02,0x0C,0x02,0x7C},//m(12)
};
void CloseWDTCTL()
{
    WDTCTL=WDTPW+WDTHOLD;
}
void ClockInit()
{
  if (CALBC1_1MHZ ==0XFF || CALDCO_1MHZ == 0XFF)
  {  P1OUT = 0X01;   }
    BCSCTL1=CALBC1_1MHZ;
    DCOCTL=CALDCO_1MHZ;
}


void PortInit()
{
  P2DIR &=~BIT1;
  P2SEL |=BIT1;
  P2DIR |=BIT0;
}
void Timer1Init()
{
  TACCTL1=CAP+CCIS_0+CM_3+CCIE+SCS;
  TA1CTL|=TASSEL_2+ID_0+MC_2+TAIE+TACLR;
  TACCR1=0;
  TACTL &=~CCIFG;
}
void send_15us()
{
  P2OUT &=~BIT0;
  delay_nus(20);
  P2OUT |=BIT0;
  delay_nus(15);
  P2OUT &=~BIT0;
}


void main(void)
{
  CloseWDTCTL();
  P1DIR=0x7f;
  P1OUT=0;
  PortInit();
  ClockInit();
  delay_nms(200);

  LCD_Init();
  Timer1Init();
  display_char(1,1,juli0_cm);
  display_char(2,1,juli1_cm);
  display_char(3,1,juli2_cm);
  display_char(4,1,0x00);
  display_char(5,1,juli4_cm);
  display_char(6,1,0x0b);
  display_char(7,1,0x0c);
  _EINT();
  while(1)
  {
    send_15us();
     delay_nms(100);
  }
}
#pragma vector=TIMER1_A3_VECTOR
__interrupt void TAIV_ISR(void)
{
  switch(TAIV)
  {
  case 2:
    if(TACCTL1&CCI)
    {
      result1_start=CCR1;
      index=0;
      break;
    }
    else
    {
      unsigned int juli;
      result1_end=CCR1;
      if(result1_end>result1_start)
        temp=result1_end-result1_start;
      else
        temp=result1_end+index*65535-result1_start;
      distance=temp*340/10000/2;
      juli=distance*10+1/2;
      juli0_cm=juli/1000+0x01;
      juli1_cm=juli%1000/100+0x01;
      juli2_cm=juli%100/10+0x01;
      juli4_cm=juli%10+0x01;
      

      index=0;
      break;
    }
  case 10:index++;break;
  default:break;
  }
  TACCTL1 &=~COV;
}

使用特权

评论回复
18
13528418541| | 2015-5-24 11:50 | 只看该作者
非常感谢哈哈哈

使用特权

评论回复
19
xiaoliping1945|  楼主 | 2015-6-6 09:15 | 只看该作者
andsk88 发表于 2015-4-24 11:33
我根据楼主的代码,将1602显示改成了Nokia5110,现在显示出来.....cm  定时器A没有进入中断  我想知道问题 ...

不好意思,已经一年多没进论坛了,可能毕业设计你现在弄完了吧,哈哈

使用特权

评论回复
20
wang1jie| | 2015-10-4 11:35 | 只看该作者
:)顶下

使用特权

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

本版积分规则

11

主题

74

帖子

3

粉丝