- 新增 HC-SR04 驱动与测距接口(bsp_sr04) - 增加循迹状态读取与输出,完善任务内日志 - 调整 CarCtrl 闭环更新周期,匹配霍尔测速周期,降低抖动 - 同步更新 CubeMX/CMake 生成配置与相关引脚定义
150 lines
4.2 KiB
C
150 lines
4.2 KiB
C
#include "bsp_hall.h"
|
||
#include "bsp_sr04.h"
|
||
|
||
|
||
/* 霍尔传感器数据结构体定义描述 */
|
||
static hall_sensor_t sensors[MOTOR_COUNT];
|
||
|
||
/**
|
||
* @brief 霍尔引脚初始化 (本驱动依赖 CubeMX 预设的 GPIO_EXTI 模式)
|
||
*/
|
||
void hall_init(void)
|
||
{
|
||
for(int i = 0; i < MOTOR_COUNT; i++) {
|
||
sensors[i].pulse_count = 0;
|
||
sensors[i].speed_rpm = 0.0f;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @brief HAL 层 GPIO 外部中断回调函数实现
|
||
* @note 此函数重写了 HAL 库中的 __weak 定义
|
||
*/
|
||
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
|
||
{
|
||
hall_pulse_callback(GPIO_Pin);
|
||
}
|
||
|
||
/**
|
||
* @brief 外部中断回调函数中的统计处理
|
||
*/
|
||
void hall_pulse_callback(uint16_t GPIO_Pin)
|
||
{
|
||
/* 只负责计数,不再在中断中进行浮点运算和日志打印 */
|
||
if (GPIO_Pin == M_I_1_Pin) {
|
||
sensors[MOTOR_1].pulse_count++;
|
||
} else if (GPIO_Pin == M_I_2_Pin) {
|
||
sensors[MOTOR_2].pulse_count++;
|
||
} else if (GPIO_Pin == M_I_3_Pin) {
|
||
sensors[MOTOR_3].pulse_count++;
|
||
} else if (GPIO_Pin == M_I_4_Pin) {
|
||
sensors[MOTOR_4].pulse_count++;
|
||
}
|
||
}
|
||
|
||
// /**
|
||
// * @brief 获取霍尔传感器脉冲计数
|
||
// */
|
||
// uint32_t hall_get_count(motor_id_t motor_id)
|
||
// {
|
||
// if (motor_id < MOTOR_COUNT) {
|
||
// return sensors[motor_id].pulse_count;
|
||
// }
|
||
// return 0;
|
||
// }
|
||
|
||
/**
|
||
* @brief 获取当前实时转速 (RPM)
|
||
*/
|
||
float hall_get_speed(motor_id_t motor_id)
|
||
{
|
||
if (motor_id < MOTOR_COUNT) {
|
||
return sensors[motor_id].speed_rpm;
|
||
}
|
||
return 0.0f;
|
||
}
|
||
|
||
// /**
|
||
// * @brief 重置霍尔传感器计数值
|
||
// */
|
||
// void hall_reset_count(motor_id_t motor_id)
|
||
// {
|
||
// if (motor_id < MOTOR_COUNT) {
|
||
// sensors[motor_id].pulse_count = 0;
|
||
// }
|
||
// }
|
||
|
||
/**
|
||
* @brief 计算并更新转速 (供应用层在定时任务中调用)
|
||
* @param motor_id 电机 ID
|
||
* @param interval_ms 两次调用之间的时间间隔 (ms)
|
||
* @return float 计算出的 RPM
|
||
*/
|
||
float hall_update_speed(motor_id_t motor_id, uint32_t interval_ms)
|
||
{
|
||
if (motor_id >= MOTOR_COUNT || interval_ms == 0) return 0.0f;
|
||
|
||
/* 获取当前增量并重置计数 */
|
||
uint32_t current_pulses = sensors[motor_id].pulse_count;
|
||
sensors[motor_id].pulse_count = 0;
|
||
|
||
/* PPR = 330. RPM = (增量脉冲 / 间隔ms) * 60000ms / PPR */
|
||
sensors[motor_id].speed_rpm = ((float)current_pulses / (float)interval_ms) * 60000.0f / 330.0f;
|
||
|
||
// /* 应用层打印日志 */
|
||
// log_i("Motor[%d] Real-time: %.2f RPM (pulses: %d)", motor_id + 1, sensors[motor_id].speed_rpm, current_pulses);
|
||
|
||
return sensors[motor_id].speed_rpm;
|
||
}
|
||
|
||
// /**
|
||
// * @brief 计算转速 (由于只有一根线,仅支持根据脉冲频率计算速度)
|
||
// */
|
||
// float hall_calculate_speed(motor_id_t motor_id, uint32_t interval_ms)
|
||
// {
|
||
// if (motor_id >= MOTOR_COUNT || interval_ms == 0) return 0.0f;
|
||
//
|
||
// /* 获取当前脉冲数 */
|
||
// uint32_t current_count = sensors[motor_id].pulse_count;
|
||
//
|
||
// /*
|
||
// * 计算 RPM (转每分钟)
|
||
// * 公式: (脉冲增量 / 采样时间ms) * 1000ms * 60s / PPR
|
||
// * 注意:由于此处没有传入上一次的 count,我们假设 interval_ms 是相对于 count=0 开始的,
|
||
// * 或者你可以在调用前手动 reset。这里先实现基础频率转换为 RPM 的逻辑。
|
||
// * 假设 PPR (每圈脉冲数) 暂定为 11 (常见磁平衡霍尔) * 30 (减速比) = 330
|
||
// */
|
||
// const float PPR = 330.0f;
|
||
// sensors[motor_id].speed_rpm = ((float)current_count / interval_ms) * 60000.0f / PPR;
|
||
//
|
||
// /* 输出日志:电机编号 + 转速 */
|
||
// // log_i("Motor[%d] speed: %.2f RPM", motor_id + 1, sensors[motor_id].speed_rpm);
|
||
//
|
||
// /* 计算完后为了下一次增量计算,通常需要重置计数,或者记录旧值。这里保持框架。 */
|
||
//
|
||
// return sensors[motor_id].speed_rpm;
|
||
// }
|
||
|
||
/* USER CODE BEGIN Header_speed_get */
|
||
/**
|
||
* @brief Function implementing the timerTask thread.
|
||
* @param argument: Not used
|
||
* @retval None
|
||
*/
|
||
/* USER CODE END Header_speed_get */
|
||
void speed_get(void *argument) {
|
||
/* USER CODE BEGIN speed_get */
|
||
/* Infinite loop */
|
||
|
||
for (;;) {
|
||
|
||
|
||
/* 在每 100ms 执行一次的任务中 */
|
||
for (int i = 0; i < MOTOR_COUNT; i++) {
|
||
hall_update_speed(i, 100);
|
||
}
|
||
osDelay(100); // 100ms
|
||
}
|
||
/* USER CODE END speed_get */
|
||
}
|