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