首先了解一下是什么RCC(Reset Clock Control),復(fù)位和時鐘控制(RCC)
小容量產(chǎn)品是指閃存存儲器容量在16K至32K字節(jié)之間的STM32F101xx, STM32F102xx和STM32F103xx微控制器。
中容量產(chǎn)品是指閃存存儲器容量在64K至128K字節(jié)之間的STM32F101xx, STM32F102xx和STM32F103xx微控制器。
大容量產(chǎn)品是指閃存存儲器容量在256K至512K字節(jié)之間的STM32F101xx和STM32F103xx微控制器。
除非特別說明,本章節(jié)描述的模塊應(yīng)用于整個STM32F103xx微控制器系列,因為我們使用是STM32F103RCT6開發(fā)板是mini最小系統(tǒng)板。
本例程使用是(光明谷SUN_STM32mini開發(fā)板)
一、復(fù)位
STM32F10xxx支持三種復(fù)位形式,分別為系統(tǒng)復(fù)位、上電復(fù)位和備份區(qū)域復(fù)位。
1.1 系統(tǒng)復(fù)位
系統(tǒng)復(fù)位將復(fù)位除時鐘控制寄存器CSR中的復(fù)位標(biāo)志和備份區(qū)域中的寄存器以外的所有寄存器
當(dāng)以下事件中的一件發(fā)生時,產(chǎn)生一個系統(tǒng)復(fù)位:
1. NRST管腳上的低電平(外部復(fù)位)
2. 窗口看門狗計數(shù)終止(WWDG復(fù)位)
3. 獨立看門狗計數(shù)終止(IWDG復(fù)位)
4. 軟件復(fù)位(SW復(fù)位)
5. 低功耗管理復(fù)位
可通過查看RCC_CSR控制狀態(tài)寄存器中的復(fù)位狀態(tài)標(biāo)志位識別復(fù)位事件來源。
軟件復(fù)位
通過將Cortex?-M3中斷應(yīng)用和復(fù)位控制寄存器中的SYSRESETREQ位置’1’,可實現(xiàn)軟件復(fù)位。請參考Cortex?-M3技術(shù)參考手冊獲得進(jìn)一步信息。
低功耗管理復(fù)位
在以下兩種情況下可產(chǎn)生低功耗管理復(fù)位:
1. 在進(jìn)入待機(jī)模式時產(chǎn)生低功耗管理復(fù)位:
通過將用戶選擇字節(jié)中的nRST_STDBY位置’1’將使能該復(fù)位。這時,即使執(zhí)行了進(jìn)入待機(jī)模式的過程,系統(tǒng)將被復(fù)位而不是進(jìn)入待機(jī)模式。
2. 在進(jìn)入停止模式時產(chǎn)生低功耗管理復(fù)位:
通過將用戶選擇字節(jié)中的nRST_STOP位置’1’將使能該復(fù)位。這時,即使執(zhí)行了進(jìn)入停機(jī)模式的過程,系統(tǒng)將被復(fù)位而不是進(jìn)入停機(jī)模式。
關(guān)于用戶選擇字節(jié)的進(jìn)一步信息,請參考STM32F10xxx閃存編程手冊。
1.2 電源復(fù)位
當(dāng)以下事件中之一發(fā)生時,產(chǎn)生電源復(fù)位:
1. 上電/掉電復(fù)位(POR/PDR復(fù)位)
2. 從待機(jī)模式中返回
電源復(fù)位將復(fù)位除了備份區(qū)域外的所有寄存器。(見圖3)
圖中復(fù)位源將最終作用于RESET管腳,并在復(fù)位過程中保持低電平。復(fù)位入口矢量被固定在地
址0x0000_0004。更多細(xì)節(jié),參閱stm32f10xxx參考手冊表36。
1.3 備份域復(fù)位
當(dāng)以下事件中之一發(fā)生時,產(chǎn)生備份區(qū)域復(fù)位。
1. 軟件復(fù)位,備份區(qū)域復(fù)位可由設(shè)置備份區(qū)域控制寄存器RCC_BDCR中的BDRST位產(chǎn)生。
2. 在VDD和VBAT兩者掉電的前提下, VDD或VBAT上電將引發(fā)備份區(qū)域復(fù)位。
二、 時鐘
三種不同的時鐘源可被用來驅(qū)動系統(tǒng)時鐘(SYSCLK):
- HSI振蕩器時鐘
- HSE振蕩器時鐘
- PLL時鐘
這些設(shè)備有以下2種二級時鐘源:
- 40kHz低速內(nèi)部RC,可以用于驅(qū)動獨立看門狗和通過程序選擇驅(qū)動RTC。RTC用于從停機(jī)/待機(jī)模式下自動喚醒系統(tǒng)。
- 32.768kHz低速外部晶體也可用來通過程序選擇驅(qū)動RTC(RTCCLK)。
當(dāng)不被使用時,任一個時鐘源都可被獨立地啟動或關(guān)閉,由此優(yōu)化系統(tǒng)功耗。
復(fù)位和時鐘控制 STM32F10xxx參考手
1.3 備份域復(fù)位
當(dāng)以下事件中之一發(fā)生時,產(chǎn)生備份區(qū)域復(fù)位。
1. 軟件復(fù)位,備份區(qū)域復(fù)位可由設(shè)置備份區(qū)域控制寄存器RCC_BDCR中的BDRST位產(chǎn)生。
2. 在VDD和VBAT兩者掉電的前提下, VDD或VBAT上電將引發(fā)備份區(qū)域復(fù)位。
6.2 時鐘
三種不同的時鐘源可被用來驅(qū)動系統(tǒng)時鐘(SYSCLK):
- HSI振蕩器時鐘
- HSE振蕩器時鐘
- PLL時鐘
這些設(shè)備有以下2種二級時鐘源:
- 40kHz低速內(nèi)部RC,可以用于驅(qū)動獨立看門狗和通過程序選擇驅(qū)動RTC。RTC用于從停機(jī)/待機(jī)模式下自動喚醒系統(tǒng)。
- 32.768kHz低速外部晶體也可用來通過程序選擇驅(qū)動RTC(RTCCLK)。
當(dāng)不被使用時,任一個時鐘源都可被獨立地啟動或關(guān)閉,由此優(yōu)化系統(tǒng)功耗。
更多細(xì)節(jié),參閱 STM32F10xxx參考手冊
RCC設(shè)置流程:
1、將RCC寄存器重新設(shè)置為默認(rèn)值 RCC_DeInit
2、打開外部高速時鐘晶振HSE RCC_HSEConfig(RCC_HSE_ON)
3、等待外部高速時鐘晶振工作 HSEStartUpStatus = RCC_WaitForHSEStartUp();
4、設(shè)置AHB時鐘 RCC_HCLKConfig
5、設(shè)置高速APB時鐘 RCC_PCLK2Config
6、設(shè)置低速APB時鐘 RCC_PCLK1Config
7、設(shè)置PLL RCC_PLLConfig
8、打開PLL RCC_PLLCmd(ENABLE)
9、等待PLL工作 while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)==RESET)
10、設(shè)置系統(tǒng)時鐘 RCC_SYSCLOCKConfig
11、判斷是否PLL是系統(tǒng)時鐘 while(RCC_GetSYSCLKSource()!=0x08)
12、打開要使用的外設(shè)時鐘 RCC_APB2PerphClockCmd()/RCC_APB1PeriphClockCmd()
了解基礎(chǔ)知識下面實操吧
以前我們其實也有配置,但不具體,基本都本MCU默認(rèn)的配置,真正用好STM32,還得熟悉RCC.
復(fù)制上節(jié)工程文件夾打開(這個方法比較方便)
- 編輯main.c, 在上節(jié)基礎(chǔ)上增加RCC配置函數(shù)。
/**********************************************************************************
* Sun STM32 mini Demo
* Description
RCC Config Demo
* Version Date Auther Reversed History
----------------------------------------------------------------------------
V1.0.0 2021-11-07 Lojam Fan Fisrt Created
* (C) Sunshine Silicon Corporation
* Website: http://www.sunsili.com http://sunsili.taobao.com http://bbs.sunsili.com
* E-Mail : fan@sunsili.com
**********************************************************************************/
#include "stm32f10x.h"
#include "usart.h"
#include "SysTick.h"
#include "led.h"
#include "key.h"
#include <stdio.h>
extern vu8 Usart1_R_Buff[USART1_REC_MAXLEN]; //串口1數(shù)據(jù)接收緩沖區(qū)
extern vu8 Usart1_R_State; //串口1接收狀態(tài)
extern vu16 Usart1_R_Count; //當(dāng)前接收數(shù)據(jù)的字節(jié)數(shù)
void RCC_Configuration(void);
/*******************************************************************************
* 函數(shù)名 : main
* 描述 : 主函數(shù),用戶程序從main函數(shù)開始運行
* 輸入 : 無
* 輸出 : 無
* 返回值 : int:返回值為一個16位整形數(shù)
* 說明 : 無
*******************************************************************************/
int main(void){
u8 keyVal;
RCC_Configuration();
SysTick_Init_Config();
USART1_Init_Config(115200);//USART1初始化配置
LED_GPIO_Config();
Key_GPIO_Config();
printf ("*===================================================*n");
printf ("* * Name: Sun STM32 mini Demo Code. *************n");
printf ("* * (C) Sunshine Silicon Corporation *************n");
printf ("* * Website: http://www.sunsili.com *************n");
printf ("* * E-Mail : fan@sunsili.com *************n");
printf ("*===================================================*n");
printf ("* Sun STM32 mini Key Demo code .*n");
while (1)
{
keyVal = Key_Down_Scan();
if(Usart1_R_State == 1)//一幀數(shù)據(jù)接收完成
{
USART1_SendData((u8 *)Usart1_R_Buff, Usart1_R_Count); //USART1發(fā)送數(shù)據(jù)緩沖區(qū)數(shù)據(jù)(發(fā)送剛接收完成的一幀數(shù)據(jù))
Usart1_R_State =0;
Usart1_R_Count =0;
}
if(keyVal)
{
printf("KeyVal:%dr", keyVal);
if(keyVal & 0x01) LED3_ON();
else if(keyVal & 0x02) LED4_ON();
}
else LED_ALL_OFF();
}
}
/*******************************************************************************
* 函數(shù)名 : RCC_Configuration
* 描述 : 設(shè)置系統(tǒng)時鐘為72MHZ(這個可以根據(jù)需要改)
* 輸入 : 無
* 輸出 : 無
* 返回值 : 無
* 說明 : STM32F107x和STM32F105x系列MCU與STM32F103x系列MCU時鐘配置有所不同
*******************************************************************************/
void RCC_Configuration(void){
ErrorStatus HSEStartUpStatus; //外部高速時鐘(HSE)的工作狀態(tài)變量
RCC_DeInit(); //將所有與時鐘相關(guān)的寄存器設(shè)置為默認(rèn)值
RCC_HSEConfig(RCC_HSE_ON); //啟動外部高速時鐘HSE
HSEStartUpStatus = RCC_WaitForHSEStartUp(); //等待外部高速時鐘(HSE)穩(wěn)定
if(SUCCESS == HSEStartUpStatus) //如果外部高速時鐘已經(jīng)穩(wěn)定
{
/* Enable Prefetch Buffer */
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); //Flash設(shè)置
/* Flash 2 wait state */
FLASH_SetLatency(FLASH_Latency_2);
RCC_HCLKConfig(RCC_SYSCLK_Div1); //設(shè)置AHB時鐘等于系統(tǒng)時鐘(1分頻)/72MHZ
RCC_PCLK2Config(RCC_HCLK_Div1); //設(shè)置APB2時鐘和HCLK時鐘相等/72MHz(最大為72MHz)
RCC_PCLK1Config(RCC_HCLK_Div2); //設(shè)置APB1時鐘是HCLK時鐘的2分頻/36MHz(最大為36MHz)
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); //PLLCLK = 8MHz * 9 = 72 MHz
RCC_PLLCmd(ENABLE); //使能PLL
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET); //等待PLL穩(wěn)定
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); //設(shè)置系統(tǒng)時鐘的時鐘源為PLL
while(RCC_GetSYSCLKSource() != 0x08); //檢查系統(tǒng)的時鐘源是否是PLL
RCC_ClockSecuritySystemCmd(ENABLE); //使能系統(tǒng)安全時鐘
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE | RCC_APB2Periph_AFIO,ENABLE);
}
}
/******************* (C) COPYRIGHT SUNSHINE SILICON **************************
******************** END OF FILE main.c *******************/
- 編譯調(diào)試
保存直接編譯,發(fā)現(xiàn)編譯出錯,提示FLASH_PrefetchBufferCmd 和 FLASH_SetLatency函數(shù)未定義。解決方法添加庫文件stm32f10x_flash.c
重新編譯,通過。
調(diào)試
方法不再重復(fù),經(jīng)過前兩節(jié)練習(xí),大家應(yīng)該是會了.
效果與前一節(jié)是一樣,只是我們多了RCC配置?,F(xiàn)在效果一樣,但是真正項目里RCC是配置不一樣,是致命的。