#include "bsp_hall.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 */ }