解析先楫“硬核”解码利器 —— QEIV2
引言
QEIV2是先楫高性能MCU中非常核心的外设,主要用于高精度电机控制、运动控制和位置传感,是处理编码器信号的“眼睛”。
主要功能
-
QEIV2支持数字信号输入和模拟信号输入,能解析多种编码器模式:
-
正交编码器模式(ABZ信号)


-
正余弦信号模式(SinCos信号)

-
UVW霍尔传感器模式(UVW信号)

-
脉冲+方向信号模式(PD信号)

-
上/下信号模式(UD信号)

-
单脉冲信号模式(P信号)

-
单相正弦信号模式(Sin信号)

-
-
可直接输出位置信息
- POSITION值为0,对应0度
- POSITION值为0xFFFFFFFF,对应360度
-
支持M/T法测速
- 结合M法和T法,硬件既测量脉冲数,又测量产生这些脉冲所用的精确时间,软件使用这些测量的数值可精确计算出速度。
-
具有位置比较功能(精准触发)
- 走到某个位置,能自动触发中断、DMA或触发输出
-
具有信号滤波功能
- QEIV2的信号有数字滤波器,能有效滤除信号毛刺,从而保证控制系统在强电磁干扰环境下不“飞车”
-
具有数据锁存功能
- 支持在读取事件发生时,把各个计数器的值保存到读取
READ寄存器组里。以此保证用户读到的各种计数器值信息是严格同一时刻的 - 读取事件可以是软件触发,用户通过软件写
CR[READ]位置1 - 读取事件也可以是硬件触发,用户通过硬件写
READEN寄存器使能相应的读取事件
- 支持在读取事件发生时,把各个计数器的值保存到读取
-
具有数据暂停功能
- 当
PAUSE信号输入为1时,QEIV2将暂停计数
- 当
-
具有数据复位功能
- 当
CR[RSTCNT]置1时,QEIV2将复位所有计数器
- 当
-
具有2个HOME位置检测功能
- HOME信号代表电机系统的零点位置,当检测到HOME信号的上升沿或下降沿时,可产生中断、DMA或触发输出。
-
具有FAULT信号用于故障输入
- 当电机系统发生故障时,给FAULT信号输入上升沿,QEIV2模块将停止输出Position有效信号,停止Position的内部流转。
QEIV2模块连接示意图

-
信号输入
- QEIV2具有6个IO信号输入,A、B、Z、H(HOME)、H2(HOME2)、F(Fault),这6个IO信号均可配置数字滤波器,可用来滤除信号“毛刺”。
- Pause信号没有专用引脚,需从TRGMMUX中选择信号作为Pause信号。
- Snap信号也没有专用引脚,需从TRGMMUX中选择信号作为Snap信号。
- ADC0和ADC1用于正余弦模拟信号输入,可从TRGM ADC_MATRIX中指定ADC数值的来源,ADC_MATRIX示意图如下:

- SyncTime时钟,可以用来在位置信息中添加时间戳
-
信号输出
- TrigOut触发输出信号,连接到TRIGMUX,可给其他模块使用。
- DMAReq输出信号,连接到DMAMUX,可给DMA使用。
- Position位置输出,连接到POS_MAXTRIX,可给其他模块使用。
编码器应用要点
编码器数值介绍
- 编码器主要有四个值,Position、Angle、PhCnt和ZCnt(圈数),如下COUNT寄存器中的的SPD和TMR可以通过
CR[RD_SEL]位域设置将数值映射为Position和Angle。

