This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Timer0 as an encoder edge counter

Other Parts Discussed in Thread: TM4C123GH6PM

I have to read a pair of encoders, and is not possible to use an interrupt, because the frequency of the input signal is too high (Encoder) and the microcontroller is busy all the time to answer the interrupts generated. In this case, I need to use a polling technique by reading an accumulator register every “x” milliseconds. I think the TIMER0 and PORTB configuration is correct, but the “TIMER0_TAV_R” remain at zero all the time...Can you help me? Where is the mistake?

 

Here is my code:

 

// external signal connected to PB6 (T0CCP0) (trigger on rising edge)
#include <stdint.h>
#include "..\tm4c123gh6pm.h"
#include "PLL.h"

void EdgeCounter_Init(void){ 
 
 int delay;

 SYSCTL_RCGC1_R |= SYSCTL_RCGC1_TIMER0;  // activate timer0
 SYSCTL_RCGC2_R |= SYSCTL_RCGC2_GPIOB;  // activate port B
 delay = SYSCTL_RCGC2_R;              // allow time for clock to start
 GPIO_PORTB_DIR_R &= ~0x40;         // make PB6 input (encoder input pulses)
 GPIO_PORTB_DEN_R |= 0x40;          // enable digital I/O on PB6
 GPIO_PORTB_AFSEL_R |= 0x40;        // enable alternate function on PB6
 GPIO_PORTB_PCTL_R &= ~0x0F000000;      // configure PB6 as TIMER
 GPIO_PORTB_PCTL_R |= 0x07000000;  
 GPIO_PORTB_AMSEL_R &= ~0x40;       // disable analog functionality on PB6 
 TIMER0_CTL_R &= ~TIMER_CTL_TAEN;       // disable timer0A during setup
 TIMER0_CFG_R = TIMER_CFG_16_BIT;     // configure for 16-bit timer mode
 TIMER0_TAMR_R = (TIMER_TAMR_TACMR|TIMER_TAMR_TAMR_CAP);  // configure for capture mode
 TIMER0_CTL_R &= ~(TIMER_CTL_TAEVENT_POS|0xC);       // configure for rising edge event
 TIMER0_TAILR_R = 0x00000000;         // start value
  TIMER0_CTL_R |= TIMER_CTL_TAEN;      // enable timer0A 16-b

}

int main(void){
 
 unsigned int CounterValue = 0;
 
 PLL_Init();
 EdgeCounter_Init();            // initialize GPIOB and TIMER0A
 while(1){
  CounterValue = TIMER0_TAV_R;      //Counter Value
 }
}

 

  • 1. Please use the TivaWare API calls to get your system working. If you need to optimize for performance, you can later migrate to direct register accesses. But always start with the API calls - they have been tested by many. I won't bother trying to understand others' register accesses unless there's a very specific problem at hand.
    2. Does your encoder happen to be a quadrature encoder? In that case, and seeing that your device supposedly is the TM4C123GH6PM, I would suggest you take a look at the quadrature encoder interface (QEI) modules that your device has two of.
  • Hello user4009506

    The timer is in down count mode. The TAILR must be a non-zero value

    Regards
    Amit
  • Amit Ashara said:
    The timer is in down count mode. The TAILR must be a non-zero value

     Hi Amit, just a curiosity, I am usual have some 50-100KHz quadrature encoder IRQ served on MSP430 and still have time to execute main loop @8Mhz, so how much time need TIVA to service interrupt? I cannot figure an Encoder also if GPIO IRQ served saturate this processor, am I right?

  • Hello Roberto,

    From the top of my head it was 7-8 clocks for the interrupt service routine jump.

    Regards
    Amit