Hello,
I am having an issue using a TM4C123G to interface with an 4K resolution bi-directional incremental encoder. I am using CCS and put a watch/breakpoint on my variable position. The value comes back as 0,1, or 36000 at random, without any change in position. I have verified that the encoder is working via an oscilloscope. The index pulse also interrupts and runs the ISR correctly.
Is there some sort of configuration that I'm missing or something in my code that would explain this behavior? I have gone through the search and looked for similar questions but didn't find a similar issue.
EDIT: It appears I didn't unlock PF0 (NMI pin). I have edited my code below. After this edit, I consistently receive 0 as my position value even when the rotor of the encoder is moving.
#include "stdint.h" #include "stdbool.h" #include "inc/hw_types.h" #include "inc/hw_gpio.h" #include "inc/hw_ints.h" #include "inc/hw_memmap.h" #include "inc/hw_qei.h" #include "driverlib/gpio.h" #include "driverlib/rom_map.h" #include "driverlib/sysctl.h" #include "driverlib/qei.h" #include "driverlib/pin_map.h" #include "driverlib/interrupt.h" /* Encoder */ #define QEI_PHA_PORT GPIO_PORTF_BASE //Phase A #define QEI_PHA_PIN GPIO_PIN_0 #define QEI_PHA_INT INT_GPIOF #define QEI_PHB_PORT GPIO_PORTF_BASE //Phase B #define QEI_PHB_PIN GPIO_PIN_1 #define QEI_INDEX_PORT GPIO_PORTJ_BASE //Index Port #define QEI_INDEX_PIN GPIO_PIN_2 #define QEI_INDEX_INT INT_GPIOJ const uint32_t MaxPanEncResolution = 35999; int32_t position; void Encoder0IntHandler(void) { uint32_t ulStatus; /* Get the interrrupt status and clear asserted interrupt. */ ulStatus = QEIIntStatus(QEI0_BASE, true); QEIIntClear(QEI0_BASE, ulStatus); if(ulStatus == QEI_INTINDEX) { //position = 0; } } void QEI_Init(void) { /* Enable the peripheral */ MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_QEI0); MAP_SysCtlPeripheralPowerOn(SYSCTL_PERIPH_QEI0); /* Configure the QEI pins. ENCODER 0 */ GPIOPinConfigure(GPIO_PF0_PHA0); GPIOPinConfigure(GPIO_PF1_PHB0); GPIOPinConfigure(GPIO_PJ2_IDX0); MAP_GPIOPinTypeQEI(QEI_PHA_PORT, QEI_PHA_PIN); MAP_GPIOPinTypeQEI(QEI_PHB_PORT, QEI_PHB_PIN); MAP_GPIOPinTypeQEI(QEI_INDEX_PORT, QEI_INDEX_PIN); QEIConfigure(QEI0_BASE, (QEI_CONFIG_RESET_IDX | QEI_CONFIG_CAPTURE_A_B | QEI_CONFIG_QUADRATURE | QEI_CONFIG_SWAP ), MaxPanEncResolution); MAP_QEIVelocityConfigure(QEI0_BASE, QEI_VELDIV_1, MAP_SysCtlClockGet()/100); //Set to 10 ms MAP_QEIVelocityEnable(QEI0_BASE); /* Initialize the QEI position to zero. */ QEIPositionSet(QEI0_BASE, 0); /* Enable the QEI module. */ QEIEnable(QEI0_BASE); QEIIntEnable(QEI0_BASE, (QEI_INTERROR)| (QEI_INTINDEX) ); //MAP_QEIIntEnable(QEI0_BASE, (QEI_INTERROR)); /*Enable the QEI interrupt.*/ IntEnable(INT_QEI0); } int ReadPositionFromEncoder(void) { return ( (MAP_QEIPositionGet(QEI0_BASE) * 36000)/MaxPanEncResolution); } int main(void) { SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ); MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOG); MAP_SysCtlPeripheralPowerOn(SYSCTL_PERIPH_GPIOG); MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF); MAP_SysCtlPeripheralPowerOn(SYSCTL_PERIPH_GPIOF); MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOJ); MAP_SysCtlPeripheralPowerOn(SYSCTL_PERIPH_GPIOJ); HWREG(GPIO_PORTF_BASE + GPIO_O_LOCK) = GPIO_LOCK_KEY; HWREG(GPIO_PORTF_BASE + GPIO_O_CR) |= GPIO_PIN_0;; QEI_Init(); MAP_IntMasterEnable(); while(1) { SysCtlDelay(MAP_SysCtlClockGet()/3); position = ReadPositionFromEncoder(); } return 0; }