- Position为一圈中的角度,0-360°对应0x00000000至0xFFFFFFFF。
- Angle为SinCos编码器一个信号周期内的正切角度。
ABZ编码器应用要点
Z相的介绍
- 正交编码器,有些带有Z相信号,它通常用来定位编码器的零点位置。
- 为了保证电机无论正向还是反向旋转,总是定位到Z相信号的同一边沿,正交解码器默认的内部逻辑会将Z相信号与A/B相信号同步,具体做法为:
- 当电机正向旋转时,Z相信号捕捉总是同步于A相的上升沿,即当Z相信号为高电平,A相信号捕捉到上升沿,Z相计数器+1。
- 当电机反向旋转时,Z相信号捕捉总是同步于A相的下降沿,即当Z相信号为高电平,A信信号捕捉到下降沿,Z相计数器-1。
- 通过设置
CR[Z_ONLY_EN]位域,使得Z相信号忽略A/B相信号同步- 当电机正向旋转时,Z相信号捕捉到上升沿,Z相计数器+1
- 当电机反向旋转时,Z相信号捕捉到下降沿,Z相计数器-1
- 当没有Z相信号时,可以通过设置
CR[ZCNTCFG]位域,使得Z相计数通过Phcnt计数到达Phmax时+1,或则phcnt递降过0时-1。 - 需要主要的是:当没有Z相信号时,Z相引脚不能够配置,只能配置AB相信号引脚。否则,ZCNT可能会异常增大或减小。
测速模块介绍
-
测速模块的原理是M/T法,既测量脉冲数,又测量产生这些脉冲所用的精确时间。
-
硬件有2种方式来实现上述M/T法
- 基于脉冲数PULSE的测速方法

[1] 预先设置PULSE脉冲数,QEIV2会记录达到该PULSE脉冲数所需的时钟周期,在cycle_snap寄存器中可以读取到。
[2] 软件使用预设的PULSE脉冲数和cycle_snap数据,可以计算出实际的转速。
[3] 上图中的周期快照0为当前记录的周期快照,周期快照1为上一周期记录的周期快照。 - 基于周期数CYCLE的测速方法

[1] 预先设置CYCLE周期数,当周期数到达时,QEIV2会记录这段时间内的脉冲数和这些脉冲数对应的时钟周期,即pulse_snap和pulse_cylce_snap。
[2] 软件使用pulse_snap和pulse_cylce_snap数据,可以计算出实际的转速。
[3] 上图中的脉冲快照0和周期快照0为当前记录的脉冲快照和周期快照,脉冲快照1和周期快照1为上一周期记录的脉冲快照和周期快照。
- 基于脉冲数PULSE的测速方法
-
ABZ编码器软件典型配置
qeiv2_mode_config_t mode_config = { 0 }; mode_config.work_mode = qeiv2_work_mode_abz; /* 工作模式 */ mode_config.spd_tmr_content_sel = qeiv2_spd_tmr_as_spd_tm; /* 计数值选择(测速计数值可用于位置值、定时器计数值可用于角度值) */ mode_config.z_count_inc_mode = qeiv2_z_count_inc_on_z_input_assert; /* Z相计数器递增模式选择 */ mode_config.phcnt_max = APP_ENCODER_PHASE_COUNT_PER_REV; /* 一圈有多少个脉冲 */ mode_config.z_cali_enable = true; /* Z相信号校准Phcnt使能 */ mode_config.z_cali_ignore_ab = false; /* Z相信号忽略A/B相信号同步 */ mode_config.phcnt_idx = 0; /* Z相信号有效时,将Phcnt校准到该数值 */ qeiv2_config_mode(APP_QEI_BASE, &mode_config); -
之后,可通过API qeiv2_set_phase_cnt()和qeiv2_set_z_phase()来分别设置PhaseCnt和ZPhaseCnt初值。
Sin/Cos编码器应用要点
-
需要配置ADC,为了数据同步性,建议使用2个ADC instance,一个用于正弦,一个用于余弦。若是Sin和Cos使用同一个ADC去采样,则两路的信号延迟会使得计算出的角度偏差较大。
-
需要配置ADC Matrix,将ADC信号连接到QEIV2的ADC0/ADC1输入。
-
需要配置QEIV2的ADC相关的参数,主要有offset、param0和param1,典型的配置代码如下:
adc_config.adc_select = 0; adc_config.adc_channel = qeiv2_adc_channel_convert(BOARD_APP_QEI_ADC_COS_CHN, 0); adc_config.offset = 0x80000000; /* middle point */ adc_config.param0 = 0x4000; adc_config.param1 = 0; qeiv2_config_adcx(APP_QEI_BASE, &adc_config, true); adc_config.adc_select = 1; adc_config.adc_channel = qeiv2_adc_channel_convert(BOARD_APP_QEI_ADC_SIN_CHN, 0); adc_config.offset = 0x80000000; /* middle point */ adc_config.param0 = 0; adc_config.param1 = 0x4000; qeiv2_config_adcy(APP_QEI_BASE, &adc_config, true); -
x通道对应cos信号,y通道对应sin信号;offset为sin/cos信号的中间电压值,例如为0x80000000;param0和param1是对sin/cos分量进行微调,以处理sin/cos信号不是完全正交或者幅值不同的情况,具体计算推理如下:
- 例如Sin信号相位偏差B角度,即Y0=sin(A+B),X0=cos(A),那么可通过配置param0和param1来消除Sin信号偏差的角度B,推到据图如下:

