『壹』 请求教,STM32超声波如何定义管脚,给管脚高低电平,是如何写的,稍微写一下,我理解理解
一般就是两个管脚:TRIG、ECHO。超声波又分两种,一种是自己驱动的(自己画超声波部分电路),一种是驱动第三方做好的。
一、自己驱动的
TRIG脚初始化为输出,ECHO初始化为输入。同时ECHO脚设置为外部中断
2.TRIG脚发送脉冲,一般是循环发送8个脉冲。然后计时清0.
for(u8 i = 0; i < 8; i++)
{
TRIG_HIGH;
delay_us(10);
TRIG_LOW;
delay_us(10);
}
3.等待触发ECHO脚的外部中断,或者等待超时(这是为了前方空旷没有超声波返回)。
4.数据处理。((float)(SonicL.time.ms * 1000.0 + PULSE_TIME + WAIT_STABLE_TIME + SonicL.time.endCnt - SonicL.time.startCnt)/ 58.0);//cm
二、直接用模块,这个模块一般会有厂家提供手册
TRIG脚初始化为输出,ECHO初始化为输入。同时ECHO脚设置为外部中断
2.TRIG脚发送脉冲,一般是循环发送8个脉冲。
TRIG_HIGH; delay_us(20); TRIG_LOW;
3.等待触发ECHO脚的外部中断(上升沿中断时计时清0.下降沿中断时停止计时),或者等待超时(这是为了前方空旷没有超声波返回)
4.数据处理。((float)(SonicL.time.ms * 1000.0 + SonicL.time.endCnt - SonicL.time.startCnt)/ 58.0);//cm
『贰』 stm32避障小车,驱动是l298n,超声波传感器是HY-SRF05,求程序,若成功还有追加财富值。麻烦大家了。
兄弟,你觉着可能会有人花时间给你做全套程序么。。。
『叁』 stm32中软件部分如何利用传感器接口驱动超声波测距
这个可以通过超声波传感器的输出端口采集,看传感器是数字接口还是模拟输出。
『肆』 stm32引脚接超声波接口用什么模式
stm32引脚接超声波接口用什么模式
超声波模块测得的距离一直是固定值的同仁看过来:
如果你是用3.3v给开发板供电,但用到了开发板的5v给HC-SR04供电,那么你就和我掉进的同一个坑
出现这个问题的原因是STM32开发板一般没有升压芯片或其他升压措施,因此低于5v给开发板供电是不可能输出5v电压的 ,根据测量它只有2.86v,这就导致了HC-SR04供电不足的问题
在我认为是代码问题并修改了16个小时的最后一分钟,我发现他是供电不足引起的,这一结论真让我哭笑不得
开篇闲谝:
耀风(鄙人)是一个STM32才入门的小白所以文章写的不是很严谨,如果有错误欢迎大家指正。我写这篇文章的目的有两个:
第一,记录本次实验方便自己以后查看(毕竟卡了我16个小时,错误原因竟然是哭笑不得的供电不足)。
第二,分享给其他在学或还不知道怎么使用超声波模块的同仁,避免犯和我一样的错误。
编程IDE工具: KEIL5
实验所需材料:
1.STM32F1系列单片机任意一款
2. HC_SR04超声波模块
3.杜邦线若干
引脚连接:
Tring —>PA4
Echo —>PA5
GND —>GND
VCC —>5v~5.5v
网上资料说超声波模块的供电电压在3~5.5v,但是还是建议用5v左右,因为稳定。如果STM32不是5v供电,那么就不要用STM32开发板上的引脚给HC_SR04供电。
原因就是STM32开发板一般没有升压芯片或其他升压措施,因此低于5v给开发板供电是不可能输出5v电压的 (再啰嗦一遍)
实验原理:
通过STM32的GPIO给HC_SR04模块的Tring引脚输出一个至少10us的高电平开启超声波模块,然后超声波模块就会自动发送一个连续的由8个40KHZ脉冲组成的脉冲串,发送完成后HC_SR04模块的Echo引脚会变成低电平并且HC_SR04模块的芯片也会开始时。如果HC_SR04发出的脉冲串遇到障碍物就会被反射回来,当超声波模块接收到返回的脉冲串时就会将Echo引脚变成高电平并且HC_SR04模块的芯片也会停止计时,Echo引脚输出高电平的时间就是脉冲串从发出到接收的时间。
由上面这巴拉巴拉的一段话我们可以知道驱动HC_SR04的步骤:
1. 通过STM32的GPIO给HC_SR04的Tring引脚输出一个至少10us的高电平
2. 当HC_SR04的Echo引脚输出高电平时开启STM32的定时器或Systick定时器开始计时,当Echo引脚输出低电平时停止计时,并记录时间
3. 根据时间算距离
distance = T(所测时间)x 340m/s / 2 = T(所测时间) x 170m/s = T(所测时间) x 17000 cm / 1000 000 us = T(所测时间)/ 1000 000 us / 17000 cm = T(所测时间)/ 58.0(近似值)
不想看上面推导的朋友知道距离 distance = T(所测时间)/ 58.0 就可以了
代码核心片段讲解:
//**********引脚初始化*************
void init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStruct);
}
/***********延时函数定义(使用Systick定时器实现)**************
1.用Systick定时器的原因就是它操作简单一点,不用初始化,直接调用SysTick_Config()函数即可,然后在写个相应中断函数就可
2.因为在本项目中延时和定时不用同时运行,所以这两个功能用一个定时器就好
*************************************************************/
void delay_ms(uint32_t time)
{
TIME = time;
State = 0; // 用于区分是Systick因延时的进入中断还是因定时进入中断
SysTick_Config(72000); //定时器每1ms计时一次
while(TIME!=0);
SysTick->CTRL &=~ SysTick_CTRL_ENABLE_Msk; //关闭定时器
}
void delay_us(uint32_t time)
{
TIME = time;
State = 0;// 用于区分是Systick因延时的进入中断还是因定时进入中断
SysTick_Config(72);//定时器每1us计时一次
while(TIME!=0);
SysTick->CTRL &=~ SysTick_CTRL_ENABLE_Msk;//关闭定时器
}
//************测引脚电平持续时间函数定义******************
uint32_t pulseIn(GPIO_TypeDef* GPIOx,uint16_t Pin,STATE state)
{
uint32_t time = 0;
uint8_t i ;
while(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_5) == (u8)!state){}
State = 1;
TIME = 0;
SysTick_Config(72); //一定要以1us为溢出时间,因为算距离的公式中的T是以us为单位的
while(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_5) == (u8)state){}
SysTick->CTRL &=~SysTick_CTRL_ENABLE_Msk;
time = TIME;
TIME = 0;
printf(" Time = %d\n",time);
return time;
}
extern int TIME;
extern uint8_t State;
void SysTick_Handler(void)
{
if(State == 0) //因延时函数中的SysTick定时器溢出进入
TIME--;
else if(State == 1) //因定时中的SysTick定时器溢出进入
TIME++;
}
int main(void)
{
init();
Usart_begin(USART1,9600); //这是我自己写的STM32库函数二次封装中的USART1初始化函数
//啊吧啊吧,本来整个工程都是用我开发的二次封装写的,奈何我竟傻傻的16个小时都认为是代码问题,所以就改掉了。
while(1){
float distance;
GPIO_ResetBits(GPIOA,GPIO_Pin_4);
delay_us(10);
GPIO_SetBits(GPIOA,GPIO_Pin_4);
delay_us(20);
GPIO_ResetBits(GPIOA,GPIO_Pin_4);
distance = (float)pulseIn(GPIOA, GPIO_Pin_5,HIGH)/58.0; //算出距离(58.0的原因前面有讲解)
printf("distance = %.2lf\n",distance);
delay_ms(200);
}
}
登录后复制
后面我会专门写一个这个二次封装用法的文章的,大家先搞着用这个四不像的工程代码吧。啊吧啊吧
输出正常:
代码分享:
耀风写的代码,需要请点击下载
提取码:YFJS
『伍』 使用超声波传感器HY-SRF05时,VCC端接在STM32F103C8T6单片机的5V引脚
STM32F103的电源是3.3V的,而一般这个3.3V的电源都是从5V电源得来的;
如果你板上没有5V电源,如是直接从锂电池供电的,只需要加个小小的电源转换模块,3.3-->5V,便可得到5V电源,而传感器的耗电很小容易满足;
『陆』 求教,stm32怎么用超声波模块测距,用的是HC
超声波测距模块是传感器,输出什么信号,让STM32来采集这个信号就能得到距离。这个你查看这个模块的输出接口与STM32链接就好了,一般是usart或者是spi,或者是AD,对应采集数据就完事了。
『柒』 基于stm32的多功能时钟4——超声波测距
hello,读者们好!
前两章,主要讲述了环境参量的测量获取,想必大家都有些许收获。在这一章中,我将介绍如何利用超声波来测距。在现实生活中,利用超声波测距的应用很多,广泛应用于机器人避障 、物体测距 、液位检测 、公共安防、停车场检测等领域。
本次测距使用的超声波为HC-SRO4,该模块共有4个引脚,分别是两个电源引脚VCC和GND,一个触发控制信号输入(TRIG)和一个回响信号输出( ECHO),性能稳定,测度距离精确,模块高精度,盲区小。
那么,超声波模块测距原理是:首先,给Trig引脚至少10us的高电平信号,检测Echo是否有信号返回,若有信号返回,则Echo发出高电平。高电平持续的时间就是超声波从发射到返回的时间,所以测试距离为(高电平时间*声速)/2。下面,就是超声波模块的时序图。
本模块使用方法简单,配合stm32的定时器TIM4,一个控制口发一个10us以上的高电平,就可以在接收口等待高电平输出。一有输出就可以开定时器TIM4计时,当此口变为低电平时就可以读定时器TIM4的值,此时就为此次测距的时间,方可算出距离。如此不断的周期测,即可以达到你移动测量的值。
(1)配置超声波的引脚
/*初始化超声波引脚:Trig:PB0,Echo:PB1*/
void ultra_gpio_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/*使能GPIO的RCC时钟*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
/*配置Trig引脚*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//Trig
GPIO_Init(GPIOB,&GPIO_InitStructure);
/*配置Echo引脚*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//Echo
GPIO_Init(GPIOB,&GPIO_InitStructure);
}
由于PB0接超声波Trig引脚,所以选择推挽输出模式,PB1接超声波Echo引脚,所以选择浮空输入模式。这样,超声波模块引脚就配置完成。
(2)定时器TIM4初始化
/*定时器4的NVIC配置*/
void tim4_nvic_config(void)
{
NVIC_InitTypeDef NVIC_InitStruct;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitStruct.NVIC_IRQChannel = TIM4_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;//抢占优先级为0
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;//子优先级为0
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
}
/*定时器4初始化*/
void tim4_config(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
tim4_nvic_config(); //配置NVIC
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);//开启时钟
TIM_DeInit(TIM4); //定时器4复位
TIM_TimeBaseInitStruct.TIM_Period = 1000-1; //自动重装载寄存器值
TIM_TimeBaseInitStruct.TIM_Prescaler = 72-1; //时钟预分频数
TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1; //采样分频
TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up; //计数模式
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseInitStruct); //初始化TIM4
TIM_ClearFlag(TIM4, TIM_FLAG_Update); //清除溢出中断标志
TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE);
TIM_Cmd(TIM4, DISABLE);
}
由于考虑到测距时的距离过大,计数会溢出,出现不准确的现象,这里需要用到长计时,并且使用TIM4中断对计时变量进行自增,所以需要配置NVIC。这里设置的中断优先级比较高,因为测距不能被其他中断打断,否则可能出现数据不准的现象,或是数据抖动现象。其次,设置TIM4的中断溢出时间为1ms,此时还不能开启定时器TIM4。
(3)编写定时器中断程序
/*定时器4中断服务函数*/
void TIM4_IRQHandler(void)
{
if(TIM_GetITStatus(TIM4 ,TIM_IT_Update)!=RESET)
{
TIM4_NUM++;//长计时变量
}
TIM_ClearITPendingBit(TIM4 ,TIM_FLAG_Update);
}
为避免测量的距离过长,这里我们需要进行长计时,只需在中断函数里这样操作:TIM4_NUM++,同时记得在每次测量距离前对TIM4_NUM复位即可。
(4)编写超声波测距相关函数
/*启动超声波测距*/
u16 ultra_measure(void)
{
u16 distance;
TRIG_H;
delay_us(20);
TRIG_L;
while(ECHO==RESET);
TIM_SetCounter(TIM4,0);
TIM4_NUM = 0;
TIM_Cmd(TIM4, ENABLE);
while(ECHO!=RESET);
TIM_Cmd(TIM4, DISABLE);
distance = (u16)ultra_get_distance();
return distance;
}
/*获取超声波传播时间,间接计算出距离*/
float ultra_get_distance(void)
{
u32 time;
float distance;
time = TIM4_NUM*1000;
time += TIM_GetCounter(TIM4);//获取超声波测距总时间
TIM4->CNT = 0; //定时器复位
distance = (float)time*0.017;
return distance;
}
这里,需要查阅超声波手册中的时序图,方可编写程序。首先,向给trig 发送至少10 us的高电平脉冲,然后等待,捕捉 echo 端输出上升沿,捕捉到上升沿的同时,打开定时器开始计时,再次等待捕捉echo的下降沿,当捕捉到下降沿,读出计时器的时间,这就是超声波在空气中运行的时间,按照测试距离=(高电平时间*声速)/2 就可以算出超声波到障碍物的距离。
这里我们测算的距离:distance = (float)time*0.017,计算的距离单位为cm。
(5)主函数调用测距函数
最后,在主函数里,调用测距函数即可获取到距离值,再通过lcd显示函数,显示出距离值。
value = ultra_measure();
lcd_display_string(0,32,"测量距离");
lcd_display_num_m(3, 48, value/1000);
lcd_display_num_m(3, 56, (value%1000)/100);
lcd_display_num_m(3, 64, (value%100)/10);
lcd_display_num_m(3, 72, value%10);
通过本章的介绍,相信你对于超声波测距应该了解不少了吧,相信你也可以做出来的。通过不断改变超声波和障碍物之间的位置,距离值会随之改变,是不是很有趣啊~
到目前为止,多功能时钟已经具备了显示时间、测量温湿度、测量空气质量以及测距的功能,但我们的LCD显示部分还没有优化。在下一章中,我将带着大家完成多功能时钟人机交互界面(简称UI)的开发,到时候,我们的界面就会变得比较美观了。敬请期待~
『捌』 关于stm32驱动超声波测距模块的问题,要疯了QAQ
1、目前大部分超声波模块都是5V供电的,STM32是3.3V供电,如果你的模块是3.3V那么它是不能正常工作的。
2、另外,如果模块使用5V供电,应当在通信口串联限流电阻,避免5V信号直接灌入芯片,造成损坏。
『玖』 我用如图的stm32板子,求一个超声波传感器扫描到距离小于一个值便触发震动电机的程序,急!
是余震,你用示波器看下余震波形和维持时间,要把余震时间隔离开不进行计算距离
『拾』 求教,stm32怎么用超声波模块测距,用的是HC-SR04
应该说在保修期,硬盘坏的话,应该直接换硬盘,一天足够了,但是许多地方的笔记本商家,都没有售后,只能送到大城市去修,所以时间 长,