# 2-STM32F103-復位和時鐘控制RCC

STM32-復位和時鐘控制RCC

  • 2-STM32-復位和時鐘控制RCC
  • 摘要
  • 說明
    • 本文參考資料如下:
  • 一、STM32最小系統回顧
    • STM32F103C8T6核心板原理圖
  • 二、復位
  • 三、時鐘
    • 3.1 時鐘樹
    • 3.2 STM32啟動過程
    • 3.2 SystemInit()函數
      • 3.2.1 SystemInit()第1句:
      • 3.2.2 SystemInit()第2句:
      • 3.2.3 SystemInit()第3句:
    • 3.3 SetSysClock()函數:
    • 3.4 SetSysClockTo72()函數:
      • 3.4.1 SetSysClockTo72()第1句:
      • 3.4.2 SetSysClockTo72()第2句:
      • 3.4.3 SetSysClockTo72()第3句:
      • 3.4.4 SetSysClockTo72()第4句:
      • 3.4.5 SetSysClockTo72()第5句:
      • 3.4.6 SetSysClockTo72()第6句:
      • 3.4.7 SetSysClockTo72()第7句:
  • 四、標準庫與HAL庫區別
    • 4.1 HAL庫SystemInit()函數
    • 4.1 HAL庫配置系統時鐘為72MHz函數
      • 4.1.1 Stm32_Clock_Init函數
    • 4.1 HAL庫配置系統時鐘為72MHz函數
  • 五、總結
  • 六、資料連接

2-STM32-復位和時鐘控制RCC

摘要

在上一篇文章中,我們講解了STM32F103C8T6最小系統中復位和時鐘硬件部分,在本章中講解最小系統中的復位和時鐘的軟件部分。本文章根據《1-STM32F10x-中文參考手冊》的第6節復位和時鐘為依據,并介紹時鐘源選擇外部8MHz晶震HSE,通過SystemInit()函數將STM32時鐘配置為72HMz的代碼,并在最后對比標準庫和HAL庫對時鐘配置的不同。

說明

本系列,將整理STM32F103內置外設的使用,“基于標準庫“進行學習開發,并將手冊說明與標準庫代碼進行對應學習,在文章最后提供本系列中參考的文章和工程代碼下載鏈接。

本文參考資料如下:


## 1.硬件平臺
STM32F103C8T6最小系統板
## 2.軟件平臺
MDK5
## 3.參考文檔
1.《1-STM32F10x-中文參考手冊》
2.《3-STM32F103xCDE數據手冊-中文》
3. 《STM32F103C8T6核心板原理圖》
4.《Cortex-M3權威指南》

一、STM32最小系統回顧

在上一節STM32最小系統中,講解了STM32最小系統由:電源、時鐘、下載、復位、啟動五個部分組成,本文主要講解時鐘和復位兩個部分,因為這兩個部分和后續編程緊密相連,而電源、下載、啟動三個部分相對固定,編程上不需要太多改動。

STM32F103C8T6核心板原理圖

STM32F103C8T6核心板原理圖
圖中標紅的兩個部分,時鐘和復位就是本文要講述的部分。復位使用NRST引腳復位,時鐘使用外部晶體震蕩器HSE

二、復位

由《1-STM32F10x-中文參考手冊》的第6節復位和時鐘可知,STM32復位方式有三類:系統復位、上電復位、備份區域復位,其中系統復位包含了:NRST引腳復位
復位方式

由系統復位方式可知:一共有5種復位方式,STM32最小系統中的復位就是NRST引腳復位,是硬件復位方式,也是最常用的一種復位方式。其余四種都是軟件復位,IWDG、WWDG、SW三種復位方式,在后續看門狗實驗時講解。低功耗復位在低功耗實驗時講解。

三、時鐘

時鐘源選擇

根據《1-STM32F10x-中文參考手冊》的第6節時鐘部分可知,STM32F103有5種時鐘源,但是系統時鐘源SYSCLK只有三種選擇,HSE、HSI、PLL,LSI和LSE兩種低速時鐘是提供給RTC和IWDG使用。其中HSE和LSE是需要我們自己外接晶振的,HSI和LSI是STM32F103C8T6內置的,PLL是取自HSE或HSI。由于HSI不精確,所以為了系統時鐘SYSCLK能達到72MHz,我們只能選擇HSE。如果沒有外接HSE的話,單片機會自動使用內部8MHz的HSI作為系統時鐘SYSCLK,此時系統時鐘就只有8MHz,且不精確。

