• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

STM32传感器外设集--声波模块HC_SR04

武飞扬头像
阿柒学起来
帮助1

目录

1.器件介绍

1.1.参数

1.2.测量范围

1.3.计算公式

1.4.优点

2.1.原理

3.代码编写

3.1.接线图

3.2.代码

3.2.1.HC_SR04.h

3.2.2.HC_SR04.c

3.2.3.timer.h

3.2.4.timer.c

 3.2.5.main.c


学新通

1.器件介绍

1.1.参数

  • 5根引脚
  • 工作电压5v
  • 工作电流15mA
  • 工作频率40Hz

1.2.测量范围

  • 最近距离 2cm
  • 最远距离 4m
  • 测量角度 15度

1.3.计算公式

测试距离=(高电平时间*声速(340M/S))/2

1.4.优点

  • 性能稳定
  • 测度距离精确
  • 模块高精度
  • 盲区小
  • 易于使用

2.使用原理

2.1.原理

使用stm32的定时器测量反射波的返回时间,再根据计算公式求出物体的相对距离,

3.代码编写

3.1.接线图

学新通

3.2.代码

3.2.1.HC_SR04.h

  1.  
    #ifndef __HC_SR04_H
  2.  
    #define __HC_SR04_H
  3.  
    #include "sys.h"
  4.  
     
  5.  
     
  6.  
    #define SR04_Trlg PBout(12)// PB12
  7.  
    #define SR04_Echo PBin(13)// PB13
  8.  
     
  9.  
    void HC_SR04_IO_Init(void);
  10.  
    u16 Get_SR04_Distance(void);
  11.  
     
  12.  
     
  13.  
     
  14.  
     
  15.  
    #endif
学新通

3.2.2.HC_SR04.c

  1.  
    #include "HC_SR04.h"
  2.  
    #include "timer.h"
  3.  
    #include "delay.h"
  4.  
     
  5.  
    //
  6.  
     
  7.  
    void HC_SR04_IO_Init(void)
  8.  
    {
  9.  
     
  10.  
    GPIO_InitTypeDef GPIO_InitStructure;
  11.  
     
  12.  
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能PB端口时钟
  13.  
     
  14.  
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; // 端口配置
  15.  
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //推挽输出
  16.  
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz
  17.  
    GPIO_Init(GPIOB, &GPIO_InitStructure); //根据设定参数初始化GPIOB.12
  18.  
     
  19.  
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; // 端口配置
  20.  
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  21.  
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz
  22.  
    GPIO_Init(GPIOB, &GPIO_InitStructure); //根据设定参数初始化GPIOB.13
  23.  
     
  24.  
    }
  25.  
     
  26.  
    u16 TIM2_UPDATA = 0;
  27.  
    u32 temp = 0;
  28.  
    u16 Get_SR04_Distance(void)
  29.  
    {
  30.  
     
  31.  
    SR04_Trlg=1; //触发信号是高电平脉冲,宽度大于10us
  32.  
    delay_us(20);
  33.  
    SR04_Trlg=0;
  34.  
    while(!SR04_Echo); //等待高电平
  35.  
    TIM_SetCounter(TIM2,0); //重填计数器值
  36.  
    TIM2_UPDATA = 0; //溢出次数清零
  37.  
    while(SR04_Echo); //等待低电平
  38.  
    TIM_Cmd(TIM2,DISABLE); //暂时关闭定时器,保证数据正确性
  39.  
    temp = (int)(((double)(TIM_GetCounter(TIM2) (7200* TIM2_UPDATA)))/72/2); //得到高电平总时间,单位us(定时器的计数值加上溢出的值才是高电平的时间),除以2是计算单程的时间
  40.  
    //7200* TIM2_UPDATA这里为溢出的时间us,可以转换为100* TIM2_UPDATA,因为在公式后面除以了72。可最终理解为TIM2_UPDATA个100us)
  41.  
    TIM_Cmd(TIM2,ENABLE);
  42.  
    return temp;
  43.  
    }
  44.  
     
  45.  
     
  46.  
     
学新通

3.2.3.timer.h

  1.  
    #ifndef __TIMER_H
  2.  
    #define __TIMER_H
  3.  
    #include "sys.h"
  4.  
     
  5.  
     
  6.  
    void TIM2_Init(u16 arr,u16 psc);
  7.  
     
  8.  
    #endif

3.2.4.timer.c

  1.  
    #include "timer.h"
  2.  
    #include "delay.h"
  3.  
    #include "sys.h"
  4.  
     
  5.  
     
  6.  
    void TIM2_Init(u16 arr,u16 psc)
  7.  
    {
  8.  
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
  9.  
    NVIC_InitTypeDef NVIC_InitStructure;
  10.  
     
  11.  
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //使能TIM2时钟
  12.  
     
  13.  
    //初始化定时器2
  14.  
    TIM_TimeBaseStructure.TIM_Period = arr; //设定计数器自动重装值
  15.  
    TIM_TimeBaseStructure.TIM_Prescaler =psc; //预分频器
  16.  
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
  17.  
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
  18.  
    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
  19.  
     
  20.  
     
  21.  
     
  22.  
    //中断分组初始化
  23.  
    NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; //TIM3中断
  24.  
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; //先占优先级2
  25.  
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //从优先级0
  26.  
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
  27.  
    NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
  28.  
     
  29.  
    TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);//允许更新中断 ,
  30.  
     
  31.  
    TIM_Cmd(TIM2,ENABLE ); //使能定时器2
  32.  
     
  33.  
    }
  34.  
    //定时器2中断服务程序 主要记录溢出次数
  35.  
     
  36.  
    extern u16 TIM2_UPDATA;
  37.  
    extern u8 state_machine;
  38.  
    void TIM2_IRQHandler(void)
  39.  
    {
  40.  
    if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) //检查指定的TIM中断发生与否:TIM 中断源
  41.  
    {
  42.  
    TIM2_UPDATA ;//当回响信号很长时,记录溢出次数,每加一次代表加100us
  43.  
    TIM_ClearITPendingBit(TIM2, TIM_IT_Update); //清除中断标志位
  44.  
    }
  45.  
    }
学新通

 3.2.5.main.c

  1.  
    int main(void)
  2.  
    {
  3.  
     
  4.  
    u16 time=0;
  5.  
    delay_init(); //延时函数初始化
  6.  
    uart_init(115200);
  7.  
    HC_SR04_IO_Init(); //超声波模块GPIO初始化
  8.  
    delay_ms(500); //上电瞬间加入一定延时在初始化
  9.  
    TIM2_Init(7199,0); //10KHz计数,定时100us
  10.  
    HC05_Role_Show();
  11.  
    delay_ms(100);
  12.  
    while(1)
  13.  
    {
  14.  
    time ;
  15.  
     
  16.  
    Distance = (Get_SR04_Distance() * 331) * 1.0/1000; //Get_SR04_Distance()返回单程声波传输时间 us,转换为秒=时间*10^(-6);331m/s等于331000mm/s,
  17.  
    //最终换算为Distance =Get_SR04_Distance()*10^(-6)*331000=(Get_SR04_Distance() * 331) * 1.0/1000;
  18.  
     
  19.  
    delay_ms(10);
  20.  
    if(time==300) {
  21.  
    printf("%.1f\n",Distance);
  22.  
    HC05_Sta_Show();
  23.  
    time=0;
  24.  
    }
  25.  
     
  26.  
    }
  27.  
     
  28.  
    }
学新通

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgcjhcj
系列文章
更多 icon
同类精品
更多 icon
继续加载