TM4C123G 上的 LED 无法闪烁?

Unable to blink LED on TM4C123G?

我的 TI Tiva ARM 程序无法在 TM4C123G 上运行。使用板 EK TM4C123GXL。程序不会在板载 RGB LED 上闪烁。我能够 运行 其他示例程序来检查 LED,该程序来自教科书 TI TIVA ARM PROGRAMMING FOR EMBEDDED SYSTEMS。需要帮助来调试这个程序。谢谢

代码:

/*  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 */
}

我用的是KEIL IDE-版本:µ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

如果必须使用计数循环延迟,则必须至少声明控制变量 volatile 以确保它们不会 optimised away:

volatile int i, j;

然而,最好避免实施依赖于指令周期和编译器代码生成的延迟。 Cortex-M 内核具有 SYSTICK 时钟,可提供不依赖于编译器代码生成、系统时钟更改或移植到不同 Cortex-M 设备的准确时序。

例如:

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 ) ;

    ...  
  
}

忙等待延迟具有局限性,使其不适用于除最微不足道的程序以外的所有程序。在延迟期间,处理器被束缚——没有做任何有用的事情。使用上面定义的 SYSTICK 和 msTicks 更好的解决方案可能是:

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
    ...
        
}

另请注意使用按位异或运算符来切换 LED。这可以用来简化你原来的循环:

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

编译器版本优化似乎有些问题。恢复到 v5。