一、超声波介绍
利用TI公司的MSP430F5529单片机+超声波模块+OLED 实现
这里主要是利用单片机定时器的捕获功能来捕获超声波高电平持续时间,再计算得到距离,最后再在OLED 屏幕上显示出来,上图:
这里是把数字用了32号的,比较清晰,大家也可以自己更改
具体怎么接OLED 屏幕上一讲里面代码也有详细介绍,这里的超声波模块的Trig我接的是1.3,Echo接的是1.2
P1.2 为echo 设置为捕获模式
介绍:P1.2 具有端口中断的通用数字I / O ,TA0 CCR1捕获:CCI1A输入,比较:Out1输出 BSL接收输入
P1.3 为Trig 设置为 数字i/o模式
介绍:P1.3 具有端口中断的通用数字I / O , TA0 CCR2捕获:CCI2A输入,比较:Out2输出
二、部分代码
超声波模块初始化
void US_015_Init(void)
{
P1OUT &= ~( BIT2 + BIT3 );
P1DIR |= BIT3;
P1SEL |= BIT2;
TA0CTL = TASSEL__SMCLK + ID__8 + MC_2 + TACLR + TAIE;
TA0CCTL1 = CM_1 + SCS +CAP + CCIE + CCIS_0;
}
void Hc_sr_Open(void) //生成一个持续10us的高电平
{
Trig1(1);//这里就是把P1.2置1,即P1OUT |= BIT2
__delay_cycles(250);//这里我把系统时钟升为25MHZ,因此250/25000000=10us
Trig1(0);置0
}
我们选用的是P1.2, 根据端口定义,使用的是TA0CCR1,捕获输入引脚通过TA0CCTL1寄存器控制,捕获值存储在TA0CCR1中。
TASSEL(时钟源选择):SMCLK; ID分频(下面介绍):(这里分频系数会影响后面计算)4MHz/8 = 500k;计数模式:0 ==> 0xFFFF; 定时器清零位 ;中断使能。
TA0CCTL1:上升沿捕获 ;同步捕捉;捕获模式;中断使能;CCI1A输入。
(这里查了一下SCS和CAP都有两种模式,但是这里直接就是把寄存器代码搞上去,没有分出0和1两种模式,这里搞不太懂,哪位大佬解惑解惑?)
这里ID分频有两种写法,但是总共有四种分频:
MC的四种模式:停止、增加模式、连续上升、增减模式
CM的四种模式:不捕获、上升沿捕获、下降沿捕获、上升下降都捕获
原理:这里其实就是复用P1.2口为捕获,通过P1.3发出一个10us的高电平给超声波TRIG口触发进行测距,模块内部就返回一个信号,P1.2就捕获一个返回的高电平持续时间,再计算得出距离
公式:s=高电平持续时间*声速340/2(因为上面分频采用了8分频,因此我下面计算就不用除以2)
定时中断函数:
#pragma vector=TIMER0_A1_VECTOR
__interrupt void TIMER0_A1_ISR(void)
{
switch(__even_in_range(TA0IV,14))//采用这个range函数就是为了使switch函数效率高
{
case 0:break; // No interrupt
case 2:
state = TA0CCTL1 >> 14;
TA0CCTL1 &= ~CCIFG;//标志位清零
if( TA0CCTL1 & CM_1){//开始捕获高电平时间
cap_new = TA0CCR1;
TA0CCTL1 &= ~CM_1;
TA0CCTL1 |= CM_2;
}else if ( TA0CCTL1 & CM_2){
cap_old = TA0CCR1;
cap_data = ( cap_old - cap_new ) * 0.34/10/6.25;//这里外面解释!
Gui_DrawFont_Num32(10,50,BLUE,GRAY0,cap_data/100);//显示数字
Gui_DrawFont_Num32(37,50,BLUE,GRAY0,cap_data/10%10);
Gui_DrawFont_Num32(64,50,BLUE,GRAY0,cap_data%10);
TA0CCTL1 &= ~CM_2;
TA0CCTL1 |= CM_1;
}else
break; // CCR1 not used
case 4: break; // CCR2 not used
case 6: break; // reserved
case 8: break; // reserved
case 10: break; // reserved
case 12: break; // reserved
case 14:
TA0CTL &= ~TAIFG;
if(cap_old < cap_new ){
cap_N += 1;
}
break; // overflow
default: break;
}
}
这里其实都挺好理解的,就是大家可能对那个cap_data计算不太理解,首先为什么不除以2,是因为上面分频系数为8,(如果改为4,那么就应该除以2了),具体我也是测试出来的,至于为啥我觉得可能是分频系数为4时分频后频率为1MHZ,这样分频速率是最为正确的,但是8分频后为500KHZ就影响了原有的,相当于除以2了,哪位大佬可以帮忙解答哈哈,MSP430F5529我研究不是很长哈哈。然后后面除以10是因为计算的结果是MM为单位,我这里是以CM为单位,因此除以10;除以6.25是因为我升的时钟频率为25MHZ,跟原先的定时器4MHZ不对应,因此要换算即25/4=6.25,因此除以6.25。
最后面主函数:
int main(void) {
WDTCTL = WDTPW | WDTHOLD; // stop watchdog timer
upVcc();//升压
timerup();//时钟频率升为25MHZ
Lcd_Init();
LCD_LED_SET;//通过IO控制背光亮
Lcd_Clear(WHITE); //清屏
Hc_sr_Init();
__bis_SR_register(GIE);//开启中断
Gui_DrawFont_GBK16(10,0,BLUE,GRAY0,"电子2班");
Gui_DrawFont_GBK16(10,20,BLUE,GRAY0,"Dis:");
Gui_DrawFont_GBK24(100,60,BLUE,GRAY0,"CM");
while(1){
Hc_sr_Open();
__delay_cycles(1000000);
}
}
对了,漏了一些声明
#define Trig1(a) if(a==1) P1OUT |= BIT3; else P1OUT &= ~BIT3
unsigned int cap_new = 0; // 首次捕捉的ta0r值
unsigned int cap_old = 0; // 第二次捕捉的ta0r值
char cap_N = 0; // 溢出次数
char state = 0x00; // 状态
u16 cap_data ; // 距离值,u16
三、总结
到这里你可能对超声波测距有一个概念了,但是不够,一定要亲自上手实验,多琢磨,不要贪图省事,这样对你没有好处。
其实这里无非就是对定时器的应用,然后一些测量结果可能会出现误差,这是无法避免的,但是大体上影响不大,如果你不追求高精度测距和长距离测距的话,那么超声波测距是很好的选择!
上一篇:基于MSP430F5529的三种点灯方式(基本、定时、外部中断)
下一篇:MSP430F5529之1.44寸OLED显示
推荐阅读最新更新时间:2024-11-17 10:42
设计资源 培训 开发板 精华推荐
- 【航顺训练营】航顺 HK32开发板
- C964086_TM7705数模转换芯片方案验证板
- EVAL-AD7722CB,使用 AD7722、16 位、195 KSPS Sigma Delta 模数转换器的评估板
- DC1053A-H,使用 LTC3526LBEDC-2、0.8 至 5.5 Vin、1.8/3.3/5 Vout @ 100mA 高效同步升压转换器的演示板
- DER-112 - 具有恒流输出的 20 W 和 30 W 升压转换器
- 基于STHV64SW高压开关矩阵的评估板,用于超声成像应用
- LM2902S多反馈带通滤波器典型应用电路
- 具有静音/待机功能的 Tda7265、25 +25W 立体声放大器的典型应用电路(立体声配置)
- 带SoC配置的BGM13P Blue Gecko蓝牙模块的典型应用
- PAM2306双路高效PWM降压DC-DC转换器的典型应用可调电压稳压器
- “最后50米”配送智能化大势所趋,写字楼里机器人忙
- Zenzic发布全球首个自动驾驶发展路图
- 福特将汽车变成移动影院? 新专利揭示汽车后挡板将装投影仪
- 本田将为未来车型配备传感安全套件,全方位保护驾驶员安全!
- 特拉华大学教授开发即时定位和地图构建算法
- Kalray发布新一代处理器MPPA3 aka Coolidge™ 适用于自动驾驶汽车应用
- 特斯拉加拿大研发中心制无阳极锂电池 90次循环后保持80%容量
- 迈矽科在IC China推出国内首款77GHz满足AEC Q100 Grade1车规温度要求的长距离(LRR)车载雷达芯片
- Triaxis技术开启汽车精密化新纪元
- R&S® NGM200系列电源提供提供全新功能,树立全新测试测量标准