feat(CAN): 实现多节点CAN总线通信与节点ID管理功能
- 添加CAN调试宏定义,支持条件编译调试信息输出 - 实现节点ID相关功能,包括构建CAN ID、消息过滤、获取/设置节点ID - 支持Flash存储节点ID,提供加载和保存功能 - 实现节点ID设置和查询命令处理 - 更新CANFD发送函数使用节点ID构建发送ID - 添加消息过滤逻辑,只处理目标节点的消息 - 重构DMA中断服务程序,优化数据传输处理 - 替换printf为调试宏,便于生产环境控制调试输出
This commit is contained in:
@@ -11,12 +11,19 @@
|
||||
#include <cstring>
|
||||
#include <stdint.h>
|
||||
|
||||
// ANG_SENS 调试宏定义
|
||||
#if ANG_SENS_DEBUG
|
||||
#define ANG_SENS_DEBUG_PRINT(fmt, ...) printf(fmt, ##__VA_ARGS__)
|
||||
#else
|
||||
#define ANG_SENS_DEBUG_PRINT(fmt, ...) ((void)0)
|
||||
#endif
|
||||
|
||||
#define ANG_SPI_CS_ENABLE() gpio_bit_reset(GPIOA, GPIO_PIN_15)
|
||||
#define ANG_SPI_CS_DISABLE() gpio_bit_set(GPIOA, GPIO_PIN_15)
|
||||
#define DRV_SPI_CS_ENABLE() gpio_bit_reset(GPIOB, GPIO_PIN_14)
|
||||
#define DRV_SPI_CS_DISABLE() gpio_bit_set(GPIOB, GPIO_PIN_14)
|
||||
|
||||
// DMA传输完成标志
|
||||
// DMA 传输完成标志
|
||||
volatile bool spi_dma_tx_complete = false;
|
||||
volatile bool spi_dma_rx_complete = false;
|
||||
|
||||
@@ -24,7 +31,7 @@ angle_sensor KTH7823; // 角度传感器初始化
|
||||
extern FlashEEPROM flashEEP;
|
||||
extern EncoderAngleKalman Angle_kalman;
|
||||
extern EncoderVelocityKalman Vel_kalman;
|
||||
extern CAN_transmiter CAN0_transmiter; // CAN初始化
|
||||
extern CAN_transmiter CAN0_transmiter; // CAN 初始化
|
||||
|
||||
/**
|
||||
* @brief SPI DMA initialization
|
||||
@@ -32,10 +39,10 @@ extern CAN_transmiter CAN0_transmiter; // CAN初始化
|
||||
void spi_dma_init(void) {
|
||||
dma_parameter_struct dma_init_struct;
|
||||
|
||||
// 使能DMA时钟
|
||||
// 使能 DMA 时钟
|
||||
rcu_periph_clock_enable(RCU_DMA0);
|
||||
|
||||
// 初始化发送DMA通道
|
||||
// 初始化发送 DMA 通道
|
||||
dma_deinit(DMA0, DMA_CH2);
|
||||
dma_struct_para_init(&dma_init_struct);
|
||||
dma_init_struct.direction = DMA_MEMORY_TO_PERIPHERAL;
|
||||
@@ -49,7 +56,7 @@ void spi_dma_init(void) {
|
||||
dma_init_struct.priority = DMA_PRIORITY_HIGH;
|
||||
dma_init(DMA0, DMA_CH2, &dma_init_struct);
|
||||
|
||||
// 初始化接收DMA通道
|
||||
// 初始化接收 DMA 通道
|
||||
dma_deinit(DMA0, DMA_CH1);
|
||||
dma_struct_para_init(&dma_init_struct);
|
||||
dma_init_struct.direction = DMA_PERIPHERAL_TO_MEMORY;
|
||||
@@ -63,15 +70,15 @@ void spi_dma_init(void) {
|
||||
dma_init_struct.priority = DMA_PRIORITY_HIGH;
|
||||
dma_init(DMA0, DMA_CH1, &dma_init_struct);
|
||||
|
||||
// 使能SPI的DMA发送和接收功能
|
||||
// 使能 SPI 的 DMA 发送和接收功能
|
||||
spi_dma_enable(SPI0, SPI_DMA_TRANSMIT);
|
||||
spi_dma_enable(SPI0, SPI_DMA_RECEIVE);
|
||||
|
||||
// 配置DMA中断
|
||||
// 配置 DMA 中断
|
||||
nvic_irq_enable(DMA0_Channel2_IRQn, 0, 1);
|
||||
nvic_irq_enable(DMA0_Channel1_IRQn, 0, 1);
|
||||
|
||||
// 使能DMA传输完成中断
|
||||
// 使能 DMA 传输完成中断
|
||||
dma_interrupt_enable(DMA0, DMA_CH2, DMA_INT_FTF);
|
||||
dma_interrupt_enable(DMA0, DMA_CH1, DMA_INT_FTF);
|
||||
}
|
||||
@@ -90,30 +97,30 @@ int spi_rw_half_word_dma(uint32_t spi_periph, uint16_t tx_data,
|
||||
spi_dma_tx_complete = false;
|
||||
spi_dma_rx_complete = false;
|
||||
|
||||
// 配置发送DMA
|
||||
// 配置发送 DMA
|
||||
dma_channel_disable(DMA0, DMA_CH2);
|
||||
dma_memory_address_config(DMA0, DMA_CH2, (uint32_t)&tx_data);
|
||||
dma_transfer_number_config(DMA0, DMA_CH2, 1);
|
||||
dma_channel_enable(DMA0, DMA_CH2);
|
||||
|
||||
// 配置接收DMA
|
||||
// 配置接收 DMA
|
||||
dma_channel_disable(DMA0, DMA_CH1);
|
||||
dma_memory_address_config(DMA0, DMA_CH1, (uint32_t)rx_data);
|
||||
dma_transfer_number_config(DMA0, DMA_CH1, 1);
|
||||
dma_channel_enable(DMA0, DMA_CH1);
|
||||
|
||||
// 等待传输完成,超时时间为100个循环
|
||||
// 等待传输完成,超时时间为 100 个循环
|
||||
uint32_t timeout = 100;
|
||||
while ((!spi_dma_tx_complete || !spi_dma_rx_complete) && --timeout) {
|
||||
// 空循环等待DMA传输完成
|
||||
// 空循环等待 DMA 传输完成
|
||||
}
|
||||
|
||||
// 检查是否超时
|
||||
if (timeout == 0) {
|
||||
// 禁用DMA通道
|
||||
// 禁用 DMA 通道
|
||||
dma_channel_disable(DMA0, DMA_CH2);
|
||||
dma_channel_disable(DMA0, DMA_CH1);
|
||||
printf("SPI DMA transfer timeout\r\n");
|
||||
ANG_SENS_DEBUG_PRINT("SPI DMA transfer timeout\r\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -121,7 +128,7 @@ int spi_rw_half_word_dma(uint32_t spi_periph, uint16_t tx_data,
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA0_Channel2中断处理函数
|
||||
* @brief DMA0_Channel2 中断处理函数
|
||||
* @param 无
|
||||
*/
|
||||
extern "C" void DMA0_Channel2_IRQHandler(void) {
|
||||
@@ -132,7 +139,7 @@ extern "C" void DMA0_Channel2_IRQHandler(void) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA0_Channel1中断处理函数
|
||||
* @brief DMA0_Channel1 中断处理函数
|
||||
* @param 无
|
||||
*/
|
||||
extern "C" void DMA0_Channel1_IRQHandler(void) {
|
||||
@@ -174,7 +181,7 @@ void KTH7823_spi_init(void) {
|
||||
spi_parameter_struct spi_init_str;
|
||||
spi_struct_para_init(&spi_init_str);
|
||||
|
||||
/* SPI参数:16bit, 主机, 全双工, CPOL=1 CPHA=1, MSB first */
|
||||
/* SPI 参数:16bit, 主机,全双工,CPOL=1 CPHA=1, MSB first */
|
||||
spi_init_str.device_mode = SPI_MASTER;
|
||||
spi_init_str.trans_mode = SPI_TRANSMODE_FULLDUPLEX;
|
||||
spi_init_str.frame_size = SPI_FRAMESIZE_16BIT;
|
||||
@@ -194,16 +201,16 @@ void KTH7823_spi_init(void) {
|
||||
* @return 0:初始化成功 1:初始化失败
|
||||
*/
|
||||
u8 angle_sensor::init(void) {
|
||||
KTH7823_gpio_init(); // GPIO初始化
|
||||
KTH7823_spi_init(); // SPI初始化
|
||||
spi_dma_init(); // DMA初始化
|
||||
KTH7823_gpio_init(); // GPIO 初始化
|
||||
KTH7823_spi_init(); // SPI 初始化
|
||||
spi_dma_init(); // DMA 初始化
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @ 角度传感器类 设置当前角度
|
||||
* @param angle 输出级角度值
|
||||
* @return 0成功/1失败
|
||||
* @return 0 成功/1 失败
|
||||
*/
|
||||
u8 angle_sensor::angle_set(float angle) {
|
||||
m_cumulativeAngle = angle * REDUCTION_RATIO;
|
||||
@@ -230,10 +237,9 @@ inline float angle_sensor::read_sensorAngle(void) {
|
||||
return angle_deg;
|
||||
}
|
||||
|
||||
// 仅在调试模式下输出错误,避免发布版本中的I/O开销
|
||||
// 仅在调试模式下输出错误,避免发布版本中的 I/O 开销
|
||||
if (result != 0) {
|
||||
// 使用更高效的串口输出替代printf(如果可用)
|
||||
printf("Error reading angle from sensor.\n");
|
||||
ANG_SENS_DEBUG_PRINT("Error reading angle from sensor.\n");
|
||||
}
|
||||
|
||||
return (float)FAULT_RECEIVE;
|
||||
@@ -255,13 +261,13 @@ float angle_sensor::update(void) {
|
||||
// 计算角度变化
|
||||
float delta = current_angle_deg - m_lastAngle;
|
||||
|
||||
// 处理角度绕回情况(0度和360度之间的跳变)
|
||||
// 如果变化超过300度,说明发生了绕回
|
||||
// 处理角度绕回情况(0 度和 360 度之间的跳变)
|
||||
// 如果变化超过 300 度,说明发生了绕回
|
||||
if (delta > ANGLE_WRAP_THRESHOLD) {
|
||||
// 从接近360度绕回到接近0度
|
||||
// 从接近 360 度绕回到接近 0 度
|
||||
delta -= ANGLE_WRAP_VALUE;
|
||||
} else if (delta < -ANGLE_WRAP_THRESHOLD) {
|
||||
// 从接近0度绕到接近360度
|
||||
// 从接近 0 度绕到接近 360 度
|
||||
delta += ANGLE_WRAP_VALUE;
|
||||
}
|
||||
|
||||
@@ -271,7 +277,7 @@ float angle_sensor::update(void) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 获取累积角度值(输出级)
|
||||
* @brief 获取累积角度值 (输出级)
|
||||
* @return 累积角度值
|
||||
*/
|
||||
float angle_sensor::getAngle(void) const {
|
||||
@@ -279,15 +285,15 @@ float angle_sensor::getAngle(void) const {
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 获取累积角度值(原始级)
|
||||
* @brief 获取累积角度值 (原始级)
|
||||
* @return 累积角度值
|
||||
*/
|
||||
float angle_sensor::getRawAngle(void) const { return m_cumulativeAngle; }
|
||||
|
||||
/**
|
||||
* @brief 获取角度值(原始级)
|
||||
* @return 角度值(原始级)
|
||||
* @brief 获取角度值 (原始级)
|
||||
* @return 角度值 (原始级)
|
||||
*/
|
||||
float angle_sensor::getcurrent_sensorangle(void) const{
|
||||
return current_angle_deg;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user