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.

TM4C123GH6PM: Wide Timer not working

Part Number: TM4C123GH6PM
    SysCtlClockSet(SYSCTL_SYSDIV_2_5|SYSCTL_USE_PLL|SYSCTL_OSC_MAIN|SYSCTL_XTAL_16MHZ);

    SysCtlPeripheralEnable(SYSCTL_PERIPH_WTIMER0);
    SysCtlDelay(3);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);
    SysCtlDelay(3);
    GPIOPinConfigure(GPIO_PC5_WT0CCP1);
    GPIOPinTypeTimer(GPIO_PORTC_BASE, GPIO_PIN_5);
    TimerConfigure(WTIMER0_BASE, TIMER_CFG_SPLIT_PAIR|TIMER_CFG_B_PWM);
    TimerLoadSet(WTIMER0_BASE, TIMER_B, Period-1);
    TimerMatchSet(WTIMER0_BASE, TIMER_B, Period-1);

    HWREG(WTIMER0_BASE+TIMER_TBMR_TBMRSU) =1;

    TimerEnable(WTIMER0_BASE, TIMER_B);

    uint32_t i = 1;

I'm using widetimers to achive 50hz to control a servo. This config should configure PIN 5 of Port C to express the Timer Value but I get constant 3.3V on Pin 5 of Port C?

What am i doing wrong?

  • Without digging into your code, I see that you use the same value (Period-1) for both TimerLoadSet() and TimerMatchSet(). To generate a PWM of less than 100%, the match value should be less than the load value.
  • void ServoWrite(uint32_t valor) {
    	uint32_t i = 0;
    	i = Period - ( (valor * 444) + 80000);
    	TimerMatchSet(WTIMER0_BASE, TIMER_A, i);
    }
    
    int main(void) {
        SysCtlClockSet(SYSCTL_SYSDIV_2_5|SYSCTL_USE_PLL|SYSCTL_OSC_MAIN|SYSCTL_XTAL_16MHZ);
    
        SysCtlPeripheralEnable(SYSCTL_PERIPH_WTIMER0);
        SysCtlDelay(3);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);
        SysCtlDelay(3);
        GPIOPinConfigure(GPIO_PC5_WT0CCP1);
        GPIOPinTypeTimer(GPIO_PORTC_BASE, GPIO_PIN_5);
        TimerConfigure(WTIMER0_BASE, TIMER_CFG_SPLIT_PAIR|TIMER_CFG_B_PWM);
        TimerLoadSet(WTIMER0_BASE, TIMER_B, Period-1);
        TimerMatchSet(WTIMER0_BASE, TIMER_B, Period-1);
    
        HWREG(WTIMER0_BASE+TIMER_TBMR_TBMRSU) =1;
    
        TimerEnable(WTIMER0_BASE, TIMER_B);
    
        uint32_t i = 1;
    
    	while(1){
    
    		SysCtlDelay(20000);
    		for(i = 1; i < 30; i++)
    		{
    			ServoWrite(i);
    			SysCtlDelay(26600);
    		}
    		SysCtlDelay(20000);
            for(i = 30; i> 1; i--)
            {
                ServoWrite(i);
                SysCtlDelay(26600);
            }
    
    	}
    
    	return 0;
    }
    

    I have a ServoWrite Funciton which changes the MatchSet

  • In ServoWrite the Timer_A mistake is fixed it still gives constant 3.3 V
  • Enari,

    The code below is a very simple Timer example that generates a periodic output. It is tested to work. As you will see from the parameter, the PWM duty here will be 40%.

    In this case, a standard timer is used (we prefer to use the wide timers only if strictly necessary, because not all parts on the family have those), and the pins are mapped to a TM4C129.

        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
        while(!(SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOD)));
        SysCtlPeripheralDisable(SYSCTL_PERIPH_TIMER1);
        SysCtlPeripheralReset(SYSCTL_PERIPH_TIMER1);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER1);
        while(!(SysCtlPeripheralReady(SYSCTL_PERIPH_TIMER1)));
        GPIOPinTypeTimer(GPIO_PORTD_BASE, GPIO_PIN_3);
        GPIOPinConfigure(GPIO_PD3_T1CCP1);
        TimerConfigure(TIMER1_BASE, TIMER_CFG_SPLIT_PAIR | TIMER_CFG_B_PWM);
        TimerLoadSet(TIMER1_BASE, TIMER_B, 10000);
        TimerMatchSet(TIMER1_BASE, TIMER_B, 4000);
        TimerControlLevel(TIMER1_BASE, TIMER_B, false); // Just an example to make the timer PWM active high
        TimerEnable(TIMER1_BASE, TIMER_B);

    You may want to use this as a step-by-step reference, and only then add your servo controlling features.

    Regards

    Bruno

  • @BrunoSaraiva this not wide timer correct?