Understanding of STM32 library function SystemInit()

Publisher:脑电狂潮Latest update time:2016-12-20 Source: eefocusKeywords:STM32 Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

The SystemInit() function appears in the first line of the main() function, which shows its importance. I have never paid attention to the SystemInit() function before, and I only know that it is a function for initializing the STM32 system. Today I decided to take a closer look and start learning STM32 again. This function is in system_stm32f10x.c, and this C file is mainly used for specific hardware configuration related work.

  1.  


  2.  

  3. void SystemInit (void) 


  4.  

  5.  

  6. RCC->CR |= (uint32_t)0x00000001; 


  7.  

  8. #ifndef STM32F10X_CL 

  9. RCC->CFGR &= (uint32_t)0xF8FF0000; 

  10. #else 

  11. RCC->CFGR &= (uint32_t)0xF0FF0000; 

  12. #endif  


  13.  

  14. RCC->CR &= (uint32_t)0xFEF6FFFF; 


  15.  

  16. RCC->CR &= (uint32_t)0xFFFBFFFF; 


  17.  

  18. RCC->CFGR &= (uint32_t)0xFF80FFFF; 


  19. #ifdef STM32F10X_CL 

  20.  

  21. RCC->CR &= (uint32_t)0xEBFFFFFF; 


  22.  

  23. RCC->CIR = 0x00FF0000; 


  24.  

  25. RCC->CFGR2 = 0x00000000; 

  26. #elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined STM32F10X_HD_VL) 

  27.  

  28. RCC->CIR = 0x009F0000; 


  29.  

  30. RCC->CFGR2 = 0x00000000; 

  31. #else 

  32.  

  33. RCC->CIR = 0x009F0000; 

  34. #endif  


  35. #if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (defined STM32F10X_HD_VL) 

  36. #ifdef DATA_IN_ExtSRAM 

  37. SystemInit_ExtMemCtl(); 

  38. #endif  

  39. #endif 


  40.  

  41.  

  42. SetSysClock(); 


  43. #ifdef VECT_TAB_SRAM 

  44. SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET;  

  45. #else 

  46. SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET;  

  47. #endif 

  48. }



From the function description, this function is to initialize the internal FALSH, PLL and update the system clock. This function needs to be called after reset.

  1. RCC->CR |= (uint32_t)0x00000001;


The first line of code operates the clock control register to enable the internal 8M high-speed clock. From this we can see that after the system starts up, it first relies on the internal clock source to work.

  1. #ifndef STM32F10X_CL 

  2. RCC->CFGR &= (uint32_t)0xF8FF0000; 

  3. #else 

  4. RCC->CFGR &= (uint32_t)0xF0FF0000;


These two lines of code operate the clock configuration register. They mainly set MCO (microcontroller clock output), PLL related (PLL multiplication factor, PLL input clock source), ADCPRE (ADC clock), PPRE2 (high-speed APB division factor), PPRE1 (low-speed APB division factor), HPRE (AHB pre-division factor), SW (system clock switch). At the beginning, the system clock switches to HSI, which is used as the system initial clock. The macro STM32F10X_CL is a macro related to a specific STM32 chip.

  1.  

  2. RCC->CR &= (uint32_t)0xFEF6FFFF; 


  3.  

  4. RCC->CR &= (uint32_t)0xFFFBFFFF; 


  5.  

  6. RCC->CFGR &= (uint32_t)0xFF80FFFF;


These sentences are to configure the related parameters after turning off HSE, CSS, PLL, etc. and then turn them on to achieve the purpose of taking effect.

  1. #ifdef STM32F10X_CL 

  2.  

  3. RCC->CR &= (uint32_t)0xEBFFFFFF; 


  4.  

  5. RCC->CIR = 0x00FF0000; 


  6.  

  7. RCC->CFGR2 = 0x00000000; 

  8. #elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined STM32F10X_HD_VL) 

  9.  

  10. RCC->CIR = 0x009F0000; 


  11.  

  12. RCC->CFGR2 = 0x00000000; 

  13. #else 

  14.  

  15. RCC->CIR = 0x009F0000; 

  16. #endif


This section is mainly about interrupt setup. At the beginning, we need to disable all interrupts and clear all interrupt flags. Different hardware has different settings. 

  1. #if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (defined STM32F10X_HD_VL) 

  2. #ifdef DATA_IN_ExtSRAM 

  3. SystemInit_ExtMemCtl(); 

  4. #endif  

  5. #endif


This paragraph is related to setting external RAM. The STM32F103RBT I used has nothing to do with this.

  1. SetSysClock();


This is another function, which mainly configures the system clock frequency. The frequency division values ​​of HCLK, PCLK2, and PCLK1 represent AHB, APB2, and APB1 respectively. Of course, it also does other things, such as configuring the FLASH delay period and enabling the pre-fetch buffer period. The details of the latter configuration are not yet understood.

  1. #ifdef VECT_TAB_SRAM 

  2. SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET;  

  3. #else 

  4. SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET;  

  5. #endif


