/** * @file device/ang_sensor.h * @brief 底层设备驱动与外设封装源文件 * @note 本文件仅补充 Doxygen 文档注释,不改变代码逻辑。 */ #ifndef _angsensor_H #define _angsensor_H #ifdef __cplusplus extern "C" { #endif #include "gd32c10x_eval.h" #include #include "config.h" /** * @brief spi_rw_half_word 函数 * @param[in] spi_periph 参数 * @param[in] i_HalfWord 参数 * @return u16 返回值 */ u16 spi_rw_half_word(u32 spi_periph, const u16 i_HalfWord); /** * @brief spi_rw_half_word_polling 函数 * @param[in] spi_periph SPI 外设 * @param[in] tx_data 发送的半字 * @param[out] rx_data 接收数据输出指针 * @return int 0 成功,-1 超时 * @note 单个半字收发:直接寄存器轮询。原 DMA 实现每次传输要重配两个 * DMA 通道并触发两次 FTF 中断,之后 CPU 仍忙等完成——对单半字 * 传输 DMA 只有开销没有收益(20kHz 调用下约 40k 次/秒额外中断)。 */ int spi_rw_half_word_polling(uint32_t spi_periph, uint16_t tx_data, uint16_t *rx_data); /** * @brief angle_sensor 类或结构体 */ class angle_sensor { public: float calibration_angle = ANGLESENS_CALIBRATION_ANGLE; /** * @brief 初始化对象或模块 * @return u8 返回值 */ u8 init(void); /** * @brief 读取 read_sensorAngle 相关数据 * @return float 返回值 */ float read_sensorAngle(void); /** * @brief 更新对象内部状态或采样数据 * @return float 返回值 */ float update(void); /** * @brief 复位对象内部状态 * @return void */ void reset(void); /** * @brief 获取 getAngle 对应的数据或状态 * @return float 返回值 */ float getAngle(void) const; /** * @brief 获取 getRawAngle 对应的数据或状态 * @return float 返回值 */ float getRawAngle(void) const; /** * @brief 获取 getcurrent_sensorangle 对应的数据或状态 * @return float 返回值 */ float getcurrent_sensorangle(void) const; /** * @brief angle_set 函数 * @param[in] angle 参数 * @return u8 返回值 */ u8 angle_set(float angle); /** * @brief 设置 set_calibration 对应的参数或状态 * @param[in] angle 参数 * @return u8 返回值 */ u8 set_calibration(float angle); protected: float m_cumulativeAngle; float current_angle_deg; float current_angle_rad; bool m_firstUpdate; float m_lastAngle; }; /** * @brief 快速角度归一化到 [0, 360) * 小角度保留 while 快路径;大角度先一次性扣掉整圈数,避免累计角很大时 while 循环过多。 * 不依赖 fmodf,减少嵌入式数学库开销和链接风险。 */ inline float normalizeAngle360(float angle) { if (angle >= 720.0f || angle <= -360.0f) { int turns = (int)(angle / 360.0f); angle -= (float)turns * 360.0f; } while (angle >= 360.0f) angle -= 360.0f; while (angle < 0.0f) angle += 360.0f; return angle; } #ifdef __cplusplus } #endif #endif