# STM32 HAL can't turn LED on

I am trying to advance my coding skills and venture into the world of high-end microcontrollers, coming mainly from a Java background (1 year of android developer as a daytime job plus a bit of C developing around Attiny in Atmel Studio) I fell in love with the abstraction provided by STM's HAL. I am aware that this is a sub-optimal solution from an optimization point of view but decided to go down this way because of how promisingly fast it looks.

I started from the very basics, turning on a LED but, after an evening of no luck I really need some help.

Here is my code, it is compiling fine, uploading fine but... nothing happens!

I'm using an STM32F4-Discovery board.

#include "stm32f4xx.h"
#include "stm32f4_discovery.h"

GPIO_InitTypeDef GPIO_InitStructure;

int main(void)
{

HAL_Init();

__GPIOD_CLK_ENABLE();
GPIO_InitStructure.Pin   = GPIO_PIN_15;
GPIO_InitStructure.Mode  = GPIO_MODE_OUTPUT_PP;
GPIO_InitStructure.Pull  = GPIO_PULLUP;
GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
HAL_GPIO_Init(GPIOD, &GPIO_InitStructure);

while (1) {

HAL_GPIO_WritePin(GPIOD, GPIO_PIN_15, GPIO_PIN_SET);
}
}

• How is the LED connected to the µC? – JimmyB Oct 25 '16 at 21:45
• On-board blue LED – Caterpillaraoz Oct 25 '16 at 21:55
• If you have an STM32F4 Discovery then you have an on board debugger, so you can check where your code stuck. The below answer is probably correct by the way. – Bence Kaulics Oct 26 '16 at 8:04

Basically what @bitsmack suggested should look something like this:

#include "stm32f4xx.h"
#include "stm32f4xx_hal_cortex.h"
#include "stm32f4xx_hal.h"

void SystemClock_Config(void);

int main(void)
{
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();

/* Configure the system clock */
SystemClock_Config();

/* Initialize all configured peripherals */
__GPIOD_CLK_ENABLE();
GPIO_InitStructure.Pin   = GPIO_PIN_15;
GPIO_InitStructure.Mode  = GPIO_MODE_OUTPUT_PP;
GPIO_InitStructure.Pull  = GPIO_PULLUP;
GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
HAL_GPIO_Init(GPIOD, &GPIO_InitStructure);

while (1) {
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_15, GPIO_PIN_SET);
}

}

/**
* @brief  System Clock Configuration
*         The system Clock is configured as follow :
*            System Clock source            = PLL (HSE)
*            SYSCLK(Hz)                     = 168000000
*            HCLK(Hz)                       = 168000000
*            AHB Prescaler                  = 1
*            APB1 Prescaler                 = 4
*            APB2 Prescaler                 = 2
*            HSE Frequency(Hz)              = HSE_VALUE
*            PLL_M                          = (HSE_VALUE/1000000u)
*            PLL_N                          = 336
*            PLL_P                          = 2
*            PLL_Q                          = 7
*            VDD(V)                         = 3.3
*            Main regulator output voltage  = Scale1 mode
*            Flash Latency(WS)              = 5
* @param  None
* @retval None
*/
void SystemClock_Config(void)
{
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_OscInitTypeDef RCC_OscInitStruct;

// Enable Power Control clock
__PWR_CLK_ENABLE();

// The voltage scaling allows optimizing the power consumption when the
// device is clocked below the maximum system frequency, to update the
// voltage scaling value regarding system frequency refer to product
// datasheet.
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

// Enable HSE Oscillator and activate PLL with HSE as source
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;

// This assumes the HSE_VALUE is a multiple of 1MHz. If this is not
// your case, you have to recompute these PLL constants.
RCC_OscInitStruct.PLL.PLLM = (HSE_VALUE/1000000u);
RCC_OscInitStruct.PLL.PLLN = 336;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 7;
HAL_RCC_OscConfig(&RCC_OscInitStruct);

// Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2
// clocks dividers
RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK
| RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5);
}


I hope the comments are descriptive enough. This should work with an STM32F4 Discovery.

As for the other suggestion, STM32CubeMX, it gives a transparent way to configure your clocks (and other peripherals as well). You can check all the different buses and how they are clocked, switch between clock sources. You can see what for example what the PLL_M, PLL_N, PLL_P, PLL_Q values exactly stand for. You can obtain this information from reference manual of the controller as well, but that would be a bit raw compared to this graphical representation.

I haven't used this HAL, but it looks like you are missing some necessary system configuration code. I would expect to see (at least) something like this:

RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_ClkInitTypeDef RCC_ClkInitStruct;

HAL_Init();

// Oscillator settings here:
// ...
// ...
HAL_RCC_OscConfig(&RCC_OscInitStruct);

// System clock settings here:
// ...
// ...
HAL_RCC_ClockConfig(&RCC_ClkInitStruct);


Since you are using the HAL, I recommend you use the STM32CubeMX application build your startup code.

• Thankyou! at first I didnt realise the huge difference between smt32cubef4 (a software package) and stm32cubemx (a config tool). – Caterpillaraoz Oct 26 '16 at 15:11