超声波传感器测距实验

来源:互联网 发布:java web工作流开发 编辑:程序博客网 时间:2024/05/14 19:06

  本实验是基于MSP430利用HC-SR04超声波传感器进行测距,测距范围是3-65cm,讲得到的数据显示在LCD 1602液晶屏上。

 

模块工作原理如下

(1)采用 IO 触发测距,给至少 10us 的高电平信号;

(2)模块自动发送 8  40khz 的方波,自动检测是否有信号返回;

(3)有信号返回,通过 IO 输出一高电平,高电平持续的时间就是超声波从发射到返回的时间

(4计算测试距离测试距离=(高电平时间*声速(340M/S))/2;

 

根据工作原理,我们可以选择两种模式驱动

1.       采用中断+定时器方式,ECHO定义为上升沿下降沿都能触发中断,trig触发之后,echo高电平进中断打开定时器,echo低电平关闭定时器并统计定时器计数值

2.       采用普通IO+定时器模式,触发之后等待echo响应,响应时打开定时器,直到echo恢复低关闭定时器,获取时间

此处我采用的是第一种模式,利用MSP430的timerA 的捕获比较模式,在程序的中断中处理得到的数据,并转化成距离。

 

1:此模块不宜带电连接,如果要带电连接,则先让模块的 Gnd 端先连接。否则会影响

模块工作。

2:测距时,被测物体的面积不少于0.5平方米且要尽量平整。否则会影响测试结果。在下载程序的时候建议将连接echo的一端断开,避免出现不必要的问题。


/**********************************************************代码***************************************************/

//功能说明:1602显示 超声波模块测距   串口发送至上位机
#include <msp430x14x.h> #include "Config.h" #include "1602.c"        #include "UART.h"int count = 0;int flag = 0;#define uchar unsigned char  #define uint unsigned int  /***************????*******************************/   #define trig_H P2OUT|=BIT0 //????  #define trig_L P2OUT&=~BIT0  #define echo P2IN & BIT1 //????    uint cnt;  unsigned long int tim_data,dista_data,dista_data_all,dista_data_sum;   /***************??*******************************/   void delay(uint n)  {     uchar i;    for(;n>0;n--)    for(i=10;i>0;i--);  }  /********************??,????????***************/   void dista_f(unsigned long int distance_data)  {    dista_data_all=dista_data_all+distance_data;    cnt=cnt+1;    if(cnt==16)     {      cnt=0;      dista_data_sum=dista_data_all>>4;      dista_data_all=0;        LCD1602_write_double(13,1,dista_data_sum);   //?1602?????        LCD1602_write_char(14,1,'m');        LCD1602_write_char(15,1,'m');      //Print_float(dista_data_sum, 2);  }  }    /**************???io?********************/  void Init_IO()  {    P2DIR = 0XFD;    P2OUT |= 0XFF;    P2IE |= BIT1;                               //??P2????    P2IES &=~BIT1;                              //????????  }    /**************??????******************/  void Init_Timer()  {    TACTL|=TACLR+TASSEL_2+ID_3;                   //???A???    //TACTL |= TASSEL1 + TACLR + ID0 + ID1 + MC0 + TAIE;  //TACCR0 = 9999;}  void InitTimerB(){  TBCTL=TBSSEL1+ID1+ID0+MC0+TBCLR;//选择1/8SMCLK 增计数 清除TAR  TBCCTL0=CCIE;//CCR0中断允许 比较模式  TBCCR0=10000;//时间间隔10ms}/************???**************************/  void main( void )  {          WDTCTL = WDTPW + WDTHOLD;                   //?????      Clock_Init();    InitTimerB();     Init_IO();     UART_Init();    Start_1602();                                //??1602      tim_data=0;cnt=0;dista_data=0;                    delay(1000);   //????      uchar string[] = "distance:";      LCD1602_write_str(0, 0, string);        _EINT();                                    //?????      while(1)      {          /*if(flag == 1)        {          Print_float(dista_data_sum, 2);          flag = 0;        }*/        trig_H;                                   //?????          delay(2);                                 //??15us          trig_L;                                   //?????          delay(50);                                //????          while(echo);                              //????          delay(1000);                              //????     }  }  /*****************************P2???*******************/  #pragma vector=PORT2_VECTOR  __interrupt void port_init(void)  {    if(echo)                                      //?????    {      TACTL|=TACLR+TASSEL_2+ID_3;      TACTL|=MC_2;                                //?????,?????????       P2IES|=BIT1;                                //??P2??????    }    else                                          //?????    {      TACTL=0;                                    //????,????      TACTL|=TASSEL_2+ID_3;      P2IES&=~BIT1;                               //??P2??????           tim_data=TAR;                               //????      dista_data=(tim_data*1000/58);              //?????(??=us/58)         //dista_data=(tim_data*17/100);                 dista_f(dista_data);                        //??????    }    P2IFG&=~BIT1;                                 // P2???????  }  #pragma vector=TIMERB0_VECTOR__interrupt void TimerBINT(){  count++;  if(count>=300)  {    Print_float(dista_data_sum, 2);    //flag = 1;    count = 0;  }}


/*********************************clock.c**********************************/

//****************************************************//*************时钟源模块//****************************************************#include <msp430x14x.h>#include "config.h"#include "clock.h"/********************系统时钟初始化****************/void init_clk(void) //初始化系统时钟{  uchar i;  BCSCTL1 &=~XT2OFF; //打开XT2振荡器  BCSCTL2 |=SELM_2+SELS;    do    {      IFG1 &=~OFIFG; //清除错误标志      for(i=0;i<0xff;i++); //延时等待    }  while((IFG1 & OFIFG)!=0);  IFG1 &=~ OFIFG;}

/*******************************************1602.c***********************************/

#include <msp430x14x.h>#include "Config.h"#include "clock.h"#include "1602.h"//*************************************************************************//初始化IO口子程序//*************************************************************************void LCD1602Port_init(){P4SEL = 0x00;        P4DIR = 0xFF;                   //数据口输出模式        P5SEL = 0x00;        P5DIR|= BIT5 + BIT6 + BIT7;     //控制口设置为输出模式}//***********************************************************************//显示屏命令写入函数//***********************************************************************void LCD1602_write_com(unsigned char com) {RS_CLR;RW_CLR;EN_SET;DataPort = com;                 //命令写入端口delay_ms(5);EN_CLR;}//***********************************************************************//显示屏数据写入函数//***********************************************************************void LCD1602_write_data(unsigned char data) {RS_SET;RW_CLR;EN_SET;DataPort = data;                //数据写入端口delay_ms(5);EN_CLR;}//***********************************************************************//显示屏清空显示//***********************************************************************void LCD1602_clear(void) {LCD1602_write_com(0x01);            //清屏幕显示delay_ms(5);}//***********************************************************************//显示屏字符串写入函数//***********************************************************************void LCD1602_write_str(unsigned char x,unsigned char y,unsigned char *s) {    if (y == 0)     {    LCD1602_write_com(0x80 + x);        //第一行显示    }    else     {    LCD1602_write_com(0xC0 + x);        //第二行显示    }        while (*s)     {    LCD1602_write_data( *s);    s ++;    }}//***********************************************************************//显示屏单字符写入函数//***********************************************************************void LCD1602_write_char(unsigned char x,unsigned char y,unsigned char data) {    if (y == 0)     {    LCD1602_write_com(0x80 + x);        //第一行显示    }    else     {    LCD1602_write_com(0xC0 + x);        //第二行显示    }        LCD1602_write_data( data);  }//***********************************************************************//显示屏初始化函数//***********************************************************************void LCD1602_init(void) {    LCD1602_write_com(0x38);//显示模式设置      delay_ms(5);    LCD1602_write_com(0x08);//显示关闭    delay_ms(5);    LCD1602_write_com(0x01);//显示清屏    delay_ms(5);    LCD1602_write_com(0x06);//显示光标移动设置    delay_ms(5);    LCD1602_write_com(0x0C);//显示开及光标设置    delay_ms(5);}void LCD1602_write_double(unsigned char x,unsigned char y,unsigned int data){  uchar i;      for(i=0;i<6;i++)    {      if(i==2)      LCD1602_write_char( x--, y, '.');      else      {          LCD1602_write_char( x--, y, 0x30+data%10);        data=data/10;      }    }}void LCD1602_write_int(unsigned char x,unsigned char y,unsigned int data){  uchar i;  for(i=0;i<2;i++)  {       LCD1602_write_char( x--, y, 0x30+data%10);      data=data/10;  }}void Start_1602(){    LCD1602Port_init();                //系统初始化,设置IO口属性    delay_ms(100);                     //延时100ms    LCD1602_init();                    //液晶参数初始化设置}

uart.h

#ifndef _UART_H_#define _UART_H_#include "msp430x14x.h"void Print_Str(uchar *s);//*************************************************************************//               MSP430?????//*************************************************************************void UART_Init(){  U0CTL|=SWRST + CHAR;                //??SWRST,8?????  U0TCTL|=SSEL1;                      //SMCLK?????  U0BR1=baud_h;                       //BRCLK=8MHZ,Baud=BRCLK/N  U0BR0=baud_l;                       //N=UBR+(UxMCTL)/8  U0MCTL=0x00;                        //??????0,???9600bps  ME1|=UTXE0;                         //UART0????  ME1|=URXE0;                         //UART0????  U0CTL&=~SWRST;  IE1|=URXIE0;                        //???????    P3SEL|= BIT4 + BIT5;                //??IO????????,??UART??  P3DIR|= BIT4;                       //??TXD0??????}//*************************************************************************//              ??0??????//*************************************************************************void Send_Byte(uchar data){  while(!(IFG1&UTXIFG0));          //?????????????    U0TXBUF=data;}//***************************************//void Print_float(unsigned int  t, unsigned char position)//?????   position ???????{  unsigned int s_int[5] = {0};  int i = 0;  while(t>0)  {    s_int[i++] = t%10;    t=t/10;  }  for(i=4;i>=0;i--)    {      if(i==position)     {      Send_Byte(0x30 + s_int[i]);      Send_Byte(0x2E);      }    else      {          Send_Byte(0x30 + s_int[i]);       }    }  //delay_ms(100);  Send_Byte('m');  Send_Byte('m');  Send_Byte(' ');  delay_ms(100);}//*************************************************************************//              ??0??int???//*************************************************************************void Print_int(unsigned int  t){  unsigned int s_int[5];  unsigned int i = 1;  while(t>0)  {    s_int[i] = t%10;    t=t/10;    i++;  }    i--;    while(i)    {        Send_Byte(0x30 + s_int[i]);        i--;    }}//*************************************************************************//              ??0???????//*************************************************************************void Print_Str(uchar *s){    while(*s != '\0')    {        Send_Byte(*s++);    }}#endif


原创粉丝点击