3.1 時鐘樹

時鐘樹

時鐘樹是《1-STM32F10x-中文參考手冊》的第6節時鐘的圖,此圖介紹了5種時鐘源是如何提供給單片機內部其它外設的,我們本文主要關心圖中紅色線:通過外接8MHz晶振,并通過倍頻器PLL進行9倍放大后,得到72MHz的系統時鐘SYSCLK的過程。外接8MHz晶振我們在STM32最小系統中,我們已經連接了時鐘電路,即已經接好了外部8MHz晶振,接下來我們通過SystemInit()函數配置RCC的時鐘控制寄存器CR和時鐘配置寄存器CFGR,將SYSCLK配置為72MHz。
注:圖中梯形表示選擇器,矩形表示執行器。

3.2 STM32啟動過程

單片機上電后第一行執行的代碼是匯編文件startup_stm32f10x_md.s中的Reset_Handler標簽,然后執行SystemInit()后才執行main()。所以在執行我們的main()函數之前,單片機會執行SystemInit()函數將單片機時鐘配置為72MHz。
Reset_Handler

; Reset handler
Reset_Handler    PROCEXPORT  Reset_Handler             [WEAK]IMPORT  __mainIMPORT  SystemInitLDR     R0, =SystemInitBLX     R0LDR     R0, =__mainBX      R0ENDP

3.2 SystemInit()函數

在SystemInit()函數中會調用SetSysClock()—>>SetSysClockTo72(),SetSysClockTo72()執行完后STM32系統時鐘為72MHz,是8MHz外部高速晶振HSE通過PLL進行9倍頻后得到。

void SystemInit (void)
{/* Reset the RCC clock configuration to the default reset state(for debug purpose) *//* Set HSION bit */RCC->CR |= (uint32_t)0x00000001;/* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */
#ifndef STM32F10X_CLRCC->CFGR &= (uint32_t)0xF8FF0000;
#elseRCC->CFGR &= (uint32_t)0xF0FF0000;
#endif /* STM32F10X_CL */   /* Reset HSEON, CSSON and PLLON bits */RCC->CR &= (uint32_t)0xFEF6FFFF;/* Reset HSEBYP bit */RCC->CR &= (uint32_t)0xFFFBFFFF;/* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */RCC->CFGR &= (uint32_t)0xFF80FFFF;#ifdef STM32F10X_CL/* Reset PLL2ON and PLL3ON bits */RCC->CR &= (uint32_t)0xEBFFFFFF;/* Disable all interrupts and clear pending bits  */RCC->CIR = 0x00FF0000;/* Reset CFGR2 register */RCC->CFGR2 = 0x00000000;
#elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)/* Disable all interrupts and clear pending bits  */RCC->CIR = 0x009F0000;/* Reset CFGR2 register */RCC->CFGR2 = 0x00000000;      
#else/* Disable all interrupts and clear pending bits  */RCC->CIR = 0x009F0000;
#endif /* STM32F10X_CL */#if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (defined STM32F10X_HD_VL)#ifdef DATA_IN_ExtSRAMSystemInit_ExtMemCtl(); #endif /* DATA_IN_ExtSRAM */
#endif /* Configure the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers *//* Configure the Flash Latency cycles and enable prefetch buffer */SetSysClock();#ifdef VECT_TAB_SRAMSCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */
#elseSCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */
#endif 
}

3.2.1 SystemInit()第1句:

  /* Reset the RCC clock configuration to the default reset state(for debug purpose) *//* Set HSION bit */RCC->CR |= (uint32_t)0x00000001;

時鐘控制寄存器CR
這一行通過位或運算,將RCC->CR寄存器最低位置1,開啟HSI時鐘。這一句其實我感覺不要也是可以的,因為手冊中CR寄存器復位值是0x0000 xx83,即HSION默認值就是1。

3.2.2 SystemInit()第2句:

  /* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */
#ifndef STM32F10X_CLRCC->CFGR &= (uint32_t)0xF8FF0000;

