超声波传感器测距实验430

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


#include "msp430x14x.h"  
#include "Config.h"           
#include "1602.c"   
#include "UART.h"
#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,count=0; 
/***************延时*******************************/   
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');  
  
  }  
}  
  
/**************初始化io口********************/  
void Init_IO()  
{  
  P2DIR = 0XFD;  
  P2OUT |= 0XFF;  
  P2IE |= BIT1;                               //打开P2端口中断  
  P2IES &=~BIT1;                              //设置为上升沿中断  
}  
  
/**************初始化定时器******************/  
void Init_Timer()  
{  
  TACTL|=TACLR+TASSEL_2+ID_3;                   //定时器A初始化   
}  
void InitTimerB()
{
  TBCTL=TBSSEL1+ID1+ID0+MC0+TBCLR;//选择1/8SMCLK 增计数 清除TAR
  TBCCTL0=CCIE;//CCR0中断允许 比较模式
  TBCCR0=10000;//时间间隔10ms
}
/************主函数**************************/  
//端口的初始化
void main( void )  
{  
    WDTCTL = WDTPW + WDTHOLD; 
    InitTimerB();//关闭开门狗  
   Clock_Init();                               //时钟初始化  
    Init_IO();  //初始化IO  
    Start_1602();  //打开1602  
    tim_data=0;cnt=0;dista_data=0;                
    delay(1000);  
    UART_Init();//间隔延迟  
    uchar string[] = "distance:";  
    LCD1602_write_str(0, 0, string);  
    _EINT();                                    //打开总中断  
    while(1)  
    {  
        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)
  {
    count=0;
    Print_float(dista_data_sum,2);
  }
  
}
/*****************************Config.h*******************/  
/********************************************************************
//DM430-L型最小系统板外部资源配置文件Config.h
//包含板载各个资源的硬件配置,如果用户使用过程中,对应的硬件发生了更改,可利用该头文件更改使用
//SD/MMC卡初始化硬件配置未包含
//调试环境:EW430 V5.30
//作者:www.avrgcc.com
//时间:2014.03.01
********************************************************************/
//延时函数,IAR自带,经常使用到
#define CPU_F ((double)8000000)   //外部高频晶振8MHZ
//#define CPU_F ((double)32768)   //外部低频晶振32.768KHZ
#define delay_us(x) __delay_cycles((long)(CPU_F*(double)x/1000000.0)) 
#define delay_ms(x) __delay_cycles((long)(CPU_F*(double)x/1000.0)) 

//自定义数据结构,方便使用
#define uchar unsigned char
#define uint  unsigned int
#define ulong unsigned long

//8个LED灯,连接在P6口,可通过断开电源停止使用,ADC使用时断开电源
#define LED8DIR         P6DIR
#define LED8            P6OUT                             //P6口接LED灯,8个

//4个独立按键连接在P10~P13
#define KeyPort         P1IN                              //独立键盘接在P10~P13

//串口波特率计算,当BRCLK=CPU_F时用下面的公式可以计算,否则要根据设置加入分频系数
#define baud           9600                                //设置波特率的大小
#define baud_setting   (uint)((ulong)CPU_F/((ulong)baud))  //波特率计算公式
#define baud_h         (uchar)(baud_setting>>8)            //提取高位
#define baud_l         (uchar)(baud_setting)               //低位

//RS485控制管脚,CTR用于控制RS485处于收或者发状态
#define RS485_CTR1      P5OUT |= BIT2;          //控制线置高,RS485发送状态
#define RS485_CTR0      P5OUT &= ~BIT2;         //控制线置低,RS485接收状态

//2.8寸TFT彩屏显示控制相关硬件配置
#define RS_CLR	        P5OUT &= ~BIT5           //RS置低
#define RS_SET	        P5OUT |=  BIT5           //RS置高

#define RW_CLR	        P5OUT &= ~BIT6           //RW置低
#define RW_SET	        P5OUT |=  BIT6           //RW置高

