元驭机器人元驭机器人Hall 传感器教学下载原文件
1/*!2    \file    hall_encoder.h3    \brief   三路 120° 线性霍尔径向磁铁角度解算4*/56#ifndef HALL_ENCODER_H7#define HALL_ENCODER_H89#include <stdint.h>1011/*!12    机械安装约定,从上往下看、逆时针为正:13      - U1 / PA0 / ADC_IN0 放在 0°14      - U2 / PA1 / ADC_IN1 放在 120°15      - U4 / PA4 / ADC_IN4 放在 240°16    径向充磁磁铁的转角为 θ 时,三路输出交流分量是 cos(θ)、cos(θ-120°)、cos(θ-240°)。17    相位顺序和 PCB 不一致时,只改下面三个下标。转动方向反了就把 HALL_ANGLE_SIGN 改成 -1。18*/19#define HALL_PHASE_0_DEG            020#define HALL_PHASE_120_DEG          121#define HALL_PHASE_240_DEG          222#define HALL_ANGLE_SIGN             12324/*! 低于该峰值(ADC 计数)认为磁场太弱,角度只作参考 */25#define HALL_AMP_WEAK               802627/*! 校准结束时,任一路峰峰值低于该计数就认为没有转满一圈 */28#define HALL_CAL_SPAN_MIN           4002930/*! Q12 增益,4096 表示 1.0 倍 */31#define HALL_CAL_GAIN_ONE           4096U3233#define HALL_CAL_OK                 0U34#define HALL_CAL_IDLE               1U35#define HALL_CAL_WEAK               2U3637#define HALL_FLAG_WEAK              0x01U38#define HALL_FLAG_CAL_VALID         0x02U39#define HALL_FLAG_CAL_RUN           0x04U40#define HALL_FLAG_OUT               0x08U4142/*!43    \brief      一次采样结果44*/45typedef struct {46    uint16_t raw[3];       /*!< U1、U2、U4 的 12 位 ADC 原码 */47    int32_t angle_cdeg;    /*!< 0..35999,单位 0.01°,已减去机械零点 */48    int32_t amplitude;     /*!< 单路交流峰值,单位 ADC 计数 */49} hall_sample_t;5051/*!52    \brief      三路偏置和相对增益53    偏置是一圈里的 (min+max)/2。增益以 U1 的峰峰值为基准,Q12。54*/55typedef struct {56    int16_t offset[3];57    uint16_t gain_q12[3];58    uint8_t valid;59} hall_cal_t;6061/*!62    \brief      配置 PA0/PA1/PA4 为模拟输入,并启动扫描 + DMA63    \param[in]  none64    \param[out] none65    \retval     none66*/67void hall_encoder_init(void);6869/*!70    \brief      读取最近一组三路转换,并解算角度71    \param[out] sample: 原码、角度和幅度72    \retval     none73*/74void hall_encoder_read(hall_sample_t *sample);7576/*!77    \brief      复制最近一组三路 ADC 原码,不更新角度校准78    \param[out] raw: U1、U2、U4,各 12 位79    \retval     none80*/81void hall_encoder_copy_raw(uint16_t raw[3]);8283/*!84    \brief      弱磁、校准有效、正在校准85    \param[in]  sample: 最近一次解算86    \retval     HALL_FLAG_* 的组合87*/88uint8_t hall_encoder_flags(const hall_sample_t *sample);8990/*!91    \brief      装入已保存的校准,valid 为 0 时恢复成三路平均值92    \param[in]  cal: 偏置和增益93    \param[out] none94    \retval     none95*/96void hall_encoder_cal_apply(const hall_cal_t *cal);9798/*!99    \brief      读出当前校准100    \param[out] cal: 偏置、增益和是否有效101    \retval     none102*/103void hall_encoder_cal_get(hall_cal_t *cal);104105/*!106    \brief      开始记录三路最小/最大,转满一圈后再结束107    \param[in]  none108    \param[out] none109    \retval     none110*/111void hall_encoder_cal_begin(void);112113/*!114    \brief      用记录到的峰峰值生成偏置和增益115    \param[in]  none116    \param[out] none117    \retval     HALL_CAL_OK、HALL_CAL_IDLE 或 HALL_CAL_WEAK118*/119uint8_t hall_encoder_cal_finish(void);120121/*!122    \brief      丢掉校准,回到三路平均值123    \param[in]  none124    \param[out] none125    \retval     none126*/127void hall_encoder_cal_clear(void);128129/*!130    \brief      设置要从原始角度里减掉的机械零点131    \param[in]  zero_cdeg: 0..35999132    \param[out] none133    \retval     none134*/135void hall_encoder_zero_set(uint16_t zero_cdeg);136137/*!138    \brief      当前机械零点139    \param[in]  none140    \param[out] none141    \retval     0..35999,单位 0.01°142*/143uint16_t hall_encoder_zero_get(void);144145/*!146    \brief      把此刻的角度记成 0°147    \param[in]  none148    \param[out] none149    \retval     none150*/151void hall_encoder_zero_capture(void);152153#endif /* HALL_ENCODER_H */