基于stm32f10x的超声波模块HC-SR04的测距示例

2019-08-20来源: eefocus关键字:stm32f10x  超声波模块  HC-SR04  测距

一.所需材料:


1任何一种型号的stm32f10x的微控制器


2.HC-SR04模块


3.安装串口驱动与串口助手(这里用的火哥的串口调试助手)


4.ST-link或者串口等下载方式都可以


二。超声波原理


网上一大堆,这里我就大体说一下:单片机先给TRIG一个大于10us的高电平,然后模块ECHO引脚会发出一个高电平,检测高电平的时间乘声速便可算出距离。这里ECHO发出也接收,所以检测的时间,假设按秒算,然后乘170便是以m为单位的距离。


三.源代码分析


1.接口定义:


//由于只是用的定时器的基本计时功能,所以IO口随便找两个便可以

#define HCSR04_PORT              GPIOB

#define HCSR04_PORTC_CLK_FUN     RCC_APB2PeriphClockCmd

#define HCSR04_CLK               RCC_APB2Periph_GPIOB

#define HCSR04_TRIG              GPIO_Pin_11

#define HCSR04_ECHO              GPIO_Pin_10


2.驱动函数分析


//超声波计数,记录有几个更新中断,由于在.c文件中定义,中断函数中测试其值,故加个extern

extern u16 msHcCount = 0; 


//IO口初始化 TRIG为普通推挽输出,ECHO为浮空输入,

//配置时基结构体

void Hcsr04Init(void)

{  

    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;   

    GPIO_InitTypeDef GPIO_InitStructure;

    HCSR04_PORTC_CLK_FUN(HCSR04_CLK, ENABLE);

   

    GPIO_InitStructure.GPIO_Pin =HCSR04_TRIG;      

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

    GPIO_Init(HCSR04_PORT, &GPIO_InitStructure);

    GPIO_ResetBits(HCSR04_PORT,HCSR04_TRIG);

     

    GPIO_InitStructure.GPIO_Pin =   HCSR04_ECHO;     

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

    GPIO_Init(HCSR04_PORT, &GPIO_InitStructure);  

    GPIO_ResetBits(HCSR04_PORT,HCSR04_ECHO);    

     

          

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);   

     

    TIM_DeInit(TIM2);

    TIM_TimeBaseStructure.TIM_Period = (1000-1);         //定时器时钟1MHZ,自动重装载寄存器的值为1000, 也就是说满一次为1MS

    TIM_TimeBaseStructure.TIM_Prescaler =(72-1); 

    TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;

    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  

    TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);          

        

    TIM_ClearFlag(TIM4, TIM_FLAG_Update);  

    TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE);    

    hcsr04_NVIC();

    TIM_Cmd(TIM4,DISABLE);     

}


//中断配置,这里只用了一个中断,不用考虑中断嵌套等等,所以中断优先级以及次优先级可以随便配置,只用到了定时器update中断


void hcsr04_NVIC(void)

{

NVIC_InitTypeDef NVIC_InitStructure;

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);


NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;             

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;         

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;       

NVIC_Init(&NVIC_InitStructure);

}


//关闭定时器4

static void CloseTimerForHc(void)    

