更新
This commit is contained in:
parent
94c980caef
commit
dd7994b0b0
@ -81,6 +81,7 @@ target_sources(${CMAKE_PROJECT_NAME} PRIVATE
|
||||
User/device/supercap.c
|
||||
User/device/gimbal_imu.c
|
||||
User/device/referee.c
|
||||
User/device/buzzer.c
|
||||
# User/module sources
|
||||
User/module/chassis.c
|
||||
|
||||
|
||||
@ -99,7 +99,7 @@ void MX_TIM12_Init(void)
|
||||
htim12.Instance = TIM12;
|
||||
htim12.Init.Prescaler = 24-1;
|
||||
htim12.Init.CounterMode = TIM_COUNTERMODE_UP;
|
||||
htim12.Init.Period = 2500-1;
|
||||
htim12.Init.Period = 2000-1;
|
||||
htim12.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
|
||||
htim12.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
|
||||
if (HAL_TIM_Base_Init(&htim12) != HAL_OK)
|
||||
|
||||
171
User/device/buzzer.c
Normal file
171
User/device/buzzer.c
Normal file
@ -0,0 +1,171 @@
|
||||
#include "device/buzzer.h"
|
||||
#include "bsp/time.h"
|
||||
#include <math.h>
|
||||
|
||||
/* USER INCLUDE BEGIN */
|
||||
|
||||
/* USER INCLUDE END */
|
||||
|
||||
/* USER DEFINE BEGIN */
|
||||
|
||||
/* USER DEFINE END */
|
||||
|
||||
#define MUSIC_DEFAULT_VOLUME 0.5f
|
||||
#define MUSIC_A4_FREQ 440.0f // A4音符频率
|
||||
|
||||
/* USER MUSIC MENU BEGIN */
|
||||
// RM音乐
|
||||
const Tone_t RM[] = {
|
||||
{NOTE_B, 5, 200},
|
||||
{NOTE_G, 4, 200},
|
||||
{NOTE_B, 5, 400},
|
||||
{NOTE_G, 4, 200},
|
||||
{NOTE_B, 5, 400},
|
||||
{NOTE_G, 4, 200},
|
||||
{NOTE_D, 5, 400},
|
||||
{NOTE_G, 4, 200},
|
||||
{NOTE_C, 5, 200},
|
||||
{NOTE_C, 5, 200},
|
||||
{NOTE_G, 4, 200},
|
||||
{NOTE_B, 5, 200},
|
||||
{NOTE_C, 5, 200}
|
||||
};
|
||||
|
||||
// Nokia 经典铃声音符
|
||||
const Tone_t NOKIA[] = {
|
||||
{NOTE_E, 5, 125}, {NOTE_D, 5, 125}, {NOTE_FS, 4, 250}, {NOTE_GS, 4, 250},
|
||||
{NOTE_CS, 5, 125}, {NOTE_B, 4, 125}, {NOTE_D, 4, 250}, {NOTE_E, 4, 250},
|
||||
{NOTE_B, 4, 125}, {NOTE_A, 4, 125}, {NOTE_CS, 4, 250}, {NOTE_E, 4, 250},
|
||||
{NOTE_A, 4, 500}
|
||||
};
|
||||
/* USER MUSIC MENU END */
|
||||
|
||||
static void BUZZER_Update(BUZZER_t *buzzer){
|
||||
buzzer->header.online = true;
|
||||
buzzer->header.last_online_time = BSP_TIME_Get_ms();
|
||||
}
|
||||
|
||||
// 根据音符和八度计算频率的辅助函数
|
||||
static float BUZZER_CalcFreq(NOTE_t note, uint8_t octave) {
|
||||
if (note == NOTE_REST) {
|
||||
return 0.0f; // 休止符返回0频率
|
||||
}
|
||||
|
||||
// 将音符和八度转换为MIDI音符编号
|
||||
int midi_num = (int)note + (int)((octave + 1) * 12);
|
||||
|
||||
// 使用A4 (440Hz) 作为参考,计算频率
|
||||
// 公式: freq = 440 * 2^((midi_num - 69)/12)
|
||||
float freq = 440.0f * powf(2.0f, ((float)midi_num - 69.0f) / 12.0f);
|
||||
|
||||
return freq;
|
||||
}
|
||||
|
||||
// 播放单个音符
|
||||
static int8_t BUZZER_PlayTone(BUZZER_t *buzzer, NOTE_t note, uint8_t octave, uint16_t duration_ms) {
|
||||
if (buzzer == NULL || !buzzer->header.online)
|
||||
return DEVICE_ERR;
|
||||
|
||||
float freq = BUZZER_CalcFreq(note, octave);
|
||||
|
||||
if (freq > 0.0f) {
|
||||
// 播放音符
|
||||
if (BUZZER_Set(buzzer, freq, MUSIC_DEFAULT_VOLUME) != DEVICE_OK)
|
||||
return DEVICE_ERR;
|
||||
|
||||
if (BUZZER_Start(buzzer) != DEVICE_OK)
|
||||
return DEVICE_ERR;
|
||||
} else {
|
||||
// 休止符,停止播放
|
||||
BUZZER_Stop(buzzer);
|
||||
}
|
||||
|
||||
// 等待指定时间
|
||||
BSP_TIME_Delay_ms(duration_ms);
|
||||
|
||||
// 停止当前音符,为下一个音符做准备
|
||||
BUZZER_Stop(buzzer);
|
||||
BSP_TIME_Delay_ms(20); // 短暂间隔
|
||||
|
||||
return DEVICE_OK;
|
||||
}
|
||||
|
||||
int8_t BUZZER_Init(BUZZER_t *buzzer, BSP_PWM_Channel_t channel) {
|
||||
if (buzzer == NULL) return DEVICE_ERR;
|
||||
|
||||
buzzer->channel = channel;
|
||||
buzzer->header.online = true;
|
||||
|
||||
BUZZER_Stop(buzzer);
|
||||
|
||||
return DEVICE_OK ;
|
||||
}
|
||||
|
||||
int8_t BUZZER_Start(BUZZER_t *buzzer) {
|
||||
if (buzzer == NULL || !buzzer->header.online)
|
||||
return DEVICE_ERR;
|
||||
BUZZER_Update(buzzer);
|
||||
return (BSP_PWM_Start(buzzer->channel) == BSP_OK) ?
|
||||
DEVICE_OK : DEVICE_ERR;
|
||||
}
|
||||
|
||||
int8_t BUZZER_Stop(BUZZER_t *buzzer) {
|
||||
if (buzzer == NULL || !buzzer->header.online)
|
||||
return DEVICE_ERR;
|
||||
BUZZER_Update(buzzer);
|
||||
return (BSP_PWM_Stop(buzzer->channel) == BSP_OK) ?
|
||||
DEVICE_OK : DEVICE_ERR;
|
||||
}
|
||||
|
||||
int8_t BUZZER_Set(BUZZER_t *buzzer, float freq, float duty_cycle) {
|
||||
if (buzzer == NULL || !buzzer->header.online)
|
||||
return DEVICE_ERR;
|
||||
|
||||
int result = DEVICE_OK ;
|
||||
BUZZER_Update(buzzer);
|
||||
if (BSP_PWM_SetFreq(buzzer->channel, freq) != BSP_OK)
|
||||
result = DEVICE_ERR;
|
||||
|
||||
if (BSP_PWM_SetComp(buzzer->channel, duty_cycle) != BSP_OK)
|
||||
result = DEVICE_ERR;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int8_t BUZZER_PlayMusic(BUZZER_t *buzzer, MUSIC_t music) {
|
||||
if (buzzer == NULL || !buzzer->header.online)
|
||||
return DEVICE_ERR;
|
||||
|
||||
const Tone_t *melody = NULL;
|
||||
size_t melody_length = 0;
|
||||
|
||||
// 根据音乐类型选择对应的音符数组
|
||||
switch (music) {
|
||||
case MUSIC_RM:
|
||||
melody = RM;
|
||||
melody_length = sizeof(RM) / sizeof(Tone_t);
|
||||
break;
|
||||
case MUSIC_NOKIA:
|
||||
melody = NOKIA;
|
||||
melody_length = sizeof(NOKIA) / sizeof(Tone_t);
|
||||
break;
|
||||
default:
|
||||
return DEVICE_ERR;
|
||||
}
|
||||
|
||||
// 播放整首音乐
|
||||
for (size_t i = 0; i < melody_length; i++) {
|
||||
if (BUZZER_PlayTone(buzzer, melody[i].note, melody[i].octave, melody[i].duration_ms) != DEVICE_OK) {
|
||||
BUZZER_Stop(buzzer); // 出错时停止播放
|
||||
return DEVICE_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
// 音乐播放完成后停止
|
||||
BUZZER_Stop(buzzer);
|
||||
return DEVICE_OK;
|
||||
}
|
||||
|
||||
/* USER FUNCTION BEGIN */
|
||||
|
||||
/* USER FUNCTION END */
|
||||
138
User/device/buzzer.h
Normal file
138
User/device/buzzer.h
Normal file
@ -0,0 +1,138 @@
|
||||
/**
|
||||
* @file buzzer.h
|
||||
* @brief 蜂鸣器设备驱动头文件
|
||||
* @details 提供蜂鸣器音频播放功能,支持单音符播放和预设音乐播放
|
||||
* @author Generated by STM32CubeMX
|
||||
* @date 2025年10月23日
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ----------------------------------------------------------------- */
|
||||
#include "bsp/pwm.h" // PWM底层硬件抽象层
|
||||
#include "device.h" // 设备通用头文件
|
||||
#include <stddef.h> // 标准定义
|
||||
#include <stdint.h> // 标准整型定义
|
||||
|
||||
/* USER INCLUDE BEGIN */
|
||||
|
||||
/* USER INCLUDE END */
|
||||
|
||||
/* Exported constants ------------------------------------------------------- */
|
||||
|
||||
/* USER DEFINE BEGIN */
|
||||
|
||||
/* USER DEFINE END */
|
||||
|
||||
/* Exported types ----------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief 音符枚举类型
|
||||
* @details 定义标准十二平均律音符,用于音乐播放
|
||||
*/
|
||||
typedef enum {
|
||||
NOTE_C = 0, ///< Do音符
|
||||
NOTE_CS = 1, ///< Do#音符 (升Do)
|
||||
NOTE_D = 2, ///< Re音符
|
||||
NOTE_DS = 3, ///< Re#音符 (升Re)
|
||||
NOTE_E = 4, ///< Mi音符
|
||||
NOTE_F = 5, ///< Fa音符
|
||||
NOTE_FS = 6, ///< Fa#音符 (升Fa)
|
||||
NOTE_G = 7, ///< Sol音符
|
||||
NOTE_GS = 8, ///< Sol#音符 (升Sol)
|
||||
NOTE_A = 9, ///< La音符
|
||||
NOTE_AS = 10, ///< La#音符 (升La)
|
||||
NOTE_B = 11, ///< Si音符
|
||||
NOTE_REST = 255 ///< 休止符 (无声音)
|
||||
} NOTE_t;
|
||||
|
||||
/**
|
||||
* @brief 音调结构体
|
||||
* @details 定义一个完整的音调信息,包括音符、八度和持续时间
|
||||
*/
|
||||
typedef struct {
|
||||
NOTE_t note; ///< 音符名称 (使用NOTE_t枚举)
|
||||
uint8_t octave; ///< 八度 (0-8,通常使用3-7)
|
||||
uint16_t duration_ms; ///< 持续时间,单位毫秒
|
||||
} Tone_t;
|
||||
|
||||
/**
|
||||
* @brief 预设音乐枚举类型
|
||||
* @details 定义可播放的预设音乐类型
|
||||
*/
|
||||
typedef enum {
|
||||
/* USER MUSIC MENU BEGIN */
|
||||
MUSIC_RM, ///< RM战队音乐
|
||||
MUSIC_NOKIA, ///< 诺基亚经典铃声
|
||||
/* USER MUSIC MENU END */
|
||||
} MUSIC_t;
|
||||
|
||||
/**
|
||||
* @brief 蜂鸣器设备结构体
|
||||
* @details 蜂鸣器设备的完整描述,包含设备头信息和PWM通道
|
||||
*/
|
||||
typedef struct {
|
||||
DEVICE_Header_t header; ///< 设备通用头信息 (在线状态、时间戳等)
|
||||
BSP_PWM_Channel_t channel; ///< PWM输出通道
|
||||
} BUZZER_t;
|
||||
|
||||
/* USER STRUCT BEGIN */
|
||||
|
||||
/* USER STRUCT END */
|
||||
|
||||
/* Exported functions prototypes -------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief 初始化蜂鸣器设备
|
||||
* @param buzzer 蜂鸣器设备结构体指针
|
||||
* @param channel PWM输出通道
|
||||
* @return int8_t 返回值:DEVICE_OK(0) 成功,DEVICE_ERR(-1) 失败
|
||||
* @note 初始化后蜂鸣器处于停止状态
|
||||
*/
|
||||
int8_t BUZZER_Init(BUZZER_t *buzzer, BSP_PWM_Channel_t channel);
|
||||
|
||||
/**
|
||||
* @brief 启动蜂鸣器播放
|
||||
* @param buzzer 蜂鸣器设备结构体指针
|
||||
* @return int8_t 返回值:DEVICE_OK(0) 成功,DEVICE_ERR(-1) 失败
|
||||
* @note 需要先调用BUZZER_Set设置频率和占空比
|
||||
*/
|
||||
int8_t BUZZER_Start(BUZZER_t *buzzer);
|
||||
|
||||
/**
|
||||
* @brief 停止蜂鸣器播放
|
||||
* @param buzzer 蜂鸣器设备结构体指针
|
||||
* @return int8_t 返回值:DEVICE_OK(0) 成功,DEVICE_ERR(-1) 失败
|
||||
*/
|
||||
int8_t BUZZER_Stop(BUZZER_t *buzzer);
|
||||
|
||||
/**
|
||||
* @brief 设置蜂鸣器频率和占空比
|
||||
* @param buzzer 蜂鸣器设备结构体指针
|
||||
* @param freq 频率 (Hz),通常范围20Hz-20kHz
|
||||
* @param duty_cycle 占空比 (0.0-1.0),影响音量大小
|
||||
* @return int8_t 返回值:DEVICE_OK(0) 成功,DEVICE_ERR(-1) 失败
|
||||
* @note 设置后需要调用BUZZER_Start才能听到声音
|
||||
*/
|
||||
int8_t BUZZER_Set(BUZZER_t *buzzer, float freq, float duty_cycle);
|
||||
|
||||
/**
|
||||
* @brief 播放预设音乐
|
||||
* @param buzzer 蜂鸣器设备结构体指针
|
||||
* @param music 音乐类型 (使用MUSIC_t枚举)
|
||||
* @return int8_t 返回值:DEVICE_OK(0) 成功,DEVICE_ERR(-1) 失败
|
||||
* @note 这是一个阻塞函数,会播放完整首音乐后返回
|
||||
*/
|
||||
int8_t BUZZER_PlayMusic(BUZZER_t *buzzer, MUSIC_t music);
|
||||
|
||||
/* USER FUNCTION BEGIN */
|
||||
|
||||
/* USER FUNCTION END */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@ -30,7 +30,6 @@
|
||||
#define DR16_CH_VALUE_MIN (364u)
|
||||
#define DR16_CH_VALUE_MID (1024u)
|
||||
#define DR16_CH_VALUE_MAX (1684u)
|
||||
//#define DR16_FRAME_SIZE (18u) // DR16数据帧固定18字节
|
||||
|
||||
/* USER DEFINE BEGIN */
|
||||
|
||||
@ -42,29 +41,25 @@
|
||||
|
||||
static osThreadId_t thread_alert;
|
||||
static bool inited = false;
|
||||
static DR16_t *dr16_instance = NULL; /* 用于空闲中断回调中访问实例 */
|
||||
static uint8_t sync_buf[32]; /* 帧同步时的丢弃缓冲区 */
|
||||
|
||||
/* Private function -------------------------------------------------------- */
|
||||
static void DR16_RxCpltCallback(void) {
|
||||
osThreadFlagsSet(thread_alert, SIGNAL_DR16_RAW_REDY);
|
||||
}
|
||||
|
||||
//static void DR16_ErrorCallback(void) {
|
||||
// UART_HandleTypeDef *huart = BSP_UART_GetHandle(BSP_UART_RC);
|
||||
//
|
||||
// // 清除所有错误标志(包括FIFO错误)
|
||||
// __HAL_UART_CLEAR_OREFLAG(huart);
|
||||
// __HAL_UART_CLEAR_NEFLAG(huart);
|
||||
// __HAL_UART_CLEAR_FEFLAG(huart);
|
||||
// __HAL_UART_CLEAR_PEFLAG(huart);
|
||||
//
|
||||
// // 清除FIFO超时标志(STM32H7特有)
|
||||
// if (__HAL_UART_GET_FLAG(huart, UART_FLAG_RTOF)) {
|
||||
// __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_RTOF);
|
||||
// }
|
||||
//
|
||||
// // 中止并清除当前DMA传输
|
||||
// HAL_UART_AbortReceive(huart);
|
||||
//}
|
||||
/**
|
||||
* @brief 空闲中断回调 - 用于帧同步
|
||||
* 空闲中断表示一帧传输结束(总线空闲),此时停止当前DMA接收,
|
||||
* 丢弃不完整的数据,这样下一次 StartDmaRecv 就能从帧头开始。
|
||||
*/
|
||||
static void DR16_IdleCallback(void) {
|
||||
/* 停止当前DMA接收(无论收了多少字节) */
|
||||
HAL_UART_AbortReceive(BSP_UART_GetHandle(BSP_UART_RC));
|
||||
/* 通知任务:可以启动下一次对齐的接收了 */
|
||||
osThreadFlagsSet(thread_alert, SIGNAL_DR16_RAW_REDY);
|
||||
}
|
||||
|
||||
static bool DR16_DataCorrupted(const DR16_t *dr16) {
|
||||
if (dr16 == NULL) return DEVICE_ERR_NULL;
|
||||
@ -98,45 +93,55 @@ int8_t DR16_Init(DR16_t *dr16) {
|
||||
if (inited) return DEVICE_ERR_INITED;
|
||||
if ((thread_alert = osThreadGetId()) == NULL) return DEVICE_ERR_NULL;
|
||||
|
||||
// // 清零结构体
|
||||
// memset(dr16, 0, sizeof(DR16_t));
|
||||
dr16_instance = dr16;
|
||||
|
||||
/* 注册 DMA 接收完成回调 */
|
||||
BSP_UART_RegisterCallback(BSP_UART_RC, BSP_UART_RX_CPLT_CB,
|
||||
DR16_RxCpltCallback);
|
||||
// BSP_UART_RegisterCallback(BSP_UART_RC, BSP_UART_ERROR_CB,
|
||||
// DR16_ErrorCallback);
|
||||
|
||||
/* 注册空闲中断回调并使能空闲中断,用于帧同步 */
|
||||
BSP_UART_RegisterCallback(BSP_UART_RC, BSP_UART_IDLE_LINE_CB,
|
||||
DR16_IdleCallback);
|
||||
__HAL_UART_ENABLE_IT(BSP_UART_GetHandle(BSP_UART_RC), UART_IT_IDLE);
|
||||
|
||||
/*
|
||||
* 首次帧同步:启动一次丢弃式DMA接收。
|
||||
* 如果遥控器已经在发送,DMA会从帧中间开始收,空闲中断到来时
|
||||
* IdleCallback 会 Abort 这次接收并通知任务,下一次 StartDmaRecv
|
||||
* 就能从完整帧头开始。
|
||||
*/
|
||||
HAL_UART_Receive_DMA(BSP_UART_GetHandle(BSP_UART_RC),
|
||||
sync_buf, sizeof(sync_buf));
|
||||
/* 等待空闲中断完成首次同步(最多50ms,足够等一帧) */
|
||||
osThreadFlagsWait(SIGNAL_DR16_RAW_REDY, osFlagsWaitAll, 50);
|
||||
|
||||
inited = true;
|
||||
return DEVICE_OK;
|
||||
}
|
||||
|
||||
int8_t DR16_Restart(void) {
|
||||
__HAL_UART_DISABLE(BSP_UART_GetHandle(BSP_UART_RC));
|
||||
__HAL_UART_ENABLE(BSP_UART_GetHandle(BSP_UART_RC));
|
||||
UART_HandleTypeDef *huart = BSP_UART_GetHandle(BSP_UART_RC);
|
||||
|
||||
/* 先终止当前DMA接收 */
|
||||
HAL_UART_AbortReceive(huart);
|
||||
|
||||
/* 重置串口 */
|
||||
__HAL_UART_DISABLE(huart);
|
||||
__HAL_UART_ENABLE(huart);
|
||||
|
||||
/* 重新使能空闲中断 */
|
||||
__HAL_UART_ENABLE_IT(huart, UART_IT_IDLE);
|
||||
|
||||
/* 重新做帧同步:丢弃式接收,等空闲中断对齐 */
|
||||
HAL_UART_Receive_DMA(huart, sync_buf, sizeof(sync_buf));
|
||||
osThreadFlagsWait(SIGNAL_DR16_RAW_REDY, osFlagsWaitAll, 50);
|
||||
|
||||
return DEVICE_OK;
|
||||
}
|
||||
|
||||
int8_t DR16_StartDmaRecv(DR16_t *dr16) {
|
||||
UART_HandleTypeDef *huart = BSP_UART_GetHandle(BSP_UART_RC);
|
||||
|
||||
// // 确保之前的DMA接收已停止
|
||||
// if (huart->RxState != HAL_UART_STATE_READY) {
|
||||
// HAL_UART_AbortReceive(huart);
|
||||
// }
|
||||
//
|
||||
// // 清除所有可能的错误标志和IDLE标志
|
||||
// __HAL_UART_CLEAR_OREFLAG(huart);
|
||||
// __HAL_UART_CLEAR_NEFLAG(huart);
|
||||
// __HAL_UART_CLEAR_FEFLAG(huart);
|
||||
// __HAL_UART_CLEAR_PEFLAG(huart);
|
||||
// __HAL_UART_CLEAR_IDLEFLAG(huart);
|
||||
//
|
||||
// // 清除FIFO超时标志
|
||||
// if (__HAL_UART_GET_FLAG(huart, UART_FLAG_RTOF)) {
|
||||
// __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_RTOF);
|
||||
// }
|
||||
|
||||
if (HAL_UART_Receive_DMA(huart, (uint8_t *)&(dr16->raw_data),
|
||||
if (HAL_UART_Receive_DMA(BSP_UART_GetHandle(BSP_UART_RC),
|
||||
(uint8_t *)&(dr16->raw_data),
|
||||
sizeof(dr16->raw_data)) == HAL_OK)
|
||||
return DEVICE_OK;
|
||||
return DEVICE_ERR;
|
||||
@ -150,17 +155,9 @@ bool DR16_WaitDmaCplt(uint32_t timeout) {
|
||||
int8_t DR16_ParseData(DR16_t *dr16){
|
||||
if (dr16 == NULL) return DEVICE_ERR_NULL;
|
||||
|
||||
// // STM32H7 D-Cache一致性处理:使DMA接收的数据对CPU可见
|
||||
// // D-Cache按32字节对齐,需要对齐处理
|
||||
// uint32_t addr = (uint32_t)&(dr16->raw_data);
|
||||
// uint32_t size = sizeof(dr16->raw_data);
|
||||
// // 向下对齐到32字节边界
|
||||
// uint32_t aligned_addr = addr & ~0x1FU;
|
||||
// // 计算对齐后的大小
|
||||
// uint32_t aligned_size = ((size + (addr - aligned_addr) + 31) & ~0x1FU);
|
||||
// SCB_InvalidateDCache_by_Addr((uint32_t *)aligned_addr, aligned_size);
|
||||
|
||||
if (DR16_DataCorrupted(dr16)) {
|
||||
/* 数据损坏说明帧错位了,重启串口并重新同步 */
|
||||
DR16_Restart();
|
||||
return DEVICE_ERR;
|
||||
}
|
||||
|
||||
|
||||
@ -36,9 +36,6 @@ typedef struct __packed {
|
||||
uint16_t key;
|
||||
uint16_t res;
|
||||
} DR16_RawData_t;
|
||||
// typedef struct __packed {
|
||||
// uint8_t buff[18]; // 原始接收缓冲区
|
||||
// } DR16_RawData_t;
|
||||
|
||||
typedef enum {
|
||||
DR16_SW_ERR = 0,
|
||||
@ -89,8 +86,9 @@ typedef struct {
|
||||
bool r_click; /* 右键 */
|
||||
} mouse; /* 鼠标值 */
|
||||
|
||||
struct {
|
||||
union {
|
||||
bool key[DR16_KEY_NUM]; /* 键盘按键值 */
|
||||
uint16_t value; /* 键盘按键值的位映射 */
|
||||
} keyboard;
|
||||
|
||||
uint16_t res; /* 保留,未启用 */
|
||||
|
||||
@ -237,10 +237,11 @@ static void CMD_NUC_BuildShootCmd(CMD_t *ctx) {
|
||||
ctx->output.shoot.cmd.firecmd = false;
|
||||
break;
|
||||
case 2:
|
||||
if (ctx->input.rc.sw[1]==CMD_SW_DOWN) {
|
||||
if ((ctx->active_source == CMD_SRC_PC && ctx->input.pc.mouse.l_click) ||
|
||||
(ctx->active_source == CMD_SRC_RC && ctx->input.rc.sw[1] == CMD_SW_DOWN)) {
|
||||
ctx->output.shoot.cmd.ready = true;
|
||||
ctx->output.shoot.cmd.firecmd = true;
|
||||
}else {
|
||||
} else {
|
||||
ctx->output.shoot.cmd.ready = true;
|
||||
ctx->output.shoot.cmd.firecmd = false;
|
||||
}
|
||||
|
||||
@ -49,14 +49,6 @@ int8_t CMD_Behavior_Handle_ACCELERATE(CMD_t *ctx) {
|
||||
return CMD_OK;
|
||||
}
|
||||
|
||||
int8_t CMD_Behavior_Handle_DECELERATE(CMD_t *ctx) {
|
||||
#if CMD_ENABLE_MODULE_CHASSIS
|
||||
ctx->output.chassis.cmd.ctrl_vec.vx *= ctx->config->sensitivity.move_slow_mult;
|
||||
ctx->output.chassis.cmd.ctrl_vec.vy *= ctx->config->sensitivity.move_slow_mult;
|
||||
#endif
|
||||
return CMD_OK;
|
||||
}
|
||||
|
||||
int8_t CMD_Behavior_Handle_FIRE(CMD_t *ctx) {
|
||||
#if CMD_ENABLE_MODULE_SHOOT
|
||||
ctx->output.shoot.cmd.firecmd = true;
|
||||
@ -132,6 +124,12 @@ int8_t CMD_Behavior_Handle_CHECKSOURCERCPC(CMD_t *ctx) {
|
||||
return CMD_OK;
|
||||
}
|
||||
|
||||
extern bool reset;
|
||||
int8_t CMD_Behavior_Handle_RESET(CMD_t *ctx) {
|
||||
reset = !reset;
|
||||
return CMD_OK;
|
||||
}
|
||||
|
||||
/* 行为配置表 - 由宏生成 */
|
||||
static const CMD_BehaviorConfig_t g_behavior_configs[] = {
|
||||
CMD_BEHAVIOR_TABLE(BUILD_BEHAVIOR_CONFIG)
|
||||
|
||||
@ -253,13 +253,13 @@ typedef enum {
|
||||
X(LEFT, CMD_KEY_A, CMD_ACTIVE_PRESSED, CMD_MODULE_CHASSIS) \
|
||||
X(RIGHT, CMD_KEY_D, CMD_ACTIVE_PRESSED, CMD_MODULE_CHASSIS) \
|
||||
X(ACCELERATE, CMD_KEY_SHIFT, CMD_ACTIVE_PRESSED, CMD_MODULE_CHASSIS) \
|
||||
X(DECELERATE, CMD_KEY_CTRL, CMD_ACTIVE_PRESSED, CMD_MODULE_CHASSIS) \
|
||||
X(FIRE, CMD_KEY_L_CLICK, CMD_ACTIVE_PRESSED, CMD_MODULE_SHOOT) \
|
||||
X(FIRE_MODE, CMD_KEY_B, CMD_ACTIVE_RISING_EDGE, CMD_MODULE_SHOOT) \
|
||||
X(ROTOR, CMD_KEY_E, CMD_ACTIVE_PRESSED, CMD_MODULE_CHASSIS) \
|
||||
X(ROTOR, CMD_KEY_CTRL, CMD_ACTIVE_PRESSED, CMD_MODULE_CHASSIS) \
|
||||
X(AUTOAIM, CMD_KEY_R_CLICK, CMD_ACTIVE_PRESSED, CMD_MODULE_NONE) \
|
||||
X(CHECKSOURCERCPC, CMD_KEY_CTRL|CMD_KEY_SHIFT|CMD_KEY_V, CMD_ACTIVE_RISING_EDGE, CMD_MODULE_NONE)
|
||||
/* 触发类型 */
|
||||
X(CHECKSOURCERCPC, CMD_KEY_CTRL|CMD_KEY_SHIFT|CMD_KEY_V, CMD_ACTIVE_RISING_EDGE, CMD_MODULE_NONE)\
|
||||
X(RESET, CMD_KEY_CTRL|CMD_KEY_SHIFT|CMD_KEY_G, CMD_ACTIVE_RISING_EDGE, CMD_MODULE_NONE)
|
||||
/* 触发类型 */
|
||||
typedef enum {
|
||||
CMD_ACTIVE_PRESSED, /* 按住时触发 */
|
||||
CMD_ACTIVE_RISING_EDGE, /* 按下瞬间触发 */
|
||||
|
||||
@ -974,7 +974,7 @@ int8_t Shoot_Control(Shoot_t *s, Shoot_CMD_t *cmd)
|
||||
Shoot_CaluTargetRPM(s,233);
|
||||
|
||||
/* 运行热量检测状态机 */
|
||||
// Shoot_HeatDetectionFSM(s);
|
||||
Shoot_HeatDetectionFSM(s);
|
||||
|
||||
/* 运行卡弹检测状态机 */
|
||||
Shoot_JamDetectionFSM(s, cmd);
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
/* USER INCLUDE BEGIN */
|
||||
#include "bsp/pwm.h"
|
||||
#include <math.h>
|
||||
#include "device/buzzer.h"
|
||||
/* USER INCLUDE END */
|
||||
|
||||
/* Private typedef ---------------------------------------------------------- */
|
||||
@ -15,7 +16,9 @@
|
||||
/* Private macro ------------------------------------------------------------ */
|
||||
/* Private variables -------------------------------------------------------- */
|
||||
/* USER STRUCT BEGIN */
|
||||
|
||||
BUZZER_t buzzer;
|
||||
static uint16_t count;
|
||||
bool reset=0;
|
||||
/* USER STRUCT END */
|
||||
|
||||
/* Private function --------------------------------------------------------- */
|
||||
@ -31,14 +34,27 @@ void Task_blink(void *argument) {
|
||||
|
||||
uint32_t tick = osKernelGetTickCount(); /* 控制任务运行频率的计时 */
|
||||
/* USER CODE INIT BEGIN */
|
||||
|
||||
BUZZER_Init(&buzzer, BSP_PWM_BUZZER);
|
||||
/* USER CODE INIT END */
|
||||
|
||||
while (1) {
|
||||
tick += delay_tick; /* 计算下一个唤醒时刻 */
|
||||
/* USER CODE BEGIN */
|
||||
// 呼吸灯 - 基于tick的正弦波
|
||||
// float duty = (sinf(tick * 0.003f) + 1.0f) * 0.5f; // 0到1之间的正弦波,加快频率
|
||||
count++;
|
||||
uint16_t phase = count % 1000;
|
||||
if (count == 1001) count = 1;
|
||||
if (phase == 0) {
|
||||
/* 每秒开始播放C4音符 */
|
||||
BUZZER_Set(&buzzer, 261.63f, 0.5f); // C4音符频率约261.63Hz
|
||||
BUZZER_Start(&buzzer);
|
||||
} else if (phase == 50) {
|
||||
/* 播放100ms后停止 (50/500Hz = 0.1s) */
|
||||
BUZZER_Stop(&buzzer);
|
||||
}
|
||||
if (reset) {
|
||||
__set_FAULTMASK(1); /* 关闭所有中断 */
|
||||
NVIC_SystemReset(); /* 系统复位 */
|
||||
}
|
||||
/* USER CODE END */
|
||||
osDelayUntil(tick); /* 运行结束,等待下一次唤醒 */
|
||||
}
|
||||
|
||||
@ -31,7 +31,11 @@
|
||||
// 将DR16变量放到RAM_D1 (0x24000000),用于DMA传输
|
||||
// __attribute__((section(".ram_d1"))) __attribute__((aligned(32)))
|
||||
DR16_t dr16;
|
||||
static DR16_SwitchPos_t last_sw_l = DR16_SW_ERR; /* 记录左拨杆上一次状态 */
|
||||
#endif
|
||||
|
||||
extern bool reset;
|
||||
#include "stm32h7xx.h"
|
||||
/* USER STRUCT END */
|
||||
|
||||
/* Private function --------------------------------------------------------- */
|
||||
@ -78,6 +82,16 @@ void Task_rc(void *argument) {
|
||||
osMessageQueuePut(task_runtime.msgq.cmd.rc, &dr16, 0, 0);
|
||||
// 启动下一次DMA接收
|
||||
DR16_StartDmaRecv(&dr16);
|
||||
/* 检测左拨杆切换到UP位置时触发软件复位 */
|
||||
if (dr16.header.online) {
|
||||
/* 拨杆从非UP状态切换到UP状态,且复位功能已使能,触发系统复位 */
|
||||
if (
|
||||
dr16.data.sw_l == DR16_SW_UP &&
|
||||
last_sw_l != DR16_SW_UP) {
|
||||
reset=!reset;
|
||||
}
|
||||
last_sw_l = dr16.data.sw_l; /* 更新拨杆状态 */
|
||||
}
|
||||
#endif
|
||||
/* USER CODE END */
|
||||
osDelayUntil(tick); /* 运行结束,等待下一次唤醒 */
|
||||
|
||||
Loading…
Reference in New Issue
Block a user