- param0和param1的硬件逻辑图如下所示:

处理后的x1和y1为:x1 = (x0-x_offset)*x_param0 + (y0-y_offset)*y_param0 y1 = (x0-x_offset)*x_param1 + (y0-y_offset)*y_param1 - 当x_param0 = 1,y_param0 = 0时,x1为保持不变的cos(A)信号。
- 当x_param1 = -tan(B),y_param1 = 1/cos(B)时,y1为消除偏差角度B后的sin(A)信号。
- x_param0 和 y_param0 乘以一个系数,可以缩放 X1 的值,x_param1 和 y_param1 乘以一个系数,可以缩放 y1 的值。
- 上述调整参数的,也可通过如下API进行设置:
void qeiv2_config_adcx_adcy_param(QEIV2_Type *qeiv2_x, float tan_delta, float cos_delta, float x_magnification, float y_magnification);
- 例如Sin信号相位偏差B角度,即Y0=sin(A+B),X0=cos(A),那么可通过配置param0和param1来消除Sin信号偏差的角度B,推到据图如下:
-
配置好ADC参数后,将QEIV2配置为Sin/Cos编码器模式,软件的典型配置为
/* mode config */ mode_config.work_mode = qeiv2_work_mode_sincos; mode_config.spd_tmr_content_sel = qeiv2_spd_tmr_as_pos_angle; mode_config.z_count_inc_mode = qeiv2_z_count_inc_on_phase_count_max; mode_config.phcnt_max = 128; mode_config.z_cali_enable = false; mode_config.z_cali_ignore_ab = false; mode_config.phcnt_idx = 0; qeiv2_config_mode(APP_QEI_BASE, &mode_config); -
之后,可通过API qeiv2_set_phase_cnt()和qeiv2_set_z_phase()来分别设置PhaseCnt和ZPhaseCnt初值。
UVW编码器应用要点
- UVW编码器有三个相差120°相位的信号,按照这三个信号,可以将其分为6个相位,需配置每个相位对应的Position。
- 位置输出模式有2种,在信号边沿输出当前周期的位置,或者在信号边沿输出下一个位置周期的位置,配置的API如下:
static inline void qeiv2_set_uvw_position_opt(QEIV2_Type *qeiv2_x, qeiv2_uvw_pos_opt_t opt) - 总共有6个相位,配置UVW信号对应位置的API如下:
static inline void qeiv2_set_uvw_position_sel(QEIV2_Type *qeiv2_x, qeiv2_uvw_pos_idx_t idx, uint8_t u_pos_sel, uint8_t v_pos_sel, uint8_t w_pos_sel, bool enable) - 最后,配置这6个相位对应的Position,API如下:
static inline void qeiv2_set_uvw_position(QEIV2_Type *qeiv2_x, qeiv2_uvw_pos_idx_t idx, uint32_t pos)
TOGI应用要点
TOGI指的是三阶广义积分器(Third-Order Generalized Integrator),它是一个带直流消除功能的正交信号发生器,把输入的单相sin信号变成一对 sin/cos信号,从而能像处理旋转矢量一样精确地算出角度θ。- 它的典型应用为单相并网逆变器:用于实时跟踪电网的电压相位。
- 在QEIV2中,只需知道单相sin信号频率和ADC采样频率,即可配置TOGI的参数,API如下:
/** * @brief configures the TOGI w parameter * * This function calculates and sets the TOGI w parameter for the QEIV2 module based on the input signal frequency and ADC sample rate. * The parameter here primarily refers to the frequency control parameter used for waveform generation. * * @param[in] qeiv2_x QEIV2 base address, HPM_QEIV2x(x=0...n) * @param[in] signal_hz Frequency of the input signal * @param[in] adc_sample_rate Sample rate of the ADC */ void qeiv2_config_togi_w_param(QEIV2_Type *qeiv2_x, uint32_t signal_hz, uint32_t adc_sample_rate);
备注
- 更加详细的技术细节,请参考芯片用户手册的QEIV2章节或HPM_SDK官方示例。