STM32+蓝牙模块+超声波模块+QT
背景
倒车的时候有时不注意撞到了后面,那有没有办法检测障碍物并通知我呢。
我想了一个不太成熟的方法,就当作自娱自乐了,,,,
使用超声波测距,当作与障碍物的距离。然后STM32把测出的距离通过蓝牙模块传到手机并发出声音。由于不会安卓的编程,就用电脑实现了。
使用的设备
- 硬件
- HC-SR04
- HC-04
- STM32F103C8T6
- 软件
- pyside6
硬件电路
text
HC-SR04超声波模块 STM32F103 HC-04蓝牙模块 STM32F103 (和前面的是一个,不好画图所以分开了)
┌────────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐
│ VCC │───│ 3.3V │ │ VCC │───│ 3.3V │
│ Trig │───│ PB0 │ │ GND │───│ GND │
│ Echo │───│ PA8 │ │ TXD │───│ PA10(RX)│
│ GND │───│ GND │ │ RXD │───│ PA9(TX) │
└────────────┘ │ │ │ EN │───│ 3.3V │
└─────────┘ └─────────┘ └─────────┘
代码
- STM32
c
#include "stm32f10x.h"
#include "LED.h"
#include "app_timer.h"
#include "Delay.h"
#include "math.h"
#include "OLED.h"
#include <stdio.h>
#define TRIG GPIOB
/**
Echo PA8
Trigger PB0
LED PA1
*/
void GPIOB_0_init() {
// Trigger引脚
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_Init(TRIG, &GPIO_InitStruct);
}
void timer_init(void) {
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
TIM_TimeBaseInitTypeDef TIM_TIM_TimeBaseInitStruct;
TIM_TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0;
TIM_TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TIM_TimeBaseInitStruct.TIM_Period = 65535;
TIM_TIM_TimeBaseInitStruct.TIM_Prescaler = 71;
TIM_TimeBaseInit(TIM1, &TIM_TIM_TimeBaseInitStruct);
// Echo 引脚
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPD;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8;
GPIO_Init(GPIOA, &GPIO_InitStruct);
TIM_ICInitTypeDef TIM_ICInitStruct;
TIM_ICInitStruct.TIM_Channel = TIM_Channel_1;
TIM_ICInitStruct.TIM_ICFilter = 0;
TIM_ICInitStruct.TIM_ICPolarity = TIM_ICPolarity_Rising;
TIM_ICInitStruct.TIM_ICPrescaler = TIM_ICPSC_DIV1;
TIM_ICInitStruct.TIM_ICSelection = TIM_ICSelection_DirectTI;
TIM_ICInit(TIM1, &TIM_ICInitStruct);
TIM_ICInitStruct.TIM_Channel = TIM_Channel_2;
TIM_ICInitStruct.TIM_ICFilter = 0;
TIM_ICInitStruct.TIM_ICPolarity = TIM_ICPolarity_Falling;
TIM_ICInitStruct.TIM_ICPrescaler = TIM_ICPSC_DIV1;
TIM_ICInitStruct.TIM_ICSelection = TIM_ICSelection_IndirectTI; // 间接选择
TIM_ICInit(TIM1, &TIM_ICInitStruct);
}
// 串口初始化函数
void USART1_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
// 使能时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);
// 配置TX引脚 (PA9)
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// 配置RX引脚 (PA10)
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// 配置串口参数
USART_InitStructure.USART_BaudRate = 9600;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART1, &USART_InitStructure);
USART_Cmd(USART1, ENABLE);
}
// 串口发送字符函数
void USART1_SendChar(char ch)
{
USART_SendData(USART1, (uint8_t) ch);
while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
}
// 串口发送字符串函数
void USART1_SendString(char *str)
{
while (*str) {
USART1_SendChar(*str++);
}
}
//// 重写printf的fputc函数,支持串口输出
//int fputc(int ch, FILE *f)
//{
// USART1_SendChar(ch);
// return ch;
//}
int main(void)
{
OLED_Init();
OLED_ShowString(1, 1, "current dis:");
GPIOB_0_init();
// LED 显示
LED_Init();
LED1_OFF();
timer_init();
USART1_Init(); // 初始化串口
USART1_SendString("Distance Unit: meter");
Delay_ms(5000);
while(1) {
TIM_SetCounter(TIM1, 0);
TIM_ClearFlag(TIM1, TIM_FLAG_CC1);
TIM_ClearFlag(TIM1, TIM_FLAG_CC2);
TIM_Cmd(TIM1, ENABLE);
GPIO_WriteBit(TRIG, GPIO_Pin_0, Bit_SET);
Delay_us(20);
GPIO_WriteBit(TRIG, GPIO_Pin_0, Bit_RESET);
while(TIM_GetFlagStatus(TIM1, TIM_FLAG_CC1) == RESET) {
;
}
while(TIM_GetFlagStatus(TIM1, TIM_FLAG_CC2) == RESET) {
;
}
TIM_Cmd(TIM1, DISABLE);
// 换算
float distance = (TIM_GetCapture2(TIM1) - TIM_GetCapture1(TIM1)) * 1e-6 * 340.0f / 2;
if (distance < 1.0) {
LED1_ON();
} else {
LED1_OFF();
}
OLED_ShowString(2, 1, " ");
char str[20]; // 确保缓冲区足够大
sprintf(str, "%fmm", distance * 100.0f);
OLED_ShowString(2, 3, str);
// 串口发送距离数据
char uart_buffer[50];
sprintf(uart_buffer, "%.2f", distance * 100.0f);
USART1_SendString(uart_buffer);
Delay_ms(1000);
}
}
测距蓝牙输出