This code mainly implements the relocation of the vector table. It depends on whether you want to locate the vector table in the internal SRAM or the internal FLASH. This SCB was not found in the STM32 reference manual at first. It turns out that it is related to the Cortex-M3 core. So ST did not include it. I will learn about the core later, but here is a reminder for myself. 


Then take a look at what the function SetClock() in SystemInit() does.

  1. static void SetSysClock(void) 


  2. #ifdef SYSCLK_FREQ_HSE 

  3. SetSysClockToHSE(); 

  4. #elif definedSYSCLK_FREQ_24MHz 

  5. SetSysClockTo24(); 

  6. #elif definedSYSCLK_FREQ_36MHz 

  7. SetSysClockTo36(); 

  8. #elif definedSYSCLK_FREQ_48MHz 

  9. SetSysClockTo48(); 

  10. #elif definedSYSCLK_FREQ_56MHz 

  11. SetSysClockTo56(); 

  12. #elif definedSYSCLK_FREQ_72MHz 

  13. SetSysClockTo72(); 

  14. #endif 


  15.  

  16. }


It can be seen that different system clocks are set according to different macros, and these macros are in the same source file as this function. The official is very considerate, we only need to select the corresponding macro to achieve the purpose of quickly configuring the system clock.

  1. #if defined (STM32F10X_LD_VL) || (defined STM32F10X_MD_VL) || (defined STM32F10X_HD_VL) 

  2.  

  3. #define SYSCLK_FREQ_24MHz 24000000 

  4. #else 

  5.  

  6.  

  7.  

  8.  

  9.  

  10. #define SYSCLK_FREQ_72MHz 72000000 

  11. #endif


For example, if I need to configure the system clock to 72MHZ, I only need to remove the comment symbols on both sides of #define SYSCLK_FREQ_72MHz 72000000. 
This function also contains the SetSysClockTo72() function, which is used to configure the registers.

  1. #elif definedSYSCLK_FREQ_72MHz 

  2.  

  3. static void SetSysClockTo72(void) 


  4. __IO uint32_t StartUpCounter = 0, HSEStatus = 0; 


  5.  

  6.  

  7. RCC->CR |= ((uint32_t)RCC_CR_HSEON); 


  8.  

  9. do 


  10. HSEStatus = RCC->CR & RCC_CR_HSERDY; 

  11. StartUpCounter++; 

  12. } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); 


  13. if ((RCC->CR & RCC_CR_HSERDY) != RESET) 


  14. HSEStatus = (uint32_t)0x01; 


  15. else 


  16. HSEStatus = (uint32_t)0x00; 



  17. if (HSEStatus == (uint32_t)0x01) 


  18.  

  19. FLASH->ACR |= FLASH_ACR_PRFTBE; 


  20.  

  21. FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY); 

  22. FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2; 



  23.  

  24. RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1; 


  25.  

  26. RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1; 


  27.  

  28. RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2; 


  29. #ifdef STM32F10X_CL 

  30.  

  31.  

  32.  


  33. RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL | 

  34. RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC); 

  35. RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 | 

  36. RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV5); 


  37.  

  38. RCC->CR |= RCC_CR_PLL2ON; 

  39.  

  40. while((RCC->CR & RCC_CR_PLL2RDY) == 0) 





  41.  

  42. RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL); 

  43. RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 | 

  44. RCC_CFGR_PLLMULL9); 

  45. #else 

  46.  

  47. RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | 

  48. RCC_CFGR_PLLMULL)); 

  49. RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9); 

  50. #endif  


  51.  

  52. RCC->CR |= RCC_CR_PLLON; 


  53.  

  54. while((RCC->CR & RCC_CR_PLLRDY) == 0) 




  55.  

  56. RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); 

  57. RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL; 


  58.  

  59. while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08) 




  60. else 

  61. {  



  62. #endif


The above code needs to be looked at carefully. That's pretty much it for SystemInit().


Keywords:STM32 Reference address:Understanding of STM32 library function SystemInit()

Previous article:STM32 general timer---basic timing learning
Next article:How does the STM32 library read and write some pins of the same group of IO ports?

Recommended ReadingLatest update time:2024-11-16 08:28

Example of STM32 external interrupt implemented based on STM32CubeIDE software
This article uses STM32CubeIDE software to implement STM32 external interrupt examples. New Construction "File"-"New"-"STM32 Project". Enter the chip model STM32F103ZE. Select the appropriate package and proceed to the next step. Fill in the project name, select the project location, and click next. Configure
[Microcontroller]
Example of STM32 external interrupt implemented based on STM32CubeIDE software
The first new product, Mier STM32MP2 core board is launched! High performance + multiple interfaces + edge computing power
Mir released the MYC-LD25X core board and development board based on the STM32MP257 embedded processor module. The core board is based on the STM32MP2 series, which is the latest generation of industrial-grade 64-bit microprocessors launched by STMicroelectronics. It adopts LGA 252 PIN design, storage configuration
[Embedded]
The first new product, Mier STM32MP2 core board is launched! High performance + multiple interfaces + edge computing power
Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号