#define RD_CLR	        P5OUT &= ~BIT7           //E置低
#define RD_SET	        P5OUT |=  BIT7           //E置高

#define CS_CLR	        P5OUT &= ~BIT0            //CS置低
#define CS_SET	        P5OUT |=  BIT0            //CS置高

#define RST_CLR	        P5OUT &= ~BIT3            //RST置低
#define RST_SET	        P5OUT |=  BIT3            //RST置高

#define LE_CLR	        P5OUT &= ~BIT1            //LE置低
#define LE_SET	        P5OUT |=  BIT1            //LE置高

//2.8寸TFT彩屏触摸屏控制相关硬件配置
#define PEN_CLR	        P2OUT &= ~BIT0           //PEN置低,触碰触摸屏时,Penirq引脚由未触摸时的高电平变为低电平
#define PEN_SET	        P2OUT |=  BIT0           //PEN置高
#define PEN             (P2IN & 0x01)            //P2.0输入的值

#define TPDO_CLR	P2OUT &= ~BIT1           //TPDO置低
#define TPDO_SET	P2OUT |=  BIT1           //TPDO置高
#define TPDOUT          ((P2IN>>1)&0x01)         //P2.1输入的值

#define BUSY_CLR	P2OUT &= ~BIT3           //BUSY置低
#define BUSY_SET	P2OUT |=  BIT3           //BUSY置高

#define TPDI_CLR	P2OUT &= ~BIT4            //TPDI置低
#define TPDI_SET	P2OUT |=  BIT4            //TPDI置高

#define TPCS_CLR	P2OUT &= ~BIT5            //TPCS置低
#define TPCS_SET	P2OUT |=  BIT5            //TPCS置高

#define TPCLK_CLR	P2OUT &= ~BIT6            //TPCLK置低
#define TPCLK_SET	P2OUT |=  BIT6            //TPCLK置高

//彩屏/12864液晶/1602液晶的数据口,三液晶共用
#define DataDIR         P4DIR                     //数据口方向
#define DataPort        P4OUT                     //P4口为数据口

//12864/1602液晶控制管脚
#define RS_CLR	        P5OUT &= ~BIT5           //RS置低
#define RS_SET	        P5OUT |=  BIT5           //RS置高

#define RW_CLR	        P5OUT &= ~BIT6           //RW置低
#define RW_SET	        P5OUT |=  BIT6           //RW置高

#define EN_CLR	        P5OUT &= ~BIT7           //E置低
#define EN_SET	        P5OUT |=  BIT7           //E置高

#define PSB_CLR	        P5OUT &= ~BIT0            //PSB置低,串口方式
#define PSB_SET	        P5OUT |=  BIT0            //PSB置高,并口方式

#define RST_CLR	        P5OUT &= ~BIT1            //RST置低
#define RST_SET	        P5OUT |= BIT1             //RST置高

//12864应用指令集
#define CLEAR_SCREEN	0x01		          //清屏指令:清屏且AC值为00H
#define AC_INIT		0x02		          //将AC设置为00H。且游标移到原点位置
#define CURSE_ADD	0x06		          //设定游标移到方向及图像整体移动方向(默认游标右移,图像整体不动)
#define FUN_MODE	0x30		          //工作模式:8位基本指令集
#define DISPLAY_ON	0x0c		          //显示开,显示游标,且游标位置反白
#define DISPLAY_OFF	0x08		          //显示关
#define CURSE_DIR	0x14		          //游标向右移动:AC=AC+1
#define SET_CG_AC	0x40		          //设置AC,范围为:00H~3FH
#define SET_DD_AC	0x80                      //设置DDRAM AC
#define FUN_MODEK	0x36		          //工作模式:8位扩展指令集

//颜色代码,TFT显示用
#define White          0xFFFF           													//显示颜色代码
#define Black          0x0000
#define Blue           0x001F
#define Blue2          0x051F
#define Red            0xF800
#define Magenta        0xF81F
#define Green          0x07E0
#define Cyan           0x7FFF
#define Yellow         0xFFE0

