STM32+蓝牙模块+超声波模块+QT

STM32+蓝牙模块+超声波模块+QT

背景

倒车的时候有时不注意撞到了后面,那有没有办法检测障碍物并通知我呢。

我想了一个不太成熟的方法,就当作自娱自乐了,,,,

使用超声波测距,当作与障碍物的距离。然后STM32把测出的距离通过蓝牙模块传到手机并发出声音。由于不会安卓的编程,就用电脑实现了。

使用的设备

  1. 硬件
  • HC-SR04
  • HC-04
  • STM32F103C8T6
  1. 软件
  • 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    │
                 └─────────┘   └─────────┘   └─────────┘

代码

  1. 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);
	}
}
  1. UI界面
    https://gitee.com/blue_serial/blue_serial_ui

测距蓝牙输出

相关推荐
用户805533698032 天前
不止三件套:QObject 属性系统全关键字与运行时反射!
c++·qt
xcyxiner2 天前
DicomViewer (vcpkg Windows和ubuntu编译)7
qt
Quz7 天前
QML Hello World 入门示例
qt
xcyxiner10 天前
DicomViewer (dcmtk读取dcm文件)5
qt
xcyxiner11 天前
DicomViewer (后台线程处理文件)4
qt
xcyxiner11 天前
DicomViewer (添加模型类)3
qt
xcyxiner12 天前
DicomViewer (目录调整) 2
qt
xcyxiner12 天前
dcmtk vtk vtk-dicom(gdcm) 编译(debug) v2
qt
✎ ﹏梦醒͜ღ҉繁华落℘14 天前
单片机基础知识---stm32单片机的优先级
stm32·单片机·mongodb
u1521096484914 天前
S.S.Audio PRO A2音频隔离器
嵌入式硬件·音视频·实时音视频·视频编解码·视频