{

   TIM_Cmd(TIM4, DISABLE); 


//打开定时器4

static void OpenTimerForHc(void)  

{

   TIM_SetCounter(TIM4,0);

   msHcCount = 0;

   TIM_Cmd(TIM4, ENABLE); 

}

//获取定时器4计数器值,此值为更新中断的次数*1000+计数器的值

u32 GetEchoTimer(void)

{

   u32 t = 0;

   t = msHcCount*1000;

   t += TIM_GetCounter(TIM4);

   TIM4->CNT = 0;  

   Systick_DelayMs(50);

   return t;

}


//通过定时器4计数器值推算距离,单位厘米,假设测试值为x,距离y=x/1M*17000


//这里每测出5此求个平均值输出

float Hcsr04GetLength(void )

{

   u32 t = 0;

   int i = 0;

   float lengthTemp = 0;

   float sum = 0;

   while(i!=5)

   {

      GPIO_SetBits(HCSR04_PORT,HCSR04_TRIG);

      Systick_DelayUs(20);

      GPIO_ResetBits(HCSR04_PORT,HCSR04_TRIG);

      while(GPIO_ReadInputDataBit(HCSR04_PORT,HCSR04_ECHO)==RESET);

      OpenTimerForHc();

      i = i + 1;

      while(GPIO_ReadInputDataBit(HCSR04_PORT,HCSR04_ECHO)==SET);

      CloseTimerForHc();

      t = GetEchoTimer();

      lengthTemp = ((float)t*0.017);//cm

     

      sum = lengthTemp + sum ;

        

    }

    lengthTemp = sum/5.0;

    return lengthTemp;

}


 


3.主函数测试程序:


float length;

  //延时函数初始化

  Systick_DelayMs(10); //这里用的系统滴答定时器延时  

  hcsr04_NVIC(); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级

  

  USART_Config();//串口服务程序,这里我用的火哥的串口一

   Hcsr04Init();  


  while(1) 

  {  

     length = Hcsr04GetLength();

     printf("距离为:%.3fcmn",length);

     Systick_DelayMs(1000);

  }


 


四.效果图


关键字:stm32f10x  超声波模块  HC-SR04  测距 编辑:什么鱼 引用地址:http://news.eeworld.com.cn/mcu/ic471779.html 本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:基于STM32F103C8T6的超声波测距示例
下一篇:记STM32之PWM学习笔记 ---PWM原理

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

STM32F0x2 IWDG(独立看门狗)
单片机系统在外界的干扰下会出现程序跑飞的现象导致出现死循环,看门狗电路就是为了避免这种情况的发生。看门狗的作用就是在一定时间内(通过定时计数器实现)没有接收喂狗信号(表示 MCU 已经挂了),便实现处理器的自动复位重启(发送复位信号)。 以下为stm32f042单片机独立看门狗相关代码:/***********************************************************函数描述:初始化独立看门狗,timeout为1s*函数:void IWDG_Init(unsigned char usb_sw) *参数:无*作者:*日期
发表于 2019-11-12
STM32F103x8B PB3、PB4、PA14、PA15引脚作为普通IO口使用
STM32的PB3、PB4、PA14、PA15引脚可以在使用ISP烧录的情况下释放出来,作为普通IO口使用。初始化代码如下:void Gpio_init(void)      {       GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO,ENABLE); GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable,ENABLE
发表于 2019-10-18
STM32F10x_ADC三通道DMA连续转换(3通道、软件单次触发)
)本文讲述的知识点相对较多,若初次学习STM32的ADC转换功能,可以参考我另外一篇相对简单一点的文章:STM32F10x_ADC1单通道单次采集关于本文的更多详情请往下看。Ⅱ、实例工程下载笔者针对于初学者提供的例程都是去掉了许多不必要的功能,精简了官方的代码,对初学者一看就明白,以简单明了的工程供大家学习。笔者提供的实例工程都是在板子上经过多次测试并没有问题才上传至360云盘,欢迎下载测试、参照学习。提供下载的软件工程是基于Keil(MDK-ARM) V5版本、STM32F103ZE芯片,但F1其他型号也适用(适用F1其他型号: 关注微信,回复“修改型号”)。STM32F10x_ADC三通道DMA连续转换(3通道、软件单次触发)实例
发表于 2019-09-18
STM32F10x_ADC三通道DMA连续转换(3通道、软件单次触发)
STM32F10x JTAG端口重映射
STM32F10x系列的MCU复位后,PA13/14/15和PB3/4默认配置为JTAG功能。为了充分利用MCU I / O口的资源,会把这些端口设置为普通I/O口。【相关代码】: RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);     //使能PB端口时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);        //开启AFIO时钟    // 改变指定管脚的映射
发表于 2019-09-03
STM32F10x JTAG端口重映射
STM32F10x 学习笔记之USART实现串口通讯
STM32F10x 系列单片机中都包含了USART 模块,所谓USART,就是通用同步异步收发器。通用同步异步收发器(USART)提供了一种灵活的方法与使用工业标准NRZ异步串行数据格式的外部设备之间进行全双工数据交换。它支持同步单向通信和半双工单线通信,也支持LIN(局部互连网),智能卡协议和IrDA(红外数据组织)SIR ENDEC规范,以及调制解调器(CTS/RTS)操作。它还允许多处理器通信。从前面的介绍可知USART模块功能非常的强大。这里我只简单讲讲如何用USART模块来实现标准EIA-232 串口通讯。用过单片机的人肯定都接触过串口,设置串口无非就是设置波特率、数据位、停止位
发表于 2019-08-26
STM32F10x 学习笔记之USART实现串口通讯
STM32F10x TIM1 CH3/CH4 的重映射PWM输出
能TIMx在ARR上的预装载寄存器  TIM_CtrlPWMOutputs(TIM1,ENABLE);        //MOE 主输出使能,高级定时器必须开启这个  TIM_Cmd(TIM1, ENABLE);  //使能TIM1  }    .H文件#ifndef __TIMER_H#define __TIMER_H#include "stm32f10x.h"  void TIM1_PWM_Init(u16 arr,u16 psc); #endif2.应用版源码   
发表于 2019-08-21
小广播
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2019 EEWORLD.com.cn, Inc. All rights reserved