cancel
Showing results for 
Search instead for 
Did you mean: 

LED Blinking on STM32 via Register programming problem

SalPaz
Associate II

Hi, I am trying to learn register programming, so I am trying to write a code for STM32G071rb for blinking LD4 which is connected to Pin PA5 using Registers. But unfortunately not only the LED is not blinking, but also the code stocks in line 43 during debugging:

Below you can see the code:

I would appreciate it if you could guide me through this.

// Xtal is set to 64
// Clk is set to 10 MHz 
 
#include "stm32g071xx.h"
 
void SysClockConfig(void);
void GPIO_Config (void);
void delay (uint32_t time);
 
int main (void)
{
	SysClockConfig ();
	GPIO_Config ();
	
	while (1)
	{
		GPIOA->BSRR |= (1<<5);  // Set the pin PA5
		delay (2000); 
		GPIOA->BSRR |= ((1<<5) <<16);  // Reset pin PA5
		delay (2000); 
	}
}
 
void SysClockConfig(void)
{
		/*************>>>>>>> STEPS FOLLOWED <<<<<<<<************
	
	1. ENABLE HSE and wait for the HSE to become Ready
	2. Set the POWER ENABLE CLOCK and VOLTAGE REGULATOR
	3. Configure the FLASH PREFETCH and the LATENCY Related Settings
	4. Configure the PRESCALARS HCLK, PCLK
	5. Configure the MAIN PLL
	6. Enable the PLL and wait for it to become ready
	7. Select the Clock Source and wait for it to be set
	
	********************************************************/
	//converted value
	#define PLL_M 0		//1
	#define PLL_N 16	//16
	#define PLL_R 1		//2
	// 1. ENABLE HSE and wait for the HSE to become Ready
	RCC->CR |= RCC_CR_HSEON;  						
	while (!(RCC->CR & RCC_CR_HSERDY));  	
	
	// 2. Set the POWER ENABLE CLOCK and VOLTAGE REGULATOR
	RCC->APBENR1 |= RCC_APBENR1_PWREN;  	
	PWR->CR1 |= PWR_CR1_VOS;  							
 
	// 3. Configure the FLASH PREFETCH and the LATENCY Related Settings
	FLASH->ACR = FLASH_ACR_ICEN  | FLASH_ACR_PRFTEN | FLASH_ACR_LATENCY_2; 
		
	// 4. Configure the PRESCALARS HCLK, PCLK
	// AHB PR
	RCC->CFGR |= RCC_CFGR_HPRE_0;  // RCC->CFGR &= ~(1<<4);
 
	// 5. Configure the MAIN PLL
	RCC->PLLCFGR = (PLL_M <<4) | (PLL_N << 8) | (PLL_R <<29) | (RCC_PLLCFGR_PLLSRC_HSE);
 
	// 6. Enable the PLL and wait for it to become ready
	RCC->CR |= RCC_CR_PLLON; 
	while (!(RCC->CR & RCC_CR_PLLRDY)); 
 
	// 7. Select the Clock Source and wait for it to be set
	RCC->CFGR |= RCC_CFGR_SW ;  
	while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL);
}
 
void GPIO_Config (void)
{
	/************ STEPS FOLLOWED ***********
	1. Enable the GPIO CLOCK
	2. Set the Pin as OUTPUT
	3. Configure the OUTPUT MODE
	***************************************/
		// 1. Enable the GPIO CLOCK
	RCC->IOPENR |= (1<<0);  
		// 2. Set the Pin as OUTPUT
	GPIOA->MODER |= (1<<10);
		// 3. Configure the OUTPUT MODE
	GPIOA->OTYPER = 0;
	GPIOA->OSPEEDR = 0;
}
void delay (uint32_t time)
{
	while (time--);
}

6 REPLIES 6

For LED blinking test, you can run from HSI, you don't need to switch to HSE/PLL, you can solve that later.

Do you have a crystal attached? What is your hardware, is it a "known good" board e.g. Nucleo?

JW

Yes, it is Nucleo-G071RB

The reason I choose HSE/PLL is only that the youtube video that I am watching is using it.

MM..1
Chief II

Use register is fine , but you need do it right for example hal generate this

void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
 
  /** Configure the main internal regulator output voltage
  */
  HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1);
  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  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;
  RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV1;
  RCC_OscInitStruct.PLL.PLLN = 8;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
  RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
 
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
  {
    Error_Handler();
  }
}

Then you can see voltage is set first , in your code point 2. ... and you realy have 64MHz crystal on nucleo???

You can blind write to BSRR, no need to RMW it

Assume you can't just OR bits onto MODER, or ZERO the entire OTYPER/OSPEEDR. Mask things on carefully so bits that need clearing are, and that you don't blow away critical settings on unrelated pins, like the debug interface pins, etc.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

By default, there is no crystal on the Nucleo-G071RB board, so HSE probably won't work. You should be able to use HSE with BYPASS switched on, as there is a clock output from the STLink chip on the board, but I am not sure if HSERDY will be set in that case.

As I've said, for the simple blinking, you don't need to mess with clocks at all. Simply omit the call to SysClockConfig() for now, you can return to it later.

The delay is probably too short, and you won't see LEDs blinking, you'd need to observe them using oscilloscope. Or, increase the parameter to delay() call to say 20000 or even 200000; you may need to experiment. Also, you need to use volatile

void delay (volatile uint32_t time)

otherwise the compiler may remove that function completely.

As Clive said above, don't |= into BSRR; it is harmless in this particular case, but a bad practice generally.

And, as Clive said, if you set GPIOA_MODER entirely, you change also the setting of pins which are SWD i.e. debug, so you will lose debug at that point.

> The reason I choose HSE/PLL is only that the youtube video that I am watching is using it.

What video? Post link.

JW

> Then you can see voltage is set first , in your code point 2.

That's OK, as system clock won't change until point 7.

JW