時鐘配置寄存器CFGR

其中#ifndef STM32F10X_CL條件成立,因為在STM32F103C8T6標準庫中,并沒有定義這個宏,因此執行RCC->CFGR &= (uint32_t)0xF8FF0000;正如備注所示是復位SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits。對照時鐘復位寄存器CFGR中說明,0x00轉化二進制是0000 0000,即SW[1:0]被置為00,HPRE[3:0]被置為0000,PPRE1[2:0]被置為000,PPRE2[2:0]被置為000,ADCPRE[1:0]被置為00。0xF8轉為二進制是1111 1000,即MCO[2:0]被置為000。

3.2.3 SystemInit()第3句:

  /* Reset HSEON, CSSON and PLLON bits */RCC->CR &= (uint32_t)0xFEF6FFFF;/* Reset HSEBYP bit */RCC->CR &= (uint32_t)0xFFFBFFFF;/* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */RCC->CFGR &= (uint32_t)0xFF80FFFF;

這三句和備注一樣,對應查看CR寄存器和CFGR寄存器對應位說明,將右邊的16進制數轉化位二進制后對應查看。

3.3 SetSysClock()函數:

static void SetSysClock(void)
{
#ifdef SYSCLK_FREQ_HSESetSysClockToHSE();
#elif defined SYSCLK_FREQ_24MHzSetSysClockTo24();
#elif defined SYSCLK_FREQ_36MHzSetSysClockTo36();
#elif defined SYSCLK_FREQ_48MHzSetSysClockTo48();
#elif defined SYSCLK_FREQ_56MHzSetSysClockTo56();  
#elif defined SYSCLK_FREQ_72MHzSetSysClockTo72();
#endif/* If none of the define above is enabled, the HSI is used as System clocksource (default after reset) */ 
}

SYSCLK_FREQ_72MHz宏定義
在system_stm32F10x.c的115行定義了宏SYSCLK_FREQ_72MHz,所以會執行 SetSysClockTo72()。

3.4 SetSysClockTo72()函數:

static void SetSysClockTo72(void)
{__IO uint32_t StartUpCounter = 0, HSEStatus = 0;/* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/    /* Enable HSE */    RCC->CR |= ((uint32_t)RCC_CR_HSEON);/* Wait till HSE is ready and if Time out is reached exit */do{HSEStatus = RCC->CR & RCC_CR_HSERDY;StartUpCounter++;  } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));if ((RCC->CR & RCC_CR_HSERDY) != RESET){HSEStatus = (uint32_t)0x01;}else{HSEStatus = (uint32_t)0x00;}  if (HSEStatus == (uint32_t)0x01){/* Enable Prefetch Buffer */FLASH->ACR |= FLASH_ACR_PRFTBE;/* Flash 2 wait state */FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2;    /* HCLK = SYSCLK */RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;/* PCLK2 = HCLK */RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;/* PCLK1 = HCLK */RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;#ifdef STM32F10X_CL/* Configure PLLs ------------------------------------------------------*//* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz *//* PREDIV1 configuration: PREDIV1CLK = PLL2 / 5 = 8 MHz */RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL |RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC);RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 |RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV5);/* Enable PLL2 */RCC->CR |= RCC_CR_PLL2ON;/* Wait till PLL2 is ready */while((RCC->CR & RCC_CR_PLL2RDY) == 0){}/* PLL configuration: PLLCLK = PREDIV1 * 9 = 72 MHz */ RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL);RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 | RCC_CFGR_PLLMULL9); 
#else    /*  PLL configuration: PLLCLK = HSE * 9 = 72 MHz */RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE |RCC_CFGR_PLLMULL));RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9);
#endif /* STM32F10X_CL *//* Enable PLL */RCC->CR |= RCC_CR_PLLON;/* Wait till PLL is ready */while((RCC->CR & RCC_CR_PLLRDY) == 0){}/* Select PLL as system clock source */RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;    /* Wait till PLL is used as system clock source */while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08){}}else{ /* If HSE fails to start-up, the application will have wrong clock configuration. User can add here some code to deal with this error */}
}

在SetSysClockTo72()函數中,開啟了HSE,并配置了PLL進行9倍頻,然后將SYSCLK配置為72MHz。

