cmicrocontrollerresetstm32f4

STM32F4 Program Will Only Run After Pressing Reset Button


I recently purchased a NUCLEO-F446RE board (an STM32F4 product) and one minor issue has been bugging me. All the code I've written executes and works just fine, but they only work after pressing the reset button on the NUCLEO board.

IDE: Keil v5

For example, I wrote code for a blinking LED:

#include "stm32f446xx.h"    
int main(void) {

    RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN;
    GPIOA->MODER |= GPIO_MODER_MODE5_0;
    GPIOA->ODR |= GPIO_ODR_OD5;
    volatile int i;

    while(1) {

        for(i=0; i<100000; i++)
            GPIOA->ODR |= GPIO_ODR_OD5;

        for(i=0; i<100000; i++)
            GPIOA->ODR &= ~GPIO_ODR_OD5;
    }
}

After I run and download the code onto the board, nothing will happen. Once I press reset, the LED will blink as expected.

I'm fairly certain it's something not included in my code because when I run an example program it executes immediately.

For example, a blinking LED provided by KIEL:

#include <stdio.h>

#include "Board_LED.h"                  // ::Board Support:LED
#include "Board_Buttons.h"              // ::Board Support:Buttons

#include "stm32f4xx.h"                  // Device header


extern int stdout_init (void);

volatile uint32_t msTicks;                            /* counts 1ms timeTicks */
/*----------------------------------------------------------------------------
 * SysTick_Handler:
 *----------------------------------------------------------------------------*/
void SysTick_Handler(void) {
  msTicks++;
}

/*----------------------------------------------------------------------------
 * Delay: delays a number of Systicks
 *----------------------------------------------------------------------------*/
void Delay (uint32_t dlyTicks) {
  uint32_t curTicks;

  curTicks = msTicks;
  while ((msTicks - curTicks) < dlyTicks) { __NOP(); }
}

/*----------------------------------------------------------------------------
 * SystemCoreClockConfigure: configure SystemCoreClock using HSI
                             (HSE is not populated on Nucleo board)
 *----------------------------------------------------------------------------*/
void SystemCoreClockConfigure(void) {

  RCC->CR |= ((uint32_t)RCC_CR_HSION);                     /* Enable HSI */
  while ((RCC->CR & RCC_CR_HSIRDY) == 0);                  /* Wait for HSI Ready */

  RCC->CFGR = RCC_CFGR_SW_HSI;                             /* HSI is system clock */
  while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI);  /* Wait for HSI used as system clock */

  FLASH->ACR  = (FLASH_ACR_PRFTEN     |                    /* Enable Prefetch Buffer */
                 FLASH_ACR_ICEN       |                    /* Instruction cache enable */
                 FLASH_ACR_DCEN       |                    /* Data cache enable */
                 FLASH_ACR_LATENCY_5WS );                  /* Flash 5 wait state */

  RCC->CFGR |= (RCC_CFGR_HPRE_DIV1  |                      /* HCLK = SYSCLK */
                RCC_CFGR_PPRE1_DIV2 |                      /* APB1 = HCLK/2 */
                RCC_CFGR_PPRE2_DIV1  );                    /* APB2 = HCLK/1 */

  RCC->CR &= ~RCC_CR_PLLON;                                /* Disable PLL */

  /* PLL configuration:  VCO = HSI/M * N,  Sysclk = VCO/P */
  RCC->PLLCFGR = ( 16ul                   |                /* PLL_M =  16 */
                 (200ul <<  6)            |                /* PLL_N = 200 */
                 (  0ul << 16)            |                /* PLL_P =   2 */
                 (RCC_PLLCFGR_PLLSRC_HSI) |                /* PLL_SRC = HSI */
                 (  7ul << 24)            |                /* PLL_Q =   7 */
                 (  2ul << 28)             );              /* PLL_R =   2 */

  RCC->CR |= RCC_CR_PLLON;                                 /* Enable PLL */
  while((RCC->CR & RCC_CR_PLLRDY) == 0) __NOP();           /* Wait till PLL is ready */

  RCC->CFGR &= ~RCC_CFGR_SW;                               /* Select PLL as system clock source */
  RCC->CFGR |=  RCC_CFGR_SW_PLL;
  while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL);  /* Wait till PLL is system clock src */
}

/*----------------------------------------------------------------------------
 * main: blink LED and check button state
 *----------------------------------------------------------------------------*/
int main (void) {
  int32_t max_num = LED_GetCount();
  int32_t num = 0;

  SystemCoreClockConfigure();                              /* configure HSI as System Clock */
  SystemCoreClockUpdate();

  LED_Initialize();
  Buttons_Initialize();
  stdout_init();                                           /* Initializ Serial interface */

  SysTick_Config(SystemCoreClock / 1000);                  /* SysTick 1 msec interrupts */

  for (;;) {
    LED_On(num);                                           /* Turn specified LED on */
    Delay(500);                                            /* Wait 500ms */
    while (Buttons_GetState() & (1 << 0));                 /* Wait while holding USER button */
    LED_Off(num);                                          /* Turn specified LED off */
    Delay(500);                                            /* Wait 500ms */
    while (Buttons_GetState() & (1 << 0));                 /* Wait while holding USER button */

    num++;                                                 /* Change LED number */
    if (num >= max_num) {
      num = 0;                                             /* Restart with first LED */
    }

    printf ("Hello World\n\r");
  }

}

The example code doesn't appear to have anything special that will make it run immediately.

Any help is greatly appreciated.


Solution

  • My guess is that it's in the project flash tools settings, maybe "run to main" or "Load Application at Startup" (not your code). To check, copy/paste your code over the top of one of the samples.