//NRF2401模块控制线
#define  RF24L01_CE_0        P1OUT &=~BIT5         //CE在P15         
#define  RF24L01_CE_1        P1OUT |= BIT5        

#define  RF24L01_CSN_0       P2OUT &=~BIT7         //CS在P27
#define  RF24L01_CSN_1       P2OUT |= BIT7     

#define  RF24L01_SCK_0       P3OUT &=~BIT3         //SCK在P33
#define  RF24L01_SCK_1       P3OUT |= BIT3   

#define  RF24L01_MISO_0      P3OUT &=~BIT2         //MISO在P32
#define  RF24L01_MISO_1      P3OUT |= BIT2

#define  RF24L01_MOSI_0      P3OUT &=~BIT1         //MOSI在P31
#define  RF24L01_MOSI_1      P3OUT |= BIT1

#define  RF24L01_IRQ_0       P1OUT &=~BIT4         //IRQ在P14     
#define  RF24L01_IRQ_1       P1OUT |= BIT4

//DS18B20控制脚,单脚控制
#define DQ_IN	        P1DIR &= ~BIT7		  //设置输入,DS18B20接单片机P53口
#define DQ_OUT	        P1DIR |= BIT7		  //设置输出
#define DQ_CLR	        P1OUT &= ~BIT7	          //置低电平
#define DQ_SET	        P1OUT |= BIT7	          //置高电平
#define DQ_R	        P1IN & BIT7		  //读电平

//红外接收头H1838控制脚,单脚控制
#define RED_IN	        P1DIR &= ~BIT6	          //设置输入,红外接收头接单片机PE3口
#define RED_OUT	        P1DIR |=  BIT6	          //设置输出
#define RED_L	        P1OUT &= ~BIT6	          //置低电平
#define RED_H	        P1OUT |= BIT6             //置高电平
#define RED_R	        (P1IN & BIT6)	          //读电平

//***********************************************************************
//                   系统时钟初始化,外部8M晶振
//***********************************************************************
void Clock_Init()
{
  uchar i;
  BCSCTL1&=~XT2OFF;                 //打开XT2振荡器
  BCSCTL2|=SELM1+SELS;              //MCLK为8MHZ,SMCLK为8MHZ
  do{
    IFG1&=~OFIFG;                   //清楚振荡器错误标志
    for(i=0;i<100;i++)
       _NOP();
  }
  while((IFG1&OFIFG)!=0);           //如果标志位1,则继续循环等待
  IFG1&=~OFIFG; 
}

//***********************************************************************
//                   系统时钟初始化,内部RC晶振
//***********************************************************************
void Clock_Init_Inc()
{
  uchar i;
  
 // DCOCTL = DCO0 + DCO1 + DCO2;              // Max DCO
 // BCSCTL1 = RSEL0 + RSEL1 + RSEL2;          // XT2on, max RSEL
  
  DCOCTL = 0x60 + 0x00;                       //DCO约3MHZ,3030KHZ
  BCSCTL1 = DIVA_0 + 0x07;
  BCSCTL2 = SELM_2 + DIVM_0 + SELS + DIVS_0;
}

//***********************************************************************
//                   系统时钟初始化,外部32.768K晶振
//***********************************************************************
void Clock_Init_Ex32768()
{
  uchar i;

  BCSCTL2|=SELM1 + SELM0 + SELS;    //MCLK为32.768KHZ,SMCLK为8MHZ
  do{
    IFG1&=~OFIFG;                   //清楚振荡器错误标志
    for(i=0;i<100;i++)
       _NOP();
  }
  while((IFG1&OFIFG)!=0);           //如果标志位1,则继续循环等待
  IFG1&=~OFIFG; 
}

//***********************************************************************
//               MSP430内部看门狗初始化
//***********************************************************************
void WDT_Init()
{
   WDTCTL = WDTPW + WDTHOLD;       //关闭看门狗
}




/*****************************1602.c*******************/ 
#include <msp430x14x.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??p3.4 p3.5
  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


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值