3.4.1 SetSysClockTo72()第1句:

  /* Enable HSE */    RCC->CR |= ((uint32_t)RCC_CR_HSEON);

時鐘控制寄存器CR
時鐘控制寄存器CR的bit16是HSEON,將這一位置1,即可開啟外部高速時鐘HSE。通過按F12跳轉到定義發現,在stm32f10x.h中RCC_CR_HSEON定義如下,轉換成二進制后,剛好是bit16為1,通過位或運算”|=“將bit16置1,而其它位不變。

#define  RCC_CR_HSEON                        ((uint32_t)0x00010000)        /*!< External High Speed clock enable */

3.4.2 SetSysClockTo72()第2句:

  /* Wait till HSE is ready and if Time out is reached exit */do{HSEStatus = RCC->CR & RCC_CR_HSERDY;StartUpCounter++;  } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));if ((RCC->CR & RCC_CR_HSERDY) != RESET){HSEStatus = (uint32_t)0x01;}else{HSEStatus = (uint32_t)0x00;}

等待HSE穩定,并設置超時時間HSE_STARTUP_TIMEOUT,HSE穩定后將HSEStatus標志位置1,然后進行后續配置,如果失敗置為0,默認使用8MHz的HSI作為系統時鐘。

3.4.3 SetSysClockTo72()第3句:

  if (HSEStatus == (uint32_t)0x01){/* Enable Prefetch Buffer */FLASH->ACR |= FLASH_ACR_PRFTBE;/* Flash 2 wait state */FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2;    

這幾句是配置FLASH的等待周期的,詳情需要查看《STM32F10xxx閃存編程手冊》。

3.4.4 SetSysClockTo72()第4句:

    /* HCLK = SYSCLK */RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;/* PCLK2 = HCLK */RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;/* PCLK1 = HCLK */RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;

這三句配置三條總線HCLK、PCLK2和PCLK1的時鐘頻率。即將PCLK2=HCLK = SYSCLK,PCLK1=HCLK/2。此時SYSCLK還不是72MHz,因為還沒有配置PLL進行9倍頻。

3.4.5 SetSysClockTo72()第5句:

    /*  PLL configuration: PLLCLK = HSE * 9 = 72 MHz */RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE |RCC_CFGR_PLLMULL));RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9);

這兩句將PLL配置為對HSE進行9倍頻。此時PLL時鐘為72MHz。

3.4.6 SetSysClockTo72()第6句:

    /* Enable PLL */RCC->CR |= RCC_CR_PLLON;/* Wait till PLL is ready */while((RCC->CR & RCC_CR_PLLRDY) == 0){}/* Select PLL as system clock source */RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;    /* Wait till PLL is used as system clock source */while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08){}

這幾句是開啟PLL時鐘,并將其作為SYSCLK時鐘源,等待PLL時鐘穩定后,即可退出。此時SYSCLK為72MHz,PCLK2=HCLK = SYSCLK=72MHz,PCLK1=HCLK/2=36MHz。

3.4.7 SetSysClockTo72()第7句:

  else{ /* If HSE fails to start-up, the application will have wrong clock configuration. User can add here some code to deal with this error */}

此段代碼是 如果HSE初始化失敗,那么默認使用HSI作為SYSCLK時鐘,我們也可以在此處進行我們自己的處理,但是通常都不會進行處理。

四、標準庫與HAL庫區別

共同點:單片機上電后會立即執行啟動文件中的Reset_Handler標簽,然后調用SystemInit()函數。
不同點:SystemInit()函數實現不一樣,HAL庫中SystemInit()函數不會調用 SetSysClock()將系統時鐘初始化為72MHz,而是需要我們在main()函數中自己初始化為72Mhz。

4.1 HAL庫SystemInit()函數

