模块介绍
该模块有四个引脚,两个通信引脚,两个电源引脚。
按照官方手册时序图进行配置GPIO 以及获取高电平时间即可算出模块回响距离
时序图
图中TRIG为信号触发引脚,设置GPIO为输入模式
图中ECHO为信号回响引脚,设置GPIO为输出模式
代码
SR04.c
#include "SR04.h"
void SR04_init(void)
{
/* 硬件使能 */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
/* GPIO */
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING; // 浮空
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStruct);
/* 初始化定时器 */
TIM_InternalClockConfig(TIM2);
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInitStruct.TIM_Period = 50000; // 周期
TIM_TimeBaseInitStruct.TIM_Prescaler = 72; // 预分频器
TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStruct);
/* 不开启定时器 */
TIM_Cmd(TIM2, DISABLE);
}
uint16_t SR04_get_distance(void)
{
uint16_t temp;
uint16_t distance;
// PA2输出低电平
GPIO_WriteBit(GPIOA, GPIO_Pin_2, 0);
Delay_us(8);
/* PA2输出高电平 */
GPIO_WriteBit(GPIOA, GPIO_Pin_2, 1);
Delay_us(20);
/* PA2输出低电平 */
GPIO_WriteBit(GPIOA, GPIO_Pin_2, 0);
/* 将计数值设置为0 */
TIM2->CNT = 0;
/* 等待PA3高电平到来 */
while (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_3) == 0)
{
}
/* 使能定时器计数 */
TIM_Cmd(TIM2, ENABLE);
/* 等待PA3低电平到来 */
while (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_3) == 1)
{
}
/* 记录计数值 */
temp = TIM2->CNT;
/* 关闭定时器 */
TIM_Cmd(TIM2, DISABLE);
/* 通过公式计算超声波距离 */
/* 此时单位为cm */
distance = temp / 58;
return distance;
}
SR04.h
#ifndef __SR04_H_
#define __SR04_H_
#include "stm32f10x.h"
#include "Delay.h"
void SR04_init(void);
uint16_t SR04_get_distance(void);
#endif
main.c
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"
#include "SR04.h"
int main(void)
{
uint16_t distance = 0;
OLED_Init();
SR04_init();
while (1)
{
/* 获取距离 */
distance = SR04_get_distance();
/* 显示距离参数 */
OLED_ShowString(1, 1, "distance:");
OLED_ShowNum(1, 10, distance, 4);
Delay_ms(200);
}
}