超声波引脚 | 430单片机接线引脚 |
VCC | 5V/3.3V |
GND | GND |
Trig(控制端) | P2.5 |
Echo(接收端) | P2.4 |
Echo要接在有定时器输入捕获功能的引脚上,超声波测距的原理就是,当信号发出,某引脚为高电平,当信号碰到障碍物反射回来后,某引脚变为低电平,通过计算高电平持续的时间,再乘以声速除以2,就可以得到与障碍物的距离。
HC_SR04.c代码
#include "hc_sr.h"
/****************************************************
* P2.4:echoTA2.1
* P2.5:Trig
****************************************************/
void US_015_Init(void)
{
P2DIR |= BIT5;
P2OUT &=~ ( BIT4 + BIT5 );
P2DIR &=~BIT4;
P2SEL |= BIT4;
TA2CTL = TASSEL_2 +ID0+ MC_2 + TACLR + TAIE;
TA2CCTL1 = CM_1 + SCS +CAP + CCIE + CCIS_0;
}
void Hc_sr_Open(void) //生成一个持续至少10us的高电平
{
Trig1(1);//这里就是把P2.5置1,即P2OUT |= BIT5
__delay_cycles(12);
Trig1(0); //置0
}
unsigned int cap_new = 0; // 首次捕捉的ta0r值
unsigned int cap_old = 0; // 第二次捕捉的ta0r值
char cap_N = 0; // 溢出次数
char state = 0x00; // 状态
float cap_data ; // 距离值,u16
#pragma vector=TIMER2_A1_VECTOR
__interrupt void TIMER2_A1_ISR(void)
{
switch(__even_in_range(TA2IV,14))//采用这个range函数就是为了使switch函数效率高
{
case 0:break; // No interrupt
case 2:
state = TA2CCTL1 >> 14;//捕获比较器1
TA2CCTL1 &= ~CCIFG;//标志位清零
if( TA2CCTL1 & CM_1){//开始捕获高电平时间,上升沿触发
cap_new = TA2CCR1;
TA2CCTL1 &= ~CM_1;//清除上升沿触发
TA2CCTL1 |= CM_2;//下降沿触发
}else if ( TA2CCTL1 & CM_2)
{
cap_old = TA2CCR1;
cap_data =(float)( ( cap_old - cap_new ) * 34/50/1.8/11);//此处为距离计算公式,但常规公式显示的结果并不正确,这个算是凑出来的,但是结果挺精确,我也不知道呜呜
TA2CCTL1 &= ~CM_2;
TA2CCTL1 |= CM_1;
}
else;
break;
// CCR1 not used
case 4: break; // CCR2 not used
case 6: break;
case 8: break; // reserved
case 10: break; // reserved
case 12: break; // reserved
case 14:
TA2CTL &= ~TAIFG;//清除溢出标志位
if(cap_old < cap_new ){
cap_N += 1;
}
break; // overflow
default: break;
}
}
HC_SR04.h端代码
#ifndef HC_SR_H_
#define HC_SR_H_
#include<msp430.h>
#include"type.h"
#define Trig1(a) if(a==1) P2OUT |= BIT5; else P2OUT &= ~BIT5
void US_015_Init(void);
void Hc_sr_Open(void); //生成一个持续至少10us的高电平
#endif
type.h
#ifndef TYPE_H_
#define TYPE_H_
#define u32 unsigned int
#define u16 unsigned short
#define u8 unsigned char
#endif /* TYPE_H_ */
main.c 在OLED上显示与障碍物的距离
#include <msp430.h>
#include "OLED.h"
#include <stdio.h>
#include <string.h>
#include "hc_sr.h"
extern char control;
extern float cap_data;
float cap_buf[100];
int main( void )
{
// Stop watchdog timer to prevent time out reset
WDTCTL = WDTPW + WDTHOLD;
OLED_Init();
OLED_Clear();
US_015_Init();
while(1){
Hc_sr_Open();
sprintf((char *)cap_buf, "dis:%.1f",cap_data);
OLED_ShowString(1,2, (u8*)cap_buf);//8*16
}
}
此篇博客还有很多瑕疵,苦于元器件不在身边,等开学去研究一下再来完善!