void SystemInit (void)
{/* Reset the RCC clock configuration to the default reset state(for debug purpose) *//* Set HSION bit */RCC->CR |= (uint32_t)0x00000001;/* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */
#if !defined(STM32F105xC) && !defined(STM32F107xC)RCC->CFGR &= (uint32_t)0xF8FF0000;
#elseRCC->CFGR &= (uint32_t)0xF0FF0000;
#endif /* STM32F105xC */   /* Reset HSEON, CSSON and PLLON bits */RCC->CR &= (uint32_t)0xFEF6FFFF;/* Reset HSEBYP bit */RCC->CR &= (uint32_t)0xFFFBFFFF;/* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */RCC->CFGR &= (uint32_t)0xFF80FFFF;#if defined(STM32F105xC) || defined(STM32F107xC)/* Reset PLL2ON and PLL3ON bits */RCC->CR &= (uint32_t)0xEBFFFFFF;/* Disable all interrupts and clear pending bits  */RCC->CIR = 0x00FF0000;/* Reset CFGR2 register */RCC->CFGR2 = 0x00000000;
#elif defined(STM32F100xB) || defined(STM32F100xE)/* Disable all interrupts and clear pending bits  */RCC->CIR = 0x009F0000;/* Reset CFGR2 register */RCC->CFGR2 = 0x00000000;      
#else/* Disable all interrupts and clear pending bits  */RCC->CIR = 0x009F0000;
#endif /* STM32F105xC */#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)#ifdef DATA_IN_ExtSRAMSystemInit_ExtMemCtl(); #endif /* DATA_IN_ExtSRAM */
#endif #ifdef VECT_TAB_SRAMSCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */
#elseSCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */
#endif 
}

最后沒有調用 SetSysClock();也就不會調用 SetSysClockTo72();

4.1 HAL庫配置系統時鐘為72MHz函數

int main(void)
{HAL_Init();                    	 	//初始化HAL庫    Stm32_Clock_Init(RCC_PLL_MUL9);   	//設置時鐘,72Mwhile(1){}
}

需要我們編寫 Stm32_Clock_Init()函數。

4.1.1 Stm32_Clock_Init函數

4.1 HAL庫配置系統時鐘為72MHz函數

void Stm32_Clock_Init(u32 PLL)
{HAL_StatusTypeDef ret = HAL_OK;RCC_OscInitTypeDef RCC_OscInitStructure; RCC_ClkInitTypeDef RCC_ClkInitStructure;RCC_OscInitStructure.OscillatorType=RCC_OSCILLATORTYPE_HSE;    	//時鐘源為HSERCC_OscInitStructure.HSEState=RCC_HSE_ON;                      	//打開HSERCC_OscInitStructure.HSEPredivValue=RCC_HSE_PREDIV_DIV1;		//HSE預分頻RCC_OscInitStructure.PLL.PLLState=RCC_PLL_ON;					//打開PLLRCC_OscInitStructure.PLL.PLLSource=RCC_PLLSOURCE_HSE;			//PLL時鐘源選擇HSERCC_OscInitStructure.PLL.PLLMUL=PLL; 							//主PLL倍頻因子ret=HAL_RCC_OscConfig(&RCC_OscInitStructure);//初始化if(ret!=HAL_OK) while(1);//選中PLL作為系統時鐘源并且配置HCLK,PCLK1和PCLK2RCC_ClkInitStructure.ClockType=(RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2);RCC_ClkInitStructure.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK;		//設置系統時鐘時鐘源為PLLRCC_ClkInitStructure.AHBCLKDivider=RCC_SYSCLK_DIV1;				//AHB分頻系數為1RCC_ClkInitStructure.APB1CLKDivider=RCC_HCLK_DIV2; 				//APB1分頻系數為2RCC_ClkInitStructure.APB2CLKDivider=RCC_HCLK_DIV1; 				//APB2分頻系數為1ret=HAL_RCC_ClockConfig(&RCC_ClkInitStructure,FLASH_LATENCY_2);	//同時設置FLASH延時周期為2WS,也就是3個CPU周期。if(ret!=HAL_OK) while(1);
}

調用HAL庫HAL_RCC_ClockConfig()函數實現將SYSCLK配置為72MHz。

五、總結

通過標準庫和HAL庫對比,將STM32系統時鐘SYSCLK配置為72MHz既可以在main()函數之前,也可以在main()函數里面,即在使用其它片上外設之前都可以。雖然標準庫和HAL庫調用的庫函數不一樣,但是最底層都是配置的RCC的CR和CFGR寄存器,只是封裝不同而已,所以我們得熟悉手冊對RCC使用的說明,再結合標準庫和HAL庫進行學習,才能理解得更加透徹。

六、資料連接

