基于stm32f407的超声波并且距离越近蜂鸣器响的频率越快编写代码并通过串口发送距离
时间: 2023-08-15 16:05:03 浏览: 250
基于STM32-F407ZG的工程+源代码+文档说明01-LED-寄存器01-LED-库函数01-LED-位操作02-蜂鸣器03
以下是基于stm32f407的超声波测距并控制蜂鸣器发声的代码,距离越近蜂鸣器响的频率越快,并且通过串口发送距离:
```
#include "stm32f4xx.h"
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_tim.h"
#include "stm32f4xx_usart.h"
#include "misc.h"
#define TRIG_PIN GPIO_Pin_0
#define ECHO_PIN GPIO_Pin_1
#define BUZZER_PIN GPIO_Pin_13
void init_gpio(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOC, ENABLE);
GPIO_InitStruct.GPIO_Pin = TRIG_PIN;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.GPIO_Pin = ECHO_PIN;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource1, GPIO_AF_TIM2);
GPIO_InitStruct.GPIO_Pin = BUZZER_PIN;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOC, &GPIO_InitStruct);
GPIO_PinAFConfig(GPIOC, GPIO_PinSource13, GPIO_AF_TIM4);
}
void init_timer(void)
{
TIM_TimeBaseInitTypeDef TIM_InitStruct;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 | RCC_APB1Periph_TIM4, ENABLE);
TIM_InitStruct.TIM_Period = 65535;
TIM_InitStruct.TIM_Prescaler = 84 - 1;
TIM_InitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_InitStruct.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_InitStruct);
TIM_TimeBaseInit(TIM4, &TIM_InitStruct);
TIM_Cmd(TIM2, ENABLE);
TIM_Cmd(TIM4, ENABLE);
}
void init_usart(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
USART_InitTypeDef USART_InitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1);
USART_StructInit(&USART_InitStruct);
USART_InitStruct.USART_BaudRate = 115200;
USART_InitStruct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
USART_Init(USART1, &USART_InitStruct);
USART_Cmd(USART1, ENABLE);
NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
}
void send_data(uint8_t data)
{
while (!USART_GetFlagStatus(USART1, USART_FLAG_TXE));
USART_SendData(USART1, data);
}
void send_distance(float distance)
{
uint8_t buffer[32];
sprintf((char*)buffer, "Distance: %.2f cm\r\n", distance);
for (int i = 0; i < strlen((char*)buffer); i++)
{
send_data(buffer[i]);
}
}
int main(void)
{
uint16_t count = 0;
float distance = 0.0f;
float frequency = 0.0f;
uint32_t last_tick = 0;
uint32_t current_tick = 0;
init_gpio();
init_timer();
init_usart();
while(1)
{
// 发送超声波信号
GPIO_ResetBits(GPIOA, TRIG_PIN);
Delay_us(2);
GPIO_SetBits(GPIOA, TRIG_PIN);
Delay_us(10);
GPIO_ResetBits(GPIOA, TRIG_PIN);
// 等待接收超声波信号
while(!GPIO_ReadInputDataBit(GPIOA, ECHO_PIN));
// 开始计数
TIM_SetCounter(TIM2, 0);
while(GPIO_ReadInputDataBit(GPIOA, ECHO_PIN));
count = TIM_GetCounter(TIM2);
// 计算距离和频率
distance = count * 0.017f;
frequency = 1.0f / distance;
// 控制蜂鸣器发声
TIM_SetAutoreload(TIM4, (uint16_t)(84000000 / frequency / 2));
TIM_SetCompare1(TIM4, (uint16_t)(84000000 / frequency / 2 / 2));
TIM_Cmd(TIM4, ENABLE);
// 发送距离数据
current_tick = HAL_GetTick();
if (current_tick - last_tick > 1000)
{
send_distance(distance);
last_tick = current_tick;
}
Delay_ms(100);
TIM_Cmd(TIM4, DISABLE);
}
}
void USART1_IRQHandler(void)
{
if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
{
uint8_t data = USART_ReceiveData(USART1);
USART_ClearITPendingBit(USART1, USART_IT_RXNE);
}
}
```
其中,超声波测距的原理与之前的代码相同。控制蜂鸣器的频率和占空比的代码也与之前的代码类似,不同的是要根据距离来计算频率,距离越近频率越高。发送距离数据的函数`send_distance`使用了`sprintf`函数将距离格式化成字符串,并通过串口发送出去。在`main`函数中,使用`HAL_GetTick`函数获取当前的系统时间,并与上一次发送数据的时间进行比较,以控制发送频率。串口接收中断的函数`USART1_IRQHandler`暂时没有用到,可以根据需要进行修改。
阅读全文