2022-10-27 01:59 PM
Hi, I am trying to understand the startup process of stm32 mcu. So I have a good knowledge with STM32 and HAL but I want to learn a little deeper with the registers.
So I created a blank project and included only the peripheral header file (stm32wb55xx.h), (system_stm32wbxx.c), the startup script (startup_stm32wb55xx_cm4.s) and main.c where I implemented a blinky and it is working. Where I set the RCC->AHB2ENR(enable clock) register, but I m not sure it's frequency and the frequency's from SYSCLK, HCLK,AHB,APB1...
As far as i understand the startup script is calling the SystemInit() function from system_stm32wbxx.c where the clocks are set to default values and after that the main function is called, where the clock configuration can be changed?
Please correct me if I m wrong! And if someone have some links or documentation for properly setting the clocks.
Thanks
Solved! Go to Solution.
2022-10-28 10:06 AM
Three documents are needed to tell you (pretty much) everything about your stm32. They are the Data Sheet, the Reference Manual and the Programming Manual.
The data sheet contains a lot of the electrical, timing and pin-out stuff.
There's a huge amount of information in the Reference Manual, pretty densely packed, and it can be scary on first glance. It describes all the bits of the stm32 that ST designed.
So what bits of stm32 didn't ST design? The arm core, and core peripherals such as the vector-interrupt-controller. These are described in the Programming Manual.
Where would you find the answer to your question? I see the answer in two places:
In the Data Sheet, in section 3.10 "Clocks and Startup"
Startup clock: after reset, the microcontroller restarts by default with an internal 4 MHz clock (MSI). The prescaler ratio and clock source can be changed by the applicationprogram as soon as the code execution starts.
In the Reference Manual, section 8.4 RCC Registers. The key registers for clock source are RCC_CR and RCC_CFGR.
The Reference Manual says at power-on-reset RCC_CR is 0x00000061 so MSI is 4 MHz and enabled; RCC_CFGR is 0x00070000 so system-clock-switch selects MSI, hence 4 MHz.
The reference manual also says that at wakeup-from-standby-reset, RCC_CR is 0x00000160 so HSI is enabled (16 MHz); RCC_CFGR is 0x00070001 so system-clock-switch selects HSI hence 16 MHz.
Now there's a huge amount of detail in those manuals, and it can be daunting and off-putting. Hence ST have written the HAL stuff, to give you an "easy" C interface. But I find HAL inadequately documented; I don't see much more than the examples of usage and the source-code of the HAL functions. So I prefer to use register access guided by the Reference Manual.
Hope this helps,
Danish
2022-10-28 10:06 AM
Three documents are needed to tell you (pretty much) everything about your stm32. They are the Data Sheet, the Reference Manual and the Programming Manual.
The data sheet contains a lot of the electrical, timing and pin-out stuff.
There's a huge amount of information in the Reference Manual, pretty densely packed, and it can be scary on first glance. It describes all the bits of the stm32 that ST designed.
So what bits of stm32 didn't ST design? The arm core, and core peripherals such as the vector-interrupt-controller. These are described in the Programming Manual.
Where would you find the answer to your question? I see the answer in two places:
In the Data Sheet, in section 3.10 "Clocks and Startup"
Startup clock: after reset, the microcontroller restarts by default with an internal 4 MHz clock (MSI). The prescaler ratio and clock source can be changed by the applicationprogram as soon as the code execution starts.
In the Reference Manual, section 8.4 RCC Registers. The key registers for clock source are RCC_CR and RCC_CFGR.
The Reference Manual says at power-on-reset RCC_CR is 0x00000061 so MSI is 4 MHz and enabled; RCC_CFGR is 0x00070000 so system-clock-switch selects MSI, hence 4 MHz.
The reference manual also says that at wakeup-from-standby-reset, RCC_CR is 0x00000160 so HSI is enabled (16 MHz); RCC_CFGR is 0x00070001 so system-clock-switch selects HSI hence 16 MHz.
Now there's a huge amount of detail in those manuals, and it can be daunting and off-putting. Hence ST have written the HAL stuff, to give you an "easy" C interface. But I find HAL inadequately documented; I don't see much more than the examples of usage and the source-code of the HAL functions. So I prefer to use register access guided by the Reference Manual.
Hope this helps,
Danish
2022-10-29 03:41 AM
Thanks @Danish for such clear answer. Yes I know datasheet and reference manual and I m reading it a lot but sometimes I can't follow it.
Thanks
2022-11-03 11:39 PM
every specified MCU has it's default internal clock after boot, someone it MSI, someone is HSI..., except the reference manual and datasheet, you also can get the code example project form ST official website https://www.st.com/content/st_com/en/search.html#q=STM32F302-t=resources-page=1 to find the TOOLS&Software for your expect development board. you will get all the MCU modules code examples, include configure clock, code like below:
/**
* @brief System Clock Configuration
* The system Clock is configured as follow :
* System Clock source = PLL (HSE BYPASS)
* SYSCLK(Hz) = 400000000 (CPU Clock)
* HCLK(Hz) = 200000000 (AXI and AHBs Clock)
* AHB Prescaler = 2
* D1 APB3 Prescaler = 2 (APB3 Clock 100MHz)
* D2 APB1 Prescaler = 2 (APB1 Clock 100MHz)
* D2 APB2 Prescaler = 2 (APB2 Clock 100MHz)
* D3 APB4 Prescaler = 2 (APB4 Clock 100MHz)
* HSE Frequency(Hz) = 8000000
* PLL_M = 4
* PLL_N = 400
* PLL_P = 2
* PLL_Q = 4
* PLL_R = 2
* VDD(V) = 3.3
* Flash Latency(WS) = 4
* @param None
* @retval None
*/
static void SystemClock_Config(void)
{
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_OscInitTypeDef RCC_OscInitStruct;
HAL_StatusTypeDef ret = HAL_OK;
/*!< Supply configuration update enable */
HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY);
/* 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);
while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {}
/* Enable HSE Oscillator and activate PLL with HSE as source */
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS;
RCC_OscInitStruct.HSIState = RCC_HSI_OFF;
RCC_OscInitStruct.CSIState = RCC_CSI_OFF;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 4;
RCC_OscInitStruct.PLL.PLLN = 400;
RCC_OscInitStruct.PLL.PLLFRACN = 0;
RCC_OscInitStruct.PLL.PLLP = 2;
RCC_OscInitStruct.PLL.PLLR = 2;
RCC_OscInitStruct.PLL.PLLQ = 4;
RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;
RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_1;
ret = HAL_RCC_OscConfig(&RCC_OscInitStruct);
if(ret != HAL_OK)
{
Error_Handler();
}
/* Select PLL as system clock source and configure bus clocks dividers */
RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_D1PCLK1 | RCC_CLOCKTYPE_PCLK1 | \
RCC_CLOCKTYPE_PCLK2 | RCC_CLOCKTYPE_D3PCLK1);
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2;
RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2;
RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2;
ret = HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4);
if(ret != HAL_OK)
{
Error_Handler();
}
}