https://gitee.com/muzi_wood/stm32-f103

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/81192.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/81192.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/81192.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

rk3576 gstreamer opencv

安裝gstreamer rk3588使用gstreamer推流_rk3588 gstreamer-CSDN博客 rk3588使用gstreamer推流_rk3588 gstreamer-CSDN博客 Installing on Linux sudo apt-get install libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libgstreamer-plugins-bad1.0-dev gstreamer1.0-pl…

Quic如何實現udp可靠傳輸

QUIC&#xff08;Quick UDP Internet Connections&#xff09;是由 Google 設計并被 IETF 標準化的傳輸層協議&#xff0c;它基于 UDP 實現&#xff0c;但提供了類似 TCP 的可靠性和更高級的功能&#xff08;如多路復用、0-RTT 握手、TLS 加密等&#xff09;。 盡管 UDP 是不可…

uniapp-商城-59-后臺 新增商品(屬性的選中,進行過濾展示,filter,some,every和map)

前面講了屬性的添加&#xff0c;添加完成后&#xff0c;數據庫中已經存在數據了&#xff0c;這時再繼續商品的添加時&#xff0c;就可以進行屬性的選擇了。 在商品添加過程中&#xff0c;屬性選擇是一個關鍵步驟。首先&#xff0c;界面需要展示嵌套的屬性數據&#xff0c;用戶通…

負載均衡 ELB 在 zkmall開源商城高流量場景下的算法優化

在電商大促、直播帶貨等高頻交易場景下&#xff0c;流量突發增長對系統穩定性提出嚴峻挑戰。ZKmll 開源商城通過對負載均衡 ELB&#xff08;Elastic Load Balancer&#xff09;算法的深度優化&#xff0c;結合業務場景特性設計動態加權輪詢 地域感知 熱點分流的混合策略&…

Linux干貨(三)

前言 從B站黑馬程序員Linux課程摘選的學習干貨&#xff0c;新手友好&#xff01;若有侵權&#xff0c;會第一時間處理。 目錄 前言 1.which find命令 1.which命令 2.find命令 2.grep wc 管道符 1.grep命令 2.wc命令 3.管道符 3.echo tail 重定向符 1.echo命令 2.反…

Sigmoid與Softmax:從二分類到多分類的深度解析

Sigmoid與Softmax:從二分類到多分類的深度解析 聯系 函數性質:二者都是非線性函數 ,也都是指數歸一化函數,可將輸入值映射為0到1之間的實數 ,都能把輸出轉化成概率分布的形式,在神經網絡中常作為激活函數使用。Softmax是Sigmoid的推廣:從功能角度看,Softmax函數可視為…

文件系統交互實現

關于之前的搭建看QT控件文件系統的實現-CSDN博客&#xff0c;接下來是對本程序的功能完善&#xff0c;我想著是這樣設計的&#xff0c;打開一個目錄以后&#xff0c;鼠標選中一個項可以是目錄&#xff0c;也可以是文件&#xff0c;右鍵可以出現一個菜單選擇操作&#xff0c;比如…

[ctfshow web入門] web75

信息收集 啟用了open_basedir&#xff0c;所以之前的方法又不能用了 解題 cforeach(new DirectoryIterator("glob:///*") as $a){echo($a->__toString(). ); } ob_flush();cif ( $a opendir("glob:///*") ) {while ( ($file readdir($a)) ! false …

Vulfocus靶場-文件上傳-3

WSO2 文件上傳 &#xff08;CVE-2022-29464&#xff09; WSO2是一家成立于 2005 年的開源技術提供商。它提供了一個企業平臺&#xff0c;用于在本地和整個 Internet 上 集成應用程序編程接口(API)、應用程序和 Web 服務。 某些 WSO2 產品允許無限制的文件上傳和遠程代碼執行。…

基于MCP的橋梁設計規范智能解析與校審系統構建實踐

引言 今天本文準備盤一個大活&#xff0c;聊一聊偏特定行業一點的AI技術深入應用思考及實踐。 一、傳統設計行業項目背景與行業痛點 在橋梁設計領域&#xff0c;標準規范是設計的基礎&#xff0c;直接關系到橋梁結構的安全性、耐久性和經濟性。然而&#xff0c;傳統的規范應…

