Home > Net >  Unable to blink LED on TM4C123G?
Unable to blink LED on TM4C123G?

Time:12-30

My TI Tiva ARM program is not working on TM4C123G. Using board EK TM4C123GXL. Program doesn't blink on board RGB LEDs. I am able to run other example program to check the LEDs, this program is from textbook TI TIVA ARM PROGRAMMING FOR EMBEDDED SYSTEMS. Need help to debug this program. Thanks

Code:

/*  p2.4.c: Toggling a single LED

/*  This program turns on the red LED and toggles the blue LED 0.5 sec on and 0.5 sec off. */

#include "TM4C123GH6PM.h"

void delayMs(int n);

int main(void)
{

    /* enable clock to GPIOF at clock gating control register */
    SYSCTL->RCGCGPIO |= 0x20;
    /* enable the GPIO pins for the LED (PF3, 2 1) as output */
    GPIOF->DIR = 0x0E;
    /* enable the GPIO pins for digital function */
    GPIOF->DEN = 0x0E;
    /* turn on red LED only and leave it on */
    GPIOF->DATA = 0x02;
    
    while(1)
    {      
        GPIOF->DATA |= 4;    /* turn on blue LED */
        delayMs(500);

        GPIOF->DATA &= ~4;   /* turn off blue LED */
        delayMs(500); 
    }
}

/* delay n milliseconds (16 MHz CPU clock) */
void delayMs(int n)
{
    int i, j;
    for(i = 0 ; i < n; i  )
        for(j = 0; j < 3180; j  )
        {}  /* do nothing for 1 ms */
}

I am using KEIL IDE-Version: µVision V5.36.0.0

Tool Version Numbers:
Toolchain:        MDK-Lite  Version: 5.36.0.0
Toolchain Path:    G:\Keil_v5\ARM\ARMCLANG\Bin
C Compiler:         ArmClang.exe        V6.16
Assembler:          Armasm.exe        V6.16
Linker/Locator:     ArmLink.exe        V6.16
Library Manager:    ArmAr.exe        V6.16
Hex Converter:      FromElf.exe        V6.16
CPU DLL:               SARMCM3.DLL          V5.36.0.0
Dialog DLL:         TCM.DLL              V1.53.0.0
Target DLL:             lmidk-agdi.dll       V???
Dialog DLL:         TCM.DLL              V1.53.0.0

CodePudding user response:

Avoid implementing delays that rely on instruction cycles and the compiler;s cod generation. The Cortex-M core has a SYSTICK clock that provides accurate timing that does not rely on the compiler's code generation, changes to the system clock, or porting to different Cortex-M devices.

For example:

volatile uint32_t msTicks = 0 ;
  
void SysTick_Handler(void)  
{
    msTicks  ; 
}

void delayMs( uint32_t n )
{
    uint32_t start = msTicks ;
    while( msTicks - start < n )
    {
        // wait
    }
}
  
int main (void)  
{
    // Init SYSTICK interrupt interval to 1ms
    SysTick_Config( SystemCoreClock / 1000 ) ;

    ...  
  
}

If you must use a counting, you must at least declare the control variables volatile to be sure they will not be optimised away:

volatile int i, j;

A busy-wait delay has limitations that make it unsuitable for all but the most trivial programs. During the delay the processor is tied up-doing nothing useful. Using the SYSTICK and msTicks defined as above you a better solution might be:

uint32_t blink_interval = 1000u ;
uint32_t next_toggle = msTicks   blink_interval ;

for(;;)
{
    // If time to toggle LED ...
    if( (int32_t)(msTicks - next_toggle) <= 0 )
    {
        // Toggle LED and advance toggle time
        GPIOF->DATA ^= 4 ; 
        next_toggle  = blink_interval ;
    }

    // Do other work while blinking LED
    ...
        
}

Note also the use of the bitwise-XOR operator to toggle the LED. That could be used to simplify you original loop:

while(1)
{      
    GPIOF->DATA ^= 4 ;
    delayMs( 500 ) ;
}

CodePudding user response:

It looks like some issue with the compiler version optimization. Reverted back to v5. Here is what to do

  • Related