STM32超声波模块测距控制舵机
Posted 行稳方能走远
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了STM32超声波模块测距控制舵机相关的知识,希望对你有一定的参考价值。
摘自:stm32 超声波模块 原理 实现测距 +舵机使用
作者:点灯小哥
发布时间: 2021-03-10 19:37:16
网址:https://blog.csdn.net/weixin_46016743/article/details/114643703
效果展示
超声波传感器原理
超声波测距编程步骤
要配置三个结构体
代码编写
HC_SR04.c
#include "stm32f10x.h" // Device header
#include "SysTick.h"
#include "HC_SR04.h"
extern uint16_t mscount = 0; //extern 让main函数也能使用这里这个
void HC_SR04(void)
{
GPIO_InitTypeDef GPIO_HC_SR04init; //1.配置GPIO引脚结构体 Trig PB11 Echo PB10
TIM_TimeBaseInitTypeDef TIM_HC_SR04init; //2.配置定时器结构体
NVIC_InitTypeDef NVIC_HC_SR04init; //3.配置定时器中断结构体
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
//rcc.h
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);//4.开启时钟(定时器,GPIO 在APB2总线上)
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
//Trig PB11 发送
GPIO_HC_SR04init.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_HC_SR04init.GPIO_Pin = GPIO_Pin_11;
GPIO_HC_SR04init.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init( GPIOB, &GPIO_HC_SR04init );
//Echo PB10 接收
GPIO_HC_SR04init.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入 只要求高电平 高低电平直接检测
GPIO_HC_SR04init.GPIO_Pin = GPIO_Pin_10;
GPIO_Init( GPIOB, &GPIO_HC_SR04init );
TIM_HC_SR04init.TIM_ClockDivision = TIM_CKD_DIV1;//分频系数1 不分频 还是72MHz
TIM_HC_SR04init.TIM_CounterMode = TIM_CounterMode_Up;//向上计数
TIM_HC_SR04init.TIM_Period = 100 - 1 ; //1us
TIM_HC_SR04init.TIM_Prescaler = 72 - 1 ; //72M 这两个相乘7200/72 000 000 = 1us
TIM_TimeBaseInit( TIM4, &TIM_HC_SR04init);
TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE);//IT就是中断 定时器中断 TIM_IT_Update是允许溢出/更新?
TIM_Cmd( TIM4, DISABLE ); //定时器先关闭 等着测量距离时再打开 下面给出打开定时器函数
NVIC_HC_SR04init.NVIC_IRQChannel = TIM4_IRQn;// 通道 中断源是定时器4
NVIC_HC_SR04init.NVIC_IRQChannelPreemptionPriority = 0;//抢占优先级 给的最高的
NVIC_HC_SR04init.NVIC_IRQChannelSubPriority = 0;//子优先级
NVIC_HC_SR04init.NVIC_IRQChannelCmd = ENABLE;//
NVIC_Init(&NVIC_HC_SR04init);
}
//打开定时器4
void Open_tim4(void)
{
TIM_SetCounter( TIM4, 0);//开启计数器计数 从0开始
mscount = 0; //需要计算高电平5次数值 取平均值 防止一次算的距离不精准
TIM_Cmd( TIM4, ENABLE ); //定时器使能 打开了
}
//关闭定时器4
void Close_tim4(void)
{
TIM_Cmd( TIM4, DISABLE ); //关闭
}
//定时器中断服务函数 函数名不能改动
void TIM4_IRQHandler(void)
{
if ( TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET) //判断是否发生中断
{
TIM_ClearITPendingBit(TIM4, TIM_IT_Update); //清楚中断的标记位
mscount++; //记录发生的中断次数 为了取5次测量计算提高精度
//定时器中断一次就是1us
}
}
//获取定时器计数器的值 得到Echo高电平的时间
int GetEcho_time(void)
{
uint32_t t = 0;
t = mscount * 1000; //发生了多少次中断 *1000 得到时间(一次中断就是1us)
t += TIM_GetCounter(TIM4);//获取定时器计数值 {这两行没看懂 感觉重复了?}
TIM4->CNT = 0;//代表向上增的寄存器(向上向下计数 前面章节有讲) 要置零 重装载
ms_delay(50);//系统库延时函数
return t;
}
//获取超声波测距距离
float GetLength(void)
{
int i = 0;
uint16_t t = 0;
float length = 0;
float sum = 0;
while(i != 5)//算5次 提高计算精度
{
TRIG_Send(1);
us_delay(20);//硬件模块要求发送高电平时间大于10us
TRIG_Send(0);//此时超声波开始工作了
while(ECHO_Reci == 0);
Open_tim4();
i=i+1;
while(ECHO_Reci == 1);//ECHO从低电平到高开始 计算高电平持续时间就能换算出距离
t = GetEcho_time();//计算ECHO高电平持续时间
length =((float) t / 58.0);
sum = sum +length;
}
length = sum / 5.0;
return length;
}
HC_SR04.h
#ifndef _HC_SR04_H //条件编译 为了防止重复编译
#define _HC_SR04_H
#include "stm32f10x.h" // Device header
void HC_SR04(void);
void Open_tim4(void);
void Close_tim4(void);
int GetEcho_time(void);
float GetLength(void);
#define ECHO_Reci GPIO_ReadInputDataBit( GPIOB, GPIO_Pin_10)
//为真就给Trig发送高电平
#define TRIG_Send(a) if(a) \\
GPIO_SetBits(GPIOB, GPIO_Pin_11); \\
else \\
GPIO_ResetBits(GPIOB, GPIO_Pin_11)
#endif
main.c
#include "stm32f10x.h" // Device header
#include "usart.h"
#include "led.h"
#include "tim.h"
#include "motor.h"
#include "SysTick.h"
#include "HC_SR04.h"//记得添加路径
void delay(uint16_t time)
{
uint16_t i = 0;
while(time--)
{
i=12000;
while(i--);
}
}
int main(void)
{
int pwmval = 195;
float Length = 0;
HC_SR04();
Usart_Init();
motor_config();
while(1)
{
int pwmval = 155;
Length = GetLength();
printf("%.3f\\r\\n",Length);//之前重定向print函数 串口打印输出距离 串口小助手就能看到打印的距离了
//3位小数
ms_delay(500);
//再加一个距离判断 将之前写的舵机部分加进来即可控制舵机
if(Length < 5)
{
for(pwmval = 195; pwmval >= 195;pwmval -=15 )
{
TIM_SetCompare2( TIM3, pwmval); //5. 配置PWM比较值 占空比
delay(1000);
}
}
else if (Length > 5)
{
TIM_SetCompare2( TIM3, pwmval-20); //让舵机回去
}
}
}
以上是关于STM32超声波模块测距控制舵机的主要内容,如果未能解决你的问题,请参考以下文章
基于STM32设计的倒车雷达系统(超声波模块多方位测距应用)