遠程連接電腦的方法?異地遠程桌面連接和三方軟件實現

遠程連接電腦&#xff0c;是指通過網絡技術&#xff0c;在一臺設備上操控另一臺設備的電腦桌面&#xff0c;實現跨地域的操作和管理。在日常工作、技術支持、遠程辦公等場景中&#xff0c;遠程連接電腦都發揮著重要作用。實現遠程連接電腦主要有系統自帶工具和第三方軟件兩種方…

win11 安裝 wsl ubuntu 18.04后換源失敗!

記錄幾個問題是如何解決的。 一 下載wsl后&#xff0c;有報錯&#xff1a; Installing, this may take a few minutes... WslRegisterDistribution failed with error: 0x8007019e Error: 0x8007019e ??????? Linux ? Windows ???? Press any key to continue... …

PY32系列單片機離線燒錄器,可配置選項字節和上機臺批量燒錄

PY32離線燒錄器采用 MINI-USB 接口&#xff0c;提供穩定的物理連接。設備與電腦采用串口方式通訊&#xff0c;波特率固定為 1M。需配合我們的上位機使用。PY32離線燒錄器現支持芯片型號在PY32F002A/002B/002/003/030/071/072/040/403/303各封裝和XL32F001/003。燒錄器僅提供 3.…

深入理解 this 指向與作用域解析

引言 JavaScript 中的 this 關鍵字的靈活性既是強大特性也是常見困惑源。理解 this 的行為對于編寫可維護的代碼至關重要&#xff0c;但其動態特性也會讓我們感到困惑。 與大多數編程語言不同&#xff0c;JavaScript 的 this 不指向函數本身&#xff0c;也不指向函數的詞法作…

# IntelliJ IDEA企業版開發入門:包、類與項目結構詳解

--- ## 一、項目結構與包的概念 ### 1. 標準項目目錄解析 在IntelliJ IDEA中&#xff0c;一個Java項目通常包含以下核心目錄&#xff1a; - **src**&#xff1a;源代碼根目錄。 - **main**&#xff1a;主代碼目錄&#xff0c;存放業務邏輯代碼。 - **java**&#xff1a;Java…

NGINX 開源與社區動態:從基石到浪潮,持續演進的生態力量

NGINX 之所以能夠成為全球應用最為廣泛的 Web 服務器和反向代理軟件之一,其成功的核心驅動力無疑是開源。開放的源代碼、活躍的社區參與以及透明的開發過程,共同鑄就了 NGINX 的輝煌。然而,正如所有大型開源項目一樣,NGINX 的開源之路也并非一帆風順,其社區動態也時常涌現…

Electron(一)

前言&#xff1a; 參考尚硅谷視頻記錄&#xff1a;b站尚硅谷視頻-1小時上手electron 一、什么是electron? 是一款應用廣泛的、跨平臺的、桌面應用開發框架。 應用廣泛&#xff1a;很多桌面應用都是這個框架寫的&#xff0c;例如騰訊qq、百度云跨平臺&#xff1a;跨window、…

AI Agent開發第64課-DIFY和企業現有系統結合實現高可配置的智能零售AI Agent(上)

開篇 我們之前花了將近10個篇章講Dify的一些基礎應用,包括在講Dify之前我們講到了幾十個AI Agent的開發例子,我不知道大家發覺了沒有,在AI Agent開發過程中我們經常會伴隨著這樣的一些問題: 需要經常改貓娘;需要經常改調用LLM的參數,甚至在一個流程中有3個節點,每個節點…

ssti刷刷刷

[NewStarCTF 公開賽賽道]BabySSTI_One 測試發現過濾關鍵字&#xff0c;但是特殊符號中括號、雙引號、點都能用 可以考慮拼接或者編碼&#xff0c;這里使用拼接 ?name{{()["__cla"~"ss__"]}}?name{{()["__cla"~"ss__"]["__ba&…

google-Chrome常用插件

google-Chrome常用插件 1. json格式化展示插件 github下載jsonview-for-chrome插件 通過離線安裝方式 拓展程序-》管理拓展程序-》打開開發者模式-》加載已解壓的拓展程序-》選擇拓展程序解壓的位置 2. 翻譯插件 插件下載地址&#xff1a;Immersive Translate - Bilingual …