新增 Hc05 类,支持 HC-05 蓝牙模块的串口通信,增加串口设置波特率函数
All checks were successful
Build and Upload Artifact / build and upload-artifact (push) Successful in 19m59s

This commit is contained in:
chauyin
2025-05-12 21:57:21 +08:00
parent c3e0edd72d
commit 17d298c782
9 changed files with 119 additions and 18 deletions

View File

@@ -2,6 +2,7 @@
#include "../Common/can_mv.hpp" #include "../Common/can_mv.hpp"
#include "../Common/df_player.hpp" #include "../Common/df_player.hpp"
#include "../Common/hc05.hpp"
#include "../Common/ultrasonic.hpp" #include "../Common/ultrasonic.hpp"
#include "../config.hpp" #include "../config.hpp"
#include "Common/serial_port.hpp" #include "Common/serial_port.hpp"
@@ -33,12 +34,21 @@ public:
return *instance; return *instance;
} }
static Hc05& GetHc05() {
static Hc05* instance = nullptr;
if (instance == nullptr) {
instance = new Hc05(Config::kHc05Uart);
}
return *instance;
}
static SerialPort& GetDebugSerialPort() { static SerialPort& GetDebugSerialPort() {
static constexpr auto kBaudRate = 115200;
static constexpr auto kLength = 256; static constexpr auto kLength = 256;
static constexpr auto kTimeout = 1000; static constexpr auto kTimeout = 1000;
static SerialPort* instance = nullptr; static SerialPort* instance = nullptr;
if (instance == nullptr) { if (instance == nullptr) {
instance = new SerialPort(Config::kDebugUart, kLength, kTimeout); instance = new SerialPort(Config::kDebugUart, kBaudRate, kLength, kTimeout);
} }
return *instance; return *instance;
} }

View File

