From 83d9a263a4ffa8903fae791d9048da7ecd7606d7 Mon Sep 17 00:00:00 2001 From: chauyin Date: Sat, 10 May 2025 19:37:31 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=20DfPlayer=20=E5=92=8C=20Can?= =?UTF-8?q?Mv=20=E7=B1=BB=EF=BC=8C=E4=BC=98=E5=8C=96=20UART=20=E8=AF=BB?= =?UTF-8?q?=E5=86=99=E6=96=B9=E6=B3=95=EF=BC=8C=E6=9B=B4=E6=96=B0=20Common?= =?UTF-8?q?Center=20=E4=BB=A5=E6=94=AF=E6=8C=81=E6=96=B0=E7=B1=BB=E5=AE=9E?= =?UTF-8?q?=E4=BE=8B=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Core/App/Center/common_center.hpp | 18 +++++++++ Core/App/Common/can_mv.hpp | 19 ++++++++++ Core/App/Common/df_player.cpp | 41 ++++++++++++++++++++ Core/App/Common/df_player.hpp | 63 +++++++++++++++++++++++++++++++ Core/App/Common/serial_port.hpp | 14 ++++++- Core/App/app.cpp | 2 + Core/App/config.hpp | 4 ++ 7 files changed, 159 insertions(+), 2 deletions(-) create mode 100644 Core/App/Common/can_mv.hpp create mode 100644 Core/App/Common/df_player.cpp create mode 100644 Core/App/Common/df_player.hpp diff --git a/Core/App/Center/common_center.hpp b/Core/App/Center/common_center.hpp index 4c28694..cd2fa17 100644 --- a/Core/App/Center/common_center.hpp +++ b/Core/App/Center/common_center.hpp @@ -1,5 +1,7 @@ #pragma once +#include "../Common/can_mv.hpp" +#include "../Common/df_player.hpp" #include "../Common/ultrasonic.hpp" #include "../config.hpp" @@ -13,4 +15,20 @@ public: } return *instance; } + + static DfPlayer& GetDfPlayer() { + static DfPlayer* instance = nullptr; + if (instance == nullptr) { + instance = new DfPlayer(Config::kDfPlayerUart); + } + return *instance; + } + + static CanMv& GetCanMv() { + static CanMv* instance = nullptr; + if (instance == nullptr) { + instance = new CanMv(Config::kCanMvUart); + } + return *instance; + } }; diff --git a/Core/App/Common/can_mv.hpp b/Core/App/Common/can_mv.hpp new file mode 100644 index 0000000..684914d --- /dev/null +++ b/Core/App/Common/can_mv.hpp @@ -0,0 +1,19 @@ +#pragma once + +#include + +#include "../Common/serial_port.hpp" + +class CanMv { +public: + explicit CanMv(UART_HandleTypeDef* uart) : serialPort(new SerialPort(uart, kLength, kTimeout)) {} + + ~CanMv() { + delete serialPort; + } + +private: + static constexpr uint32_t kLength = 128; + static constexpr uint32_t kTimeout = 10; + SerialPort* serialPort; +}; diff --git a/Core/App/Common/df_player.cpp b/Core/App/Common/df_player.cpp new file mode 100644 index 0000000..c50c3ef --- /dev/null +++ b/Core/App/Common/df_player.cpp @@ -0,0 +1,41 @@ +#include "df_player.hpp" + +void DfPlayer::SendCommand(Command cmd, uint16_t param) { + uint8_t buffer[10]; + buffer[0] = kStartByte; + buffer[1] = kVersion; + buffer[2] = 0x06; + buffer[3] = static_cast(cmd); + buffer[4] = kFeedback; + buffer[5] = (param >> 8) & 0xFF; + buffer[6] = param & 0xFF; + + uint16_t checksum = 0xFFFF - (kVersion + 0x06 + static_cast(cmd) + kFeedback + buffer[5] + buffer[6]) + 1; + buffer[7] = (checksum >> 8) & 0xFF; + buffer[8] = checksum & 0xFF; + buffer[9] = kEndByte; + + serialPort->WriteBytesBlocking(buffer, sizeof(buffer)); +} + +void DfPlayer::Play() { + SendCommand(Command::kPlay); +} + +void DfPlayer::Stop() { + SendCommand(Command::kStop); +} + +void DfPlayer::SetVolume(uint8_t volume) { + if (volume > 30) { + volume = 30; + } + SendCommand(Command::kSetVolume, volume); +} + +void DfPlayer::PlayTrack(uint16_t track) { + if (track < 1 || track > 2999) { + return; + } + SendCommand(Command::kPlayTrack, track); +} diff --git a/Core/App/Common/df_player.hpp b/Core/App/Common/df_player.hpp new file mode 100644 index 0000000..7559239 --- /dev/null +++ b/Core/App/Common/df_player.hpp @@ -0,0 +1,63 @@ +#pragma once + +#include + +#include "../Common/serial_port.hpp" + +class DfPlayer { +public: + explicit DfPlayer(UART_HandleTypeDef* uart) : serialPort(new SerialPort(uart, kLength, kTimeout)) {} + + ~DfPlayer() { + delete serialPort; + } + + void Play(); + void Stop(); + void SetVolume(uint8_t volume); + void PlayTrack(uint16_t track); + +private: + enum class Command : uint8_t { + kNext = 0x01, + kPrevious = 0x02, + kPlayTrack = 0x03, + kVolumeUp = 0x04, + kVolumeDown = 0x05, + kSetVolume = 0x06, + kSetEQ = 0x07, + kSingleLoopPlayTrack = 0x08, + kSetPlaybackDevice = 0x09, + kEnterSleep = 0x0A, + kResetModule = 0x0C, + kPlay = 0x0D, + kPause = 0x0E, + kPlayFolderTrack = 0x0F, + kSetAmplification = 0x10, + kLoopAll = 0x11, + kPlayMp3FolderTrack = 0x12, + kInsertAd = 0x13, + kStopAdPlayBackground = 0x15, + kStop = 0x16, + kQueryStatus = 0x42, + kQueryVolume = 0x43, + kQueryEQ = 0x44, + kQueryUDiskTotalFiles = 0x47, + kQueryTFCardTotalFiles = 0x48, + kQueryFlashTotalFiles = 0x49, + kQueryUDiskCurrentTrack = 0x4B, + kQueryTFCardCurrentTrack = 0x4C, + kQueryFlashCurrentTrack = 0x4D, + }; + + static constexpr uint32_t kLength = 128; + static constexpr uint32_t kTimeout = 10; + SerialPort* serialPort; + + void SendCommand(Command cmd, uint16_t param = 0); + + static constexpr uint8_t kStartByte = 0x7E; + static constexpr uint8_t kVersion = 0xFF; + static constexpr uint8_t kFeedback = 0x00; + static constexpr uint8_t kEndByte = 0xEF; +}; diff --git a/Core/App/Common/serial_port.hpp b/Core/App/Common/serial_port.hpp index 60ab6df..0119eb1 100644 --- a/Core/App/Common/serial_port.hpp +++ b/Core/App/Common/serial_port.hpp @@ -29,7 +29,10 @@ public: char c; ReadByte(); while (true) { - HAL_UART_Receive(handle, reinterpret_cast(&c), sizeof(c), HAL_MAX_DELAY); + auto r = HAL_UART_Receive(handle, reinterpret_cast(&c), sizeof(c), timeout); + if (r != HAL_OK) { + throw std::runtime_error("UART receive error"); + } if (c == '\n') { if (!result.empty() && result.back() == '\r') { result.pop_back(); @@ -41,6 +44,13 @@ public: return result; } + void ReadBytesBlocking(uint8_t* data, size_t size) { + auto r = HAL_UART_Receive(handle, data, size, timeout); + if (r != HAL_OK) { + throw std::runtime_error("UART receive error"); + } + } + void WriteBytesBlocking(const uint8_t* data, size_t size) { HAL_UART_Transmit(handle, const_cast(data), size, timeout); } @@ -56,7 +66,7 @@ public: } HAL_UART_Transmit(handle, reinterpret_cast(buffer.get()), strlen(buffer.get()), timeout); } - + void WriteLineBlocking(const char* format, ...) { va_list args; va_start(args, format); diff --git a/Core/App/app.cpp b/Core/App/app.cpp index 37498d6..3346448 100644 --- a/Core/App/app.cpp +++ b/Core/App/app.cpp @@ -10,6 +10,8 @@ void Setup() { GpioHelper::EnableAllGpioPeripheral(); DelaySetup(); auto ultrasonic = CommonCenter::GetUltrasonic(); + auto dfPlayer = CommonCenter::GetDfPlayer(); + auto canMv = CommonCenter::GetCanMv(); } extern "C" void AppStart() { diff --git a/Core/App/config.hpp b/Core/App/config.hpp index 9e71dbe..17664d3 100644 --- a/Core/App/config.hpp +++ b/Core/App/config.hpp @@ -11,4 +11,8 @@ struct Config { TIM_HandleTypeDef* timer; uint32_t channel; } kCaptureConfig = {{GPIOA, GPIO_PIN_0}, &htim7, TIM_CHANNEL_1}; + + static inline UART_HandleTypeDef* kDfPlayerUart = &hcom_uart[COM1]; + + static inline UART_HandleTypeDef* kCanMvUart = &hcom_uart[COM1]; };