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: Timer0 in TM4C123GH6PM is not working

Part Number: TM4C123GH6PM
I wanted to use timers in TM4C123GH6PM (in TIVA C series TM4C123G Launchpad evaluation kit). So I decided to use GPTM TimerA0 in periodic timer mode. I defined the address of the 
registers of GPTM and followed the steps given in the section 11.4.1 One-Shot/Periodic Timer Mode of the datasheet in page 722. I want a LED to blink after every 3 seconds (connected to
PORT F-pin 1). But the LED is always ON. Are the address of the registers to which I am referring wrong? Or something else is the issue with the code?



//TIMER Registers #define RCGCTIMER (*((volatile unsigned long *)0x400FE604)) #define GPTMCTL (*((volatile unsigned long *)0x4003000C)) //timer zero #define GPTMCFG (*((volatile unsigned long *)0x40030000)) #define GPTMTAMR (*((volatile unsigned long *)0x40030004)) #define GPTMTAILR (*((volatile unsigned long *)0x40030028)) #define GPTMRIS (*((volatile unsigned long *)0x4003001C)) #define GPTMICR (*((volatile unsigned long *)0x40030024)) //PORT F Registers #define GPIO_PORTF_LOCK_R (*((volatile unsigned long *)0x40025520)) #define GPIO_PORTF_DATA_R (*((volatile unsigned long*)0x400253FC)) #define GPIO_PORTF_DIR_R (*((volatile unsigned long *)0x40025400)) #define GPIO_PORTF_AFSEL_R (*((volatile unsigned long *)0x40025420)) #define GPIO_PORTF_DEN_R (*((volatile unsigned long *)0x4002551C)) #define SYSCTL2_RCGC2_R (*((volatile unsigned long *)0x400FE108)) #define SYSCTL_RCGC2_GPIOF 0x00000020 // port F Clock Gating Control void initializeTimer() { RCGCTIMER |= 0x00000001 ; //To use a GPTM, the appropriate TIMERn bit must be set in the RCGCTIMER. Here it is TIMER0 //Periodic timer mode GPTMCTL &=(~0x00000001); //TAEN is set 0. Timer A is disabled. GPTMCFG = 0x00000000; //Write the GPTM Configuration Register (GPTMCFG) with a value of 0x0000.0000 GPTMTAMR = 0x00000002; //TAMR is set 0x2. Periodic Timer mode is used (first bit1 is set 1 and then bit0 is set 0 in two statements) GPTMTAMR &= 0xFFFFFFEF; //TACDIR is set 0. The timer counts down. GPTMTAILR = 0x02DC6C00; //TAILR is set to 48,000,000 GPTMCTL |=0x00000001; //TAEN is set 1. Timer A is enabled. } void initializePORTF() { volatile unsigned long delay; SYSCTL2_RCGC2_R |= 0x00000020; // 1) F clock delay = SYSCTL2_RCGC2_R; // delay GPIO_PORTF_LOCK_R = 0x4C4F434B; // 2) unlock GPIO Port F GPIO_PORTF_DIR_R |= 0x02; // PF2 output GPIO_PORTF_AFSEL_R &= 0x00; // No alternate function// 1) F clock GPIO_PORTF_DEN_R |= 0x02; // Enable digital pins PF2 GPIO_PORTF_DATA_R |= 0x02; //PF1 Set to 1. LED is ON } int main() { initializeTimer(); initializePORTF(); while(1) { //did TATORIS in GPTMRIS become 1?? if((GPTMRIS | 0x00000001) == 1) { GPTMICR |= 0x00000001; //Set 1 to TATOCINT. Writing a 1 to this bit clears the TATORIS bit in the GPTMRIS register and the TATOMIS bit in the GPTMMIS register. GPIO_PORTF_DATA_R ^= 0x02; //Toggle PF1. Toggle LED } } }

  • Hello Deepak,

    Please use TivaWare instead of using the DRM method. As you can see , you are also questioning the validity of the registers.
  • Hi ,

       Thank you for the reply. The aim is actually to learn things and so I wrote them myself. I just checked http://users.ece.utexas.edu/~valvano/arm/tm4c123gh6pm.h  and found that all the register address are correct. But I am still not sure why the LED is always ON. 

    Regards

    Deepak

  • Hello Deepak

    Clearly not in this case. DRM is a method when the user is 100% sure of the self's abilities to optimize and understand the code 6 months later. This is a common myth, that DRM aids learning. Sometimes it may, but most of the time not. I would suggest that you move to TivaWare, where I can help you more efficiently.
  • Amit Ashara said:
    This is a common myth, that DRM aids learning.

    If - by "retarding" efficiency, understanding & achievement - then we (may) agree that DRM aids learning.

    What (really) has poster learned (beyond) endless MCU manual "page turning" - in the attempt to correctly transcribe (every) critical bit (and there are often 32) from printed manual - to an, "overly complex" MCU code listing?

    Will this poster - and others - remember each/every one of these unique Registers & Individual bit settings?   After one week?   After a month?   After 6 months - when called to "fix" something?

    Should (this) poster or ALL others seek "REAL LEARNING" this vendor's API has, "Stood the test of time!"   The API is comprehensive, filled w/working code examples, and most importantly, "Tried, True, Tested!"

    And (some) school enforced DRM - can it EVER be classed as, "Tried, True, Tested?"   It takes (forever) to develop code in that manner - and (should) the code work (never assured) - it is NEVER, "User Friendly" nor intuitive.

    Horse & Buggy, steam-propelled water-craft, and (delightful) DRM (may) have (some) place in history books - but NOT in any "going concern" where, "Correct, Robust, and Time Efficient Code Development" is required!

  • Hi,

       I made my LED blink. The delay I chose earlier was too less and that made it appear as if the LED was always ON. Now increased the delay value and found the LED to be blinking. But there is a new problem. The MCU by default clocks at 16HHz. So I expected the earlier code to

     GPTMTAILR = 0x02DC6C00; //TAILR is set to 48,000,000

    blink my LED after every 3 seconds. But it is not actually 3 seconds when I tried running it on my MCU. So I doubt the clock frequency is 16MHz. I have not activated my PLL also. I don't know what the issue is. Will try figuring out. In the mean time if you get what the issue is, help me out.

    Code:

    //I wanted to use timers in TM4C123GH6PM (in TIVA C series TM4C123G Launchpad evaluation kit). So I decided to use GPTM TimerA0 in periodic timer mode. I defined the address of the registers of GPTM and followed the steps given in the datasheet. I want an LED to blink after every 3 seconds (connected to PORT F pin 1). But the LED is always ON. Are the address of the registers to which I am refering wrong? Or something else is the issue with the code?  
    	
    //TIMER Registers
    #define RCGCTIMER        		 (*((volatile unsigned long *)0x400FE604))
    #define GPTMCTL					 (*((volatile unsigned long *)0x4003000C)) //timer zero
    #define GPTMCFG					 (*((volatile unsigned long *)0x40030000))
    #define GPTMTAMR				 (*((volatile unsigned long *)0x40030004))	
    #define GPTMTAILR				 (*((volatile unsigned long *)0x40030028))
    #define GPTMRIS				     (*((volatile unsigned long *)0x4003001C))
    #define GPTMICR				     (*((volatile unsigned long *)0x40030024))
    	
    //PORT F Registers
    
    #define GPIO_PORTF_LOCK_R       (*((volatile unsigned long *)0x40025520))
    #define GPIO_PORTF_DATA_R       (*((volatile unsigned long*)0x400253FC))
    #define GPIO_PORTF_DIR_R        (*((volatile unsigned long *)0x40025400))
    #define GPIO_PORTF_AFSEL_R      (*((volatile unsigned long *)0x40025420))
    #define GPIO_PORTF_DEN_R        (*((volatile unsigned long *)0x4002551C))
    #define SYSCTL2_RCGC2_R          (*((volatile unsigned long *)0x400FE108))
    #define SYSCTL_RCGC2_GPIOF      0x00000020  // port F Clock Gating Control 
    	
    
    
    void initializeTimer()
    {
    	RCGCTIMER |= 0x00000001  ; //To use a GPTM, the appropriate TIMERn bit must be set in the RCGCTIMER. Here it is TIMER0
     
    	//Periodic timer mode
    	
        GPTMCTL &=(~0x00000001); //TAEN is set 0. Timer A is disabled.
    	GPTMCFG = 0x00000000; //Write the GPTM Configuration Register (GPTMCFG) with a value of 0x0000.0000
    	GPTMTAMR = 0x00000002; //TAMR is set 0x2. Periodic Timer mode is used (first bit1 is set 1 and then bit0 is set 0 in two statements)
    	GPTMTAMR &= 0xFFFFFFEF; //TACDIR is set 0. The timer counts down.
    	GPTMTAILR = 0x00FFFFFF; //TAILR is set to 48,000,000 
    	GPTMCTL |=0x00000001; //TAEN is set 1. Timer A is enabled.
    }
    
    void initializePORTF()
    {
      volatile unsigned long delay;
      SYSCTL2_RCGC2_R |= 0x00000020;     // 1) F clock
      delay = SYSCTL2_RCGC2_R;           // delay   
      GPIO_PORTF_LOCK_R = 0x4C4F434B;   // 2) unlock GPIO Port F
      GPIO_PORTF_DIR_R |= 0x02;         // PF2 output  
      GPIO_PORTF_AFSEL_R &= 0x00;       // No alternate function// 1) F clock
      GPIO_PORTF_DEN_R |= 0x02;         // Enable digital pins PF2  
      GPIO_PORTF_DATA_R |= 0x02;        //PF1 Set to 1. LED is ON
    }
    
    void delay(long int a)
    {
    	long int i;
    	for(i=-a;i<=a;i++)
    	{
    
    		//did TATORIS in GPTMRIS become 1??
    		if((GPTMRIS | 0x00000001) == 1)
    		{
    			GPTMICR |= 0x00000001; //Set 1 to TATOCINT. Writing a 1 to this bit clears the TATORIS bit in the GPTMRIS register and the TATOMIS bit in the GPTMMIS register. 
    		}
    	}
    
    }	
    int main()
    {
    	initializeTimer();
    	initializePORTF();
    	
    	while(1)
    	{
    		delay(100000);
    		GPIO_PORTF_DATA_R ^= 0x02; //Toggle PF1. Toggle LED
    	}
    }

  • Hello Deepak

    If the intent is to delay by 3 seconds, then the use of a timer is highly over-rated. Rather use the timer in PWM mode with pre-scalar so that the LED is controlled by the PWM output from the timer instead of such a complicated loop.

    If software control is what is required then a SysCtlDelay(X) is more than enough. Each X is 3 system clocks. So by knowing the system clock the delay can be determined quite well.
  • Noted is poster's continued use of the dreaded, inefficient, and anti-learning "DRM."

    While he seeks (our) effort, "Helping him out" he avoids the requested switch to the API to, "help us out."