@@ -7,11 +7,13 @@
class CanMv { class CanMv {
public: public:
explicit CanMv(UART_HandleTypeDef* uart) : serialPort(std::make_unique<SerialPort>(uart, kLength, kTimeout)) {} explicit CanMv(UART_HandleTypeDef* uart)
: serialPort(std::make_unique<SerialPort>(uart, kBaudRate, kLength, kTimeout)) {}
~CanMv() = default; ~CanMv() = default;
private: private:
static constexpr uint32_t kBaudRate = 115200;
static constexpr uint32_t kLength = 128; static constexpr uint32_t kLength = 128;
static constexpr uint32_t kTimeout = 10; static constexpr uint32_t kTimeout = 10;
std::unique_ptr<SerialPort> serialPort; std::unique_ptr<SerialPort> serialPort;

View File

@@ -7,7 +7,8 @@
class DfPlayer { class DfPlayer {
public: public:
explicit DfPlayer(UART_HandleTypeDef* uart) : serialPort(std::make_unique<SerialPort>(uart, kLength, kTimeout)) {} explicit DfPlayer(UART_HandleTypeDef* uart)
: serialPort(std::make_unique<SerialPort>(uart, kBaudRate, kLength, kTimeout)) {}
~DfPlayer() = default; ~DfPlayer() = default;
@@ -49,6 +50,7 @@ private:
kQueryFlashCurrentTrack = 0x4D, kQueryFlashCurrentTrack = 0x4D,
}; };
static constexpr uint32_t kBaudRate = 9600;
static constexpr uint32_t kLength = 128; static constexpr uint32_t kLength = 128;
static constexpr uint32_t kTimeout = 10; static constexpr uint32_t kTimeout = 10;
std::unique_ptr<SerialPort> serialPort; std::unique_ptr<SerialPort> serialPort;

43
Core/App/Common/hc05.hpp Normal file
View File

@@ -0,0 +1,43 @@
#pragma once
#include <cerrno>
#include <cstdint>
#include "../Common/serial_port.hpp"
class Hc05 {
private:
static constexpr uint32_t kBaudRate = 9600;
static constexpr uint32_t kLength = 128;
static constexpr uint32_t kTimeout = 10;
std::unique_ptr<SerialPort> serialPort;
static constexpr uint8_t kCommand = 0xAA;
public:
// App 返回单个字节 Command 结果
enum class Response : uint8_t {
kForward, // 前进
kBackward, // 后退
kTurnLeft, // 左转
kTurnRight, // 右转
kForwardLeft, // 左前方
kForwardRight, // 右前方
kBackwardLeft, // 左后方
kBackwardRight, // 右后方
kTurnAround, // 掉头/180度转向
kStop, // 停止,到达目的地
};
explicit Hc05(UART_HandleTypeDef* uart)
: serialPort(std::make_unique<SerialPort>(uart, kBaudRate, kLength, kTimeout)) {}
~Hc05() = default;
Response SendCommand() {
Response data;
serialPort->WriteBytesBlocking(reinterpret_cast<const uint8_t*>(&kCommand), sizeof(kCommand));
serialPort->ReadBytesBlocking(reinterpret_cast<uint8_t*>(&data), sizeof(data));
return data;
}
};

31
Core/App/Common/key.hpp Normal file
View File

@@ -0,0 +1,31 @@
#pragma once
#include "../Helper/delay_helper.h"
#include "stm32h5xx_hal_gpio.h"
#include <cstdint>
#include "../Helper/gpio_helper.hpp"
class Key {
private:
static constexpr uint32_t kDebounceDelay = 20;
GpioHelper::Gpio gpio;
GPIO_PinState normalStatus;
public:
explicit Key(GpioHelper::Gpio gpio, GPIO_PinState normalStatus) : gpio(gpio), normalStatus(normalStatus) {
GpioHelper::GpioInit(gpio, GPIO_MODE_INPUT, normalStatus ? GPIO_PULLUP : GPIO_PULLDOWN);
}
bool IsPressed() {
auto reading = gpio.Read();
if (reading != normalStatus) {
DelayMs(kDebounceDelay);
reading = gpio.Read();
if (reading != normalStatus) {
return true;
}
}
return false;
}
};

View File

@@ -1,6 +1,7 @@
#pragma once #pragma once
#include "main.h" #include "main.h"
#include "stm32h5xx_hal_uart.h"
#include <cstdarg> #include <cstdarg>
#include <cstdint> #include <cstdint>
#include <cstring> #include <cstring>
@@ -13,21 +14,29 @@ private:
uint32_t timeout; uint32_t timeout;
std::unique_ptr<char[]> buffer; std::unique_ptr<char[]> buffer;
uint8_t ReadByteForce() {
return handle->Instance->RDR;
}
public: public:
SerialPort(UART_HandleTypeDef* uart, uint32_t length, uint32_t timeout) SerialPort(UART_HandleTypeDef* uart, uint32_t baudRate, uint32_t length, uint32_t timeout)
: handle(uart), timeout(timeout), buffer(std::make_unique<char[]>(length)) {} : handle(uart), timeout(timeout), buffer(std::make_unique<char[]>(length)) {
SetBaudRate(baudRate);
}
~SerialPort() = default; ~SerialPort() = default;
uint8_t ReadByte() { void SetBaudRate(uint32_t baudRate) {
return handle->Instance->RDR; HAL_UART_DeInit(handle);
handle->Init.BaudRate = baudRate;
HAL_UART_Init(handle);
} }
std::string ReadLine() { std::string ReadLine() {
std::string result; std::string result;
result.reserve(128); result.reserve(128);
char c; char c;
ReadByte(); ReadByteForce();
while (true) { while (true) {
auto r = HAL_UART_Receive(handle, reinterpret_cast<uint8_t*>(&c), sizeof(c), timeout); auto r = HAL_UART_Receive(handle, reinterpret_cast<uint8_t*>(&c), sizeof(c), timeout);
if (r != HAL_OK) { if (r != HAL_OK) {

View File

@@ -56,7 +56,8 @@ public:
return {port, pin}; return {port, pin};
} }
static Gpio GpioInit(const Gpio& gpio, const uint32_t mode, const uint32_t pull, const GPIO_PinState state) { static Gpio GpioInit(const Gpio& gpio, const uint32_t mode, const uint32_t pull,
const std::optional<GPIO_PinState> state = std::nullopt) {
return GpioInit(gpio.port, gpio.pin, mode, pull, state); return GpioInit(gpio.port, gpio.pin, mode, pull, state);
} }

View File

@@ -42,6 +42,7 @@ void CommonSetup() {
CommonCenter::GetDfPlayer(); CommonCenter::GetDfPlayer();
CommonCenter::GetCanMv(); CommonCenter::GetCanMv();
CommonCenter::GetDebugSerialPort(); CommonCenter::GetDebugSerialPort();
CommonCenter::GetHc05();
} }
void Setup() { void Setup() {

View File

@@ -18,5 +18,7 @@ struct Config {
static inline UART_HandleTypeDef* kCanMvUart = &hcom_uart[COM1]; static inline UART_HandleTypeDef* kCanMvUart = &hcom_uart[COM1];
static inline UART_HandleTypeDef* kHc05Uart = &hcom_uart[COM1];
static inline GpioHelper::Gpio kLed = {GPIOB, GPIO_PIN_0}; static inline GpioHelper::Gpio kLed = {GPIOB, GPIO_PIN_0};
}; };