STM32 避障小车 —— HC-SR04

本文介绍制作过程中用到的 HC-SR04 模块

实物图片
file
电气参数
file
工作原理
  1. 采用 IO 触发测距,给至少 10us 的高电平信号;
  2. 模块自动发送 8 个 40KHz 的方波,自动检测是否有信号返回;
  3. 有信号返回,通过 I0 输出一高电平,高电平持续的时间就是
  4. 超声波从发射到返回的时间,测试距离 = ( 高电平时间*声速 ) / 2;
与单片机连接

Vcc -> 5V
Trig -> PB8
Echo -> PB8
Gnd -> G

程序部分

HC-SR04.h

#ifndef __HCSR04_H
#define __HCSR04_H

#include <stm32f10x.h>
#include <delay.h>

// 硬件连接不同可在此处修改
#define HCSR04_PORT        GPIOB
#define HCSR04_CLK     RCC_APB2Periph_GPIOB
#define HCSR04_TRIG        GPIO_Pin_8
#define HCSR04_ECHO        GPIO_Pin_7

#define uint unsigned int
void HC_SR04_Init(void);
float Count_Dist(void);

#endif /*__HCSR04_H*/

HC-SR04.c

#include <HC-SR04.h>

//1.采用 IO 触发测距,给至少 10us 的高电平信号;
//2.模块自动发送 8 个 40KHz 的方波,自动检测是否有信号返回;
//3.有信号返回,通过 I0 输出一高电平,高电平持续的时间就是
//4.超声波从发射到返回的时间,测试距离 = ( 高电平时间*声速 ) / 2;

//记录定时器溢出次数
uint count = 0;

//设置中断优先级
void NVIC_Config(void){

        NVIC_InitTypeDef NVIC_InitStructer;

        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

        NVIC_InitStructer.NVIC_IRQChannelPreemptionPriority = 0;
        NVIC_InitStructer.NVIC_IRQChannelSubPriority = 0;   
        NVIC_InitStructer.NVIC_IRQChannelCmd = ENABLE;
        NVIC_InitStructer.NVIC_IRQChannel = TIM2_IRQn;

        NVIC_Init(&NVIC_InitStructer);

}

/*初始化HC-SR04的GPIO以及定时器TIM2*/
void HC_SR04_Init(void){

        GPIO_InitTypeDef GPIO_InitStructer;
        TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructer;

        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

        /*TRIG 触发信号 PB8*/
        GPIO_InitStructer.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructer.GPIO_Mode = GPIO_Mode_Out_PP;  //设置为推挽输出
        GPIO_InitStructer.GPIO_Pin = HCSR04_TRIG;
        GPIO_Init(HCSR04_PORT, &GPIO_InitStructer);

        /*ECOH 回响信号 PB7*/
        GPIO_InitStructer.GPIO_Mode = GPIO_Mode_IN_FLOATING;  //设置为浮空输入
        GPIO_InitStructer.GPIO_Pin = HCSR04_ECHO;
        GPIO_Init(HCSR04_PORT, &GPIO_InitStructer);

        /*定时器 TIM2 初始化*/
        TIM_DeInit(TIM2);
        TIM_TimeBaseInitStructer.TIM_Period = 999;  //定时周期为1000
        TIM_TimeBaseInitStructer.TIM_Prescaler = 71;  //分频系数72
        TIM_TimeBaseInitStructer.TIM_ClockDivision = TIM_CKD_DIV1;  //不分频
        TIM_TimeBaseInitStructer.TIM_CounterMode = TIM_CounterMode_Up;
        TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructer);

        TIM_ClearFlag(TIM2, TIM_FLAG_Update);  // Clears the TIMx's pending flags.
        TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);  // Enables or disables the specified TIM interrupts.
        NVIC_Config();
        TIM_Cmd(TIM2, DISABLE);  //关闭定时器使能

}

float Count_Dist(void){
        float distance = 0, sum = 0;
        uint16_t time;
        uint i = 0;
        delay_init();  //在 delay.h 中
        while(i < 5){
                GPIO_SetBits(HCSR04_PORT, HCSR04_TRIG);
                delay_us(20);
                GPIO_ResetBits(HCSR04_PORT, HCSR04_TRIG);

                while(GPIO_ReadInputDataBit(HCSR04_PORT, HCSR04_ECHO) == 0);
                TIM_Cmd(TIM2, ENABLE);  //打开定时器
                i += 1;
                while(GPIO_ReadInputDataBit(HCSR04_PORT, HCSR04_ECHO) == 1);  //回响信号消失
                TIM_Cmd(TIM2,DISABLE);  //关闭定时器

                time = TIM_GetCounter(TIM2);  //获取 TIM2 计数值

                distance = (time + count*1000)/58.0;  //通过回响信号计算距离
                sum = distance + sum;  //将五次结果相加

                TIM2->CNT = 0;  //将TIM2计数寄存器的计数值清零
                count = 0;  //中断溢出次数清零
                delay_ms(10);
        }       
        distance = sum/5;  //取5次的平均值
        return distance;
}

void TIM2_IRQHandler(void) {  //中断函数
        if(TIM_GetITStatus(TIM2,TIM_IT_Update) != RESET) {
                TIM_ClearITPendingBit(TIM2, TIM_IT_Update);  //清除中断标志
                count++;
        }
}

代码讲解

关于distance = (time + count*1000)/58.0;

这个我最开始也没有搞懂,后来认真想了下明白了:声音在空气中的传播速度约为 343m/s,也就是 34300cm/s. 又因为 1s = 1000000us,可以得到声音的传播速度是 0.0343cm/us. 所以我们可以得到声音传播 1cm 所需要的时间约为 29.154us. 我们设接收到的时间为 n(us),是两倍的时间,那单程的时间就是 n/2(us). 就可以得到单程距离是 n/(2*29.154) = n/58.3 也就是我们用来计算的公式。

文章相关

上一篇:STM32 避障小车 —— L298N
下一篇:STM32 避障小车 —— SG90

  • 8
    点赞
  • 66
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值