c语言编程实现超声波测距项目实战

  本实验是基于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  #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;/***************??*******************************/voiddelay(uint n){uchar i;for(;n>0;n--)for(i=10;i>0;i--);}/********************??,????????***************/voiddista_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?********************/voidInit_IO(){P2DIR=0XFD;P2OUT|=0XFF;P2IE|=BIT1;//??P2????P2IES&=~BIT1;//????????}/**************??????******************/voidInit_Timer(){TACTL|=TACLR+TASSEL_2+ID_3;//???A???//TACTL |= TASSEL1 + TACLR + ID0 + ID1 + MC0 + TAIE;//TACCR0 = 9999;}voidInitTimerB(){TBCTL=TBSSEL1+ID1+ID0+MC0+TBCLR;//选择1/8SMCLK 增计数 清除TARTBCCTL0=CCIE;//CCR0中断允许 比较模式TBCCR0=10000;//时间间隔10ms}/************???**************************/voidmain(void){WDTCTL=WDTPW+WDTHOLD;//?????  Clock_Init();  InitTimerB();  Init_IO();  UART_Init();  Start_1602();//??1602tim_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);//??15ustrig_L;//?????  delay(50);//????while(echo);//????  delay(1000);//????}}/*****************************P2???*******************/#pragma vector=PORT2_VECTOR  __interruptvoidport_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  __interruptvoidTimerBINT(){count++;if(count>=300){  Print_float(dista_data_sum,2);//flag = 1;count=0;}}

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

  //*************时钟源模块

  //****************************************************

  #include

  #include "config.h"

  #include "clock.h"

  /********************系统时钟初始化****************/voidinit_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  #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"voidPrint_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;

  }

  //***************************************//voidPrint_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

  也欢迎进球球裙技术交流

点击链接加入群聊【嵌入式单片机Linux C交流群②】https://jq.qq.com/?_wv=1027&k=FW2qSMZ4

你可能感兴趣的:(c语言编程实现超声波测距项目实战)