1. 项目概述在嵌入式运动控制领域无论是驱动一个精密的伺服电机还是为一个机器人关节提供闭环反馈获取精确的位置和速度信息都是最核心的需求。想象一下你正在设计一个3D打印机打印头需要在X、Y、Z三个轴上精确移动误差必须控制在微米级别或者你在开发一个无人机云台需要实时、平滑地跟踪目标。在这些场景下一个可靠、高精度的位置传感器就是系统的“眼睛”。正交编码器Quadrature Encoder正是扮演这一角色的关键器件而微控制器内部的正交编码器接口QEI模块则是解读这双“眼睛”所传递信息的“大脑”。Tiva™ C系列微控制器尤其是TM4C129X这类高性能型号其内置的QEI模块是一个功能强大且高度集成的硬件外设。它直接处理来自编码器的两路相位差90度的正交信号PhA和PhB以及可选的索引信号Index自动完成方向判断、位置计数和速度计算将开发者从繁琐的GPIO中断和软件计数的泥潭中解放出来。本文将以TM4C129XKCZAD这款芯片为例深入剖析其QEI模块的寄存器级配置方法。我不会仅仅停留在数据手册的翻译层面而是结合我多年在电机驱动和运动控制项目中的实战经验带你从零开始一步步理解如何让这个模块为你所用并避开那些手册里没写、但实际开发中一定会遇到的“坑”。无论你是正在评估该芯片用于新项目还是已经在调试中遇到了位置读数跳变、速度计算不准的问题相信这篇详尽的解析都能给你带来直接的帮助。2. QEI模块核心原理与设计思路拆解在动手写代码之前我们必须先吃透QEI模块的工作原理和设计哲学。这就像开车前要先了解油门、刹车和方向盘的关系而不是直接猛踩油门。2.1 正交编码信号的本质一个典型的增量式正交编码器会输出两路方波信号Phase A (PhA) 和 Phase B (PhB)。它们频率相同但存在90度的相位差。这个相位差是解码的关键正转顺时针通常定义为PhA的上升沿领先于PhB的上升沿。此时PhA和PhB的信号序列为00 - 10 - 11 - 01 - 00。反转逆时针PhB的上升沿领先于PhA。信号序列为00 - 01 - 11 - 10 - 00。QEI模块的硬件逻辑就是持续监测这两路信号的边沿变化并根据其先后顺序自动判断方向从而对内部的位置计数器进行递增或递减操作。这种硬件解码的方式其响应速度和可靠性远高于用GPIO中断在软件中实现。2.2 TM4C129X QEI模块的两种核心模式TM4C129X的QEI模块提供了两种基础工作模式通过QEICTL寄存器的SIGMODE位进行选择。理解这两种模式的差异是正确配置的前提。2.2.1 正交相位模式SIGMODE 0这是最常用、也是默认的模式。在此模式下PhA和PhB被当作标准的正交信号处理。4倍频计数CAPMODE 1模块会在PhA和PhB的每个边沿上升沿和下降沿都进行计数。对于一个每转输出N个脉冲的编码器位置分辨率将提高到每转4N个计数。这是高精度应用的标配。例如一个1000线即每转1000个脉冲的编码器在此模式下每转能产生4000个计数。2倍频计数CAPMODE 0仅对PhA的边沿进行计数忽略PhB的边沿。此时方向信息依然由PhA和PhB的相位关系决定但分辨率减半。这种模式适用于对分辨率要求不高或者编码器信号质量较差、需要避免因噪声导致误计数的场合。实操心得绝大多数情况下我们都选择4倍频模式以获得最高分辨率。只有在编码器线数极高例如上万线而你的位置计数器位数如32位可能溢出或者信号长距离传输有畸变时才考虑使用2倍频模式。2.2.2 时钟/方向模式SIGMODE 1在此模式下编码器信号的解释方式发生了根本变化PhA被当作时钟信号CLK每个有效边沿可配置触发一次计数。PhB被当作方向信号DIR其电平高低直接决定计数的方向例如高电平递增低电平递减。这种模式常用于接收某些特定类型的传感器输出或者与仅提供“脉冲方向”格式输出的驱动器、PLC等设备对接。需要注意的是在时钟/方向模式下CAPMODE位是无效的且相位错误检测功能也会被禁用。2.3 位置计数器与归零逻辑QEI模块的核心是一个32位的位置计数器QEIPOS。它的行为由RESMODE位控制最大位置复位模式RESMODE 0当位置计数器递增超过QEIMAXPOS寄存器设定的最大值时或在反转时递减到0以下时计数器会自动归零或重置为QEIMAXPOS。这实现了一个“模计数器”非常适合测量相对位置或多圈内的绝对位置。例如将QEIMAXPOS设为3999那么位置值将在0~3999之间循环对应电机的一整圈。索引脉冲复位模式RESMODE 1每当检测到索引脉冲IDX的上升沿时位置计数器被清零。索引脉冲通常由编码器每转产生一次用于标记机械零点。此模式用于建立绝对位置坐标系。每次经过零点位置都被重置结合圈数记录可以实现真正的绝对位置测量。注意事项QEIMAXPOS寄存器存储的是最大值而不是模数。如果你希望每转计数为40000~3999那么QEIMAXPOS应设置为3999。这是一个常见的理解误区设置错误会导致计数周期少1。2.4 速度测量的实现机制除了位置QEI模块还能硬件计算速度这大大减轻了CPU的负担。速度测量的原理是在一个固定的时间窗口由速度定时器设定内统计接收到的编码器脉冲数。使能速度捕获设置QEICTL寄存器的VELEN位。配置定时器向QEILOAD寄存器写入定时器的重载值。定时器以系统时钟递减计数减到0时产生中断如果使能并自动重载。这个时间窗口的长度 (LOAD 1) * 系统时钟周期。预分频器VELDIV在高速应用中脉冲频率可能超过定时器计数器的统计能力。VELDIV位域可以对输入脉冲进行2^N分频N0~7然后再送给速度脉冲计数器QEICOUNT。这相当于降低了速度测量的分辨率但扩展了可测量的最大速度范围。读取速度值速度值存储在QEISPEED寄存器中它代表上一个完整的定时器周期内捕获到的经过分频后的脉冲数。这是一个“快照”值读取它是稳定的。核心逻辑速度V (QEISPEED * 预分频系数) / (定时器周期)。单位是“脉冲数/秒”。你需要根据编码器的线数、4倍频以及机械传动比将这个值转换为有物理意义的转速如RPM。3. 寄存器详解与配置实战理解了原理我们就可以深入每个寄存器看看如何用代码“指挥”硬件。TM4C129X的QEI模块寄存器映射基地址为0x4002.C000QEI0。我们将使用TI的TivaWare库函数进行说明这比直接操作寄存器更安全、更可读。3.1 控制寄存器QEICTL—— 模块的大脑QEICTL寄存器是配置的起点它控制了QEI模块的所有基本行为。// 假设使用QEI0模块 #define QEI0_BASE 0x4002C000 // 常用的配置宏定义 #define QEI_CTL_ENABLE 0x00000001 // 使能QEI模块 #define QEI_CTL_SIGMODE_QUAD 0x00000000 // 正交模式 #define QEI_CTL_SIGMODE_CLK_DIR 0x00000004 // 时钟/方向模式 #define QEI_CTL_CAPMODE_4X 0x00000008 // 4倍频捕获 #define QEI_CTL_CAPMODE_2X 0x00000000 // 2倍频捕获 #define QEI_CTL_RESMODE_MAXPOS 0x00000000 // 最大位置复位 #define QEI_CTL_RESMODE_IDX 0x00000010 // 索引脉冲复位 #define QEI_CTL_VELEN 0x00000020 // 使能速度捕获 #define QEI_CTL_VELDIV_1 0x00000000 // 预分频 ÷1 #define QEI_CTL_VELDIV_2 0x00000040 // 预分频 ÷2 // ... 其他 VELDIV 值 #define QEI_CTL_INVA 0x00000200 // 反相PhA #define QEI_CTL_INVB 0x00000400 // 反相PhB #define QEI_CTL_INVI 0x00000800 // 反相IDX #define QEI_CTL_SWAP 0x00000002 // 交换PhA和PhB信号 #define QEI_CTL_FILTEN 0x00002000 // 使能输入数字滤波器 #define QEI_CTL_STALLEN 0x00001000 // 调试时停止计数 // 一个典型的配置示例正交模式、4倍频、索引复位、使能速度捕获、2分频 uint32_t qeiConfig; qeiConfig QEI_CTL_SIGMODE_QUAD | // 正交模式 QEI_CTL_CAPMODE_4X | // 4倍频 QEI_CTL_RESMODE_IDX | // 索引复位 QEI_CTL_VELEN | // 使能速度捕获 QEI_CTL_VELDIV_2 | // 速度预分频 ÷2 QEI_CTL_FILTEN; // 使能输入滤波抗抖动 // 使用TivaWare API配置 QEIConfigure(QEI0_BASE, qeiConfig, QEI_CONFIG_CAPTURE_A_B | QEI_CONFIG_NO_RESET); // 注意QEIConfigure函数内部可能会处理一些位域的合并具体请参考库文档。 // 更底层的操作是直接写寄存器 HWREG(QEI0_BASE QEI_O_CTL) qeiConfig;关键位域解析与避坑指南FILTCNT(位19:16)输入滤波器预分频计数。它决定了输入信号需要稳定多少个系统时钟周期才被确认。默认是2个周期。在电机等噪声较大的环境中适当增加这个值例如到4或8可以有效滤除毛刺防止误计数。代价是引入了微小的相位延迟在极高转速下需权衡。SWAP与INVA/INVB这两个功能用于调整信号极性。交换(SWAP)发生在反相(INV)之后。如果你的电机转向与预期相反不要急着改代码里的方向判断先尝试设置SWAP位交换A、B相或者用INVA/INVB反相信号这往往是硬件接线导致的。使能位ENABLE的“一次性”数据手册明确警告一旦设置ENABLE位只有模块复位通过SRQEI寄存器才能将其清零。这意味着你的初始化代码流程必须是配置所有寄存器 - 最后置位ENABLE。如果中途需要修改配置必须先复位整个模块。3.2 位置与最大值寄存器QEIPOS, QEIMAXPOSQEIPOS是32位可读可写的位置计数器。你可以随时读取它获取当前位置也可以在初始化时写入一个初始值例如在系统上电时从非易失存储器中恢复绝对位置。QEIMAXPOS定义了位置计数器的模最大值。计算方式为期望的最大计数值 - 1。// 对于1000线编码器4倍频每转4000个计数。 // 我们希望位置范围是0~3999。 uint32_t maxPosition 4000 - 1; // 0xF9F HWREG(QEI0_BASE QEI_O_MAXPOS) maxPosition; // 如果需要可以设置初始位置必须在使能QEI之后 // 假设我们知道电机启动时处于机械零点偏移500个计数的位置 if(restoreFromBackup) { HWREG(QEI0_BASE QEI_O_POS) 500; }3.3 速度定时器相关寄存器QEILOAD, QEITIME, QEICOUNT, QEISPEED速度测量依赖于一个独立的定时器。设置采样周期QEILOAD这个寄存器决定速度更新的频率。速度 脉冲数 / 时间窗口。时间窗口T (LOAD 1) / SysClk。// 假设系统时钟为120MHz我们希望速度更新率为1kHz即1ms更新一次 // 定时器周期 1 / 1000Hz 0.001 s // 需要的时钟周期数 0.001 * 120,000,000 120,000 // QEILOAD 时钟周期数 - 1 119999 uint32_t sysClockFreq 120000000; // 120 MHz uint32_t velocitySampleRateHz 1000; // 1 kHz uint32_t timerLoadValue (sysClockFreq / velocitySampleRateHz) - 1; HWREG(QEI0_BASE QEI_O_LOAD) timerLoadValue;注意事项QEILOAD值不能为0xFFFFFFFF即4294967295否则定时器将停止工作。同时过短的采样周期LOAD值过小在高速时可能导致QEICOUNT溢出32位过长的周期则会导致速度更新迟钝。需要根据最大预期转速来权衡。理解三个速度相关寄存器QEITIME当前速度定时器的递减计数值只读。主要用于调试观察定时器是否在正常运行。QEICOUNT在当前尚未结束的定时器周期内累计捕获的经分频后的脉冲数。由于读取时刻不确定这个值本身不能直接用于速度计算会引入误差。QEISPEED这是你要读取的速度值。它锁存了上一个完整定时器周期结束时的QEICOUNT值。读取它是原子操作能获得一个稳定的速度快照。// 读取当前速度脉冲数/采样周期 uint32_t rawSpeed HWREG(QEI0_BASE QEI_O_SPEED); // 转换为转速RPM。假设编码器1000线4倍频速度预分频为2采样周期1ms。 // 每转脉冲数 1000 * 4 4000 // 实际计数脉冲分频前 rawSpeed * 2 (VELDIV2) // 每秒脉冲数 (rawSpeed * 2) / 0.001 rawSpeed * 2000 // 转速 RPM (每秒脉冲数 / 每转脉冲数) * 60 float rpm (rawSpeed * 2000.0 / 4000.0) * 60.0;3.4 中断控制寄存器QEIINTEN, QEIRIS, QEIISCQEI模块可以产生多种中断让你的CPU无需轮询即可响应关键事件。QEIINTEN中断使能寄存器。你需要显式使能感兴趣的中断源。QEIRIS原始中断状态寄存器。只要事件发生对应位就置1无论中断是否被使能。QEIISC中断状态与清除寄存器。只有当事件发生且在QEIINTEN中被使能对应位才置1。向该寄存器的位写1可以清除中断标志RW1C特性。中断类型索引脉冲中断INTINDEX检测到IDX信号上升沿。用于标记机械零点进行位置清零或圈数计数。速度定时器中断INTTIMER速度定时器减到0。可以用于定期读取QEISPEED或执行速度环控制。方向改变中断INTDIR电机旋转方向发生变化。可用于安全保护或逻辑处理。相位错误中断INTERROR仅在正交模式下有效。当PhA和PhB在同一系统时钟周期内同时改变状态时触发表明信号可能受到严重噪声干扰或编码器故障。// 使能索引脉冲和定时器溢出中断 HWREG(QEI0_BASE QEI_O_INTEN) | (QEI_INTEN_INTINDEX | QEI_INTEN_INTTIMER); // 在中断服务函数(ISR)中处理 void QEI0_IntHandler(void) { uint32_t status HWREG(QEI0_BASE QEI_O_ISC); // 读取中断状态 if(status QEI_INT_INDEX) { // 处理索引脉冲清零位置圈数加1等 g_encoderRevolutionCount; // ... 其他操作 HWREG(QEI0_BASE QEI_O_ISC) QEI_INT_INDEX; // 写1清除中断标志 } if(status QEI_INT_TIMER) { // 定时器溢出读取当前速度并进行控制计算 uint32_t speed HWREG(QEI0_BASE QEI_O_SPEED); // ... 速度处理逻辑 HWREG(QEI0_BASE QEI_O_ISC) QEI_INT_TIMER; // 清除中断标志 } // 注意必须清除所有已处理的中断标志否则会持续触发中断。 }4. 完整初始化与配置流程实战现在我们将所有知识点串联起来形成一个稳健的QEI模块初始化流程。这里以连接一个1000线增量式编码器需要4倍频计数、索引脉冲复位、并使能1ms速度采样为例。4.1 步骤一系统级准备在配置任何外设之前必须确保其时钟和对应的GPIO端口时钟已经开启。#include stdint.h #include stdbool.h #include inc/hw_memmap.h #include inc/hw_types.h #include driverlib/sysctl.h #include driverlib/gpio.h #include driverlib/pin_map.h // 包含引脚复用定义 #include driverlib/qei.h int main(void) { // 1. 使能QEI0模块的时钟 SysCtlPeripheralEnable(SYSCTL_PERIPH_QEI0); // 2. 使能编码器信号所在GPIO端口的时钟假设PhA, PhB, IDX在Port L的0,1,2引脚 SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOL); // 3. 等待外设时钟稳定良好习惯非绝对必须但推荐 while(!SysCtlPeripheralReady(SYSCTL_PERIPH_QEI0)); while(!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOL));4.2 步骤二GPIO引脚复用配置TM4C129X的引脚功能高度复用必须将物理引脚配置为QEI功能。// 4. 解锁GPIOL如果引脚被锁定某些型号需要 // HWREG(GPIO_PORTL_BASE GPIO_O_LOCK) GPIO_LOCK_KEY; // HWREG(GPIO_PORTL_BASE GPIO_O_CR) | 0x07; // 解锁PL0, PL1, PL2 // HWREG(GPIO_PORTL_BASE GPIO_O_LOCK) 0; // 5. 配置PL0, PL1, PL2为外设功能QEI GPIOPinTypeQEI(GPIO_PORTL_BASE, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2); // 上述函数内部完成了AFSEL和PCTL的配置。 // 如果你想手动配置 // GPIOPinConfigure(GPIO_PL0_PHA0); // 将PL0配置为PhA0 // GPIOPinConfigure(GPIO_PL1_PHB0); // 将PL1配置为PhB0 // GPIOPinConfigure(GPIO_PL2_IDX0); // 将PL2配置为IDX0 // GPIOPinTypeQEI(GPIO_PORTL_BASE, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2);4.3 步骤三QEI模块核心配置这是最关键的一步直接决定了模块的行为。// 6. 配置QEI模块参数 // 注意在调用QEIConfigure或直接写CTL寄存器前不要使能模块 // 先计算速度定时器加载值假设系统时钟120MHz1ms采样 uint32_t timerLoadValue (120000000 / 1000) - 1; // 119999 // 使用TivaWare库函数进行配置推荐更清晰 QEIConfigure(QEI0_BASE, (QEI_CONFIG_CAPTURE_A_B | // 4倍频模式 QEI_CONFIG_NO_SWAP | // 不交换信号 QEI_CONFIG_NO_RESET | // 使用索引复位模式RESMODE1但库函数此参数名易混淆需结合下面设置 QEI_CONFIG_QUADRATURE | // 正交模式 QEI_CONFIG_NO_INVERT), // 不反相 timerLoadValue); // 7. 单独设置最大位置值和复位模式因为库函数可能未完全覆盖 // 设置最大位置为3999 (0xF9F) QEIMaximumPositionSet(QEI0_BASE, 4000 - 1); // 明确设置为索引复位模式 uint32_t ctlReg HWREG(QEI0_BASE QEI_O_CTL); ctlReg | QEI_CTL_RESMODE_IDX; // 设置索引复位位 HWREG(QEI0_BASE QEI_O_CTL) ctlReg; // 8. 可选配置输入滤波器增加抗干扰能力 ctlReg HWREG(QEI0_BASE QEI_O_CTL); ctlReg | QEI_CTL_FILTEN; // 使能滤波器 // 设置滤波器采样计数为4个系统时钟值2因为基数是2 ctlReg ~QEI_CTL_FILTCNT_M; // 清除旧值 ctlReg | (2 16); // FILTCNT 2表示稳定4个周期后确认 HWREG(QEI0_BASE QEI_O_CTL) ctlReg; // 9. 使能速度捕获并设置预分频例如2分频 ctlReg HWREG(QEI0_BASE QEI_O_CTL); ctlReg | (QEI_CTL_VELEN | QEI_CTL_VELDIV_2); HWREG(QEI0_BASE QEI_O_CTL) ctlReg;4.4 步骤四中断配置与使能模块// 10. 配置并使能中断如果需要 QEIIntEnable(QEI0_BASE, QEI_INTTIMER | QEI_INTINDEX); // 使能定时器和索引中断 // 注册中断服务程序此处为伪代码需根据你的开发环境注册 // IntRegister(INT_QEI0, QEI0_IntHandler); // IntEnable(INT_QEI0); // 11. 最后一步使能QEI模块 // 一旦使能CTL寄存器的ENABLE位将无法通过软件清零除非模块复位。 QEIEnable(QEI0_BASE); // 12. 如果需要初始位置在使能后设置 // QEIPositionSet(QEI0_BASE, initialPosition); // 主循环 while(1) { // 可以非阻塞地读取位置和速度 int32_t currentPos QEIPositionGet(QEI0_BASE); uint32_t currentSpeed QEIVelocityGet(QEI0_BASE); // 读取QEISPEED // ... 进行控制或显示 SysCtlDelay(SysCtlClockGet() / 10); // 简单延时 } }5. 常见问题排查与调试技巧实录即使按照手册配置在实际硬件调试中也可能遇到各种问题。以下是我在多个项目中总结的常见故障和解决方法。5.1 位置读数不变化或变化异常症状电机转动但QEIPOS寄存器值不变、只增不减、或跳变混乱。排查步骤检查物理连接使用示波器或逻辑分析仪直接测量连接到MCU引脚的PhA、PhB信号。确保波形是干净的正交方波电压电平符合要求通常3.3V没有过冲或振铃。这是最重要的一步硬件问题占此类故障的80%以上。验证GPIO配置确认GPIOAFSEL和GPIOPCTL寄存器已正确配置为QEI功能。一个快速验证方法是将引脚临时配置为GPIO输入在循环中读取其电平并打印手动转动编码器看电平是否变化。检查信号极性如果位置只增不减可能是方向判断反了。尝试在代码中设置SWAP位或者交换硬件上PhA和PhB的接线。如果读数在正转时偶尔减少或反之可能是信号有噪声尝试启用并加强输入滤波器增大FILTCNT。确认工作模式检查SIGMODE和CAPMODE位是否按预期设置。如果你接的是“脉冲方向”编码器却配置成了正交模式读数必然错误。5.2 速度值QEISPEED为零或不准确症状位置读数正常但QEISPEED始终为0或计算出的转速与预期严重不符。排查步骤确认速度捕获已使能检查QEICTL寄存器的VELEN位是否为1。检查定时器配置确认QEILOAD寄存器已写入非零值。计算你期望的采样周期对应的LOAD值是否正确。一个极易犯的错误是LOAD值设置过大导致定时器溢出周期长达数十秒在测试的几秒内速度值还未更新。理解QEISPEED的更新时机QEISPEED只在定时器周期结束时更新。如果你在周期中间读取得到的是上一个周期的速度。确保你的读取频率低于速度更新频率或者使用定时器中断来同步读取。检查预分频器VELDIV如果电机转速极高脉冲频率可能超过模块计数能力导致QEICOUNT在周期结束前就溢出回绕。此时QEISPEED会是错误的小值。解决方法增大VELDIV分频系数。例如从÷1改为÷4这样QEICOUNT计的是每4个脉冲才加1可测量的最大速度理论上提高了4倍但分辨率也降低了4倍。速度计算单位转换错误这是软件逻辑问题。仔细核对公式转速(RPM) (QEISPEED * 预分频系数 * 60) / (每转总脉冲数 * 定时器周期(秒))。确保所有变量单位一致。5.3 索引脉冲中断不触发症状编码器带Z信号索引但无法触发INTINDEX中断。排查步骤检查IDX信号硬件用示波器确认IDX信号是否正常产生通常是每转一个窄脉冲。确认中断使能检查QEIINTEN寄存器的INTINDEX位是否置1。检查索引信号反相有些编码器的Z信号是低电平有效。尝试设置QEICTL寄存器的INVI位来反相IDX输入。中断服务程序ISR问题确保ISR已正确注册到向量表并且全局中断已开启__enable_irq()或类似指令。最关键的是在ISR结束前必须清除中断标志向QEIISC寄存器的对应位写1否则会连续触发中断导致系统死锁。5.4 抗干扰与滤波配置经验在工业环境或长线驱动时编码器信号容易引入噪声。硬件层面使用双绞线传输差分信号如果编码器支持或在信号线靠近MCU端并联几十皮法的小电容到地以及串联小电阻如22-100欧姆。软件层面充分利用QEI模块的数字输入滤波器。通过FILTCNT位域可以要求信号稳定多个系统时钟周期后才被确认。对于120MHz系统时钟设置FILTCNT4即稳定6个周期约50ns可以滤除大多数短毛刺。代价是引入了约50ns的延迟对于极高转速如几万RPM的应用需要评估是否可接受。诊断技巧可以启用相位错误中断INTERROR。如果频繁进入此中断说明信号质量很差需要从硬件上解决干扰问题。5.5 32位位置计数器溢出处理QEIPOS是32位无符号整数最大计数值约为43亿。对于超高精度或多圈应用可能会溢出。方案一使用索引复位模式每转到索引位置就清零同时在软件中维护一个“圈数”变量。这是最常用的绝对位置方案。volatile int32_t g_encoderRevolutions 0; void QEI0_Index_ISR(void) { if(方向为正) g_encoderRevolutions; else g_encoderRevolutions--; // QEIPOS已被硬件清零 // 总绝对位置 g_encoderRevolutions * 每转计数 QEIPositionGet() }方案二监控溢出在最大位置复位模式RESMODE0下当计数器从MAXPOS翻转到0时可以结合方向改变中断或软件监控来增加圈数计数。配置QEI模块是一个从硬件连接到寄存器配置再到软件逻辑处理的系统工程。最有效的调试方法是分而治之先用最简单的配置如仅位置计数无中断让模块跑起来确保基础读数正确再逐步添加速度测量、中断、滤波等高级功能。务必善用示波器和调试器直接观察寄存器值的变化这比盲目修改代码要高效得多。TM4C129X的QEI模块非常强大一旦正确配置它将为你的运动控制项目提供一个极其可靠和高效的位置反馈解决方案。