環境:STM32F207
內容:SystemInit到底做了啥
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT SystemInit
IMPORT __main
LDR R0, =SystemInit ;現在着重講這個地方
BLX R0
LDR R0, =__main
BX R0
ENDP
事先說明:我對整個流程並不是很清楚,所以我只會站在一個初學者的角度來寫這篇文章,老手們就請見諒
言歸正傳:
貼上函數說明,來自stm32固件庫:
/**
* @brief Setup the microcontroller system
* Initialize the Embedded Flash Interface, the PLL and update the
* SystemFrequency variable.
* @param None
* @retval None
*/
這段話的意思大概爲:初始化FLASH接口,鎖相環和更新系統時鐘
源代碼如下:
void SystemInit(void)
{
/* Reset the RCC clock configuration to the default reset state ------------*/
/* Set HSION bit */
RCC->CR |= (uint32_t)0x00000001;
/* Reset CFGR register */
RCC->CFGR = 0x00000000;
/* Reset HSEON, CSSON and PLLON bits */
RCC->CR &= (uint32_t)0xFEF6FFFF;
/* Reset PLLCFGR register */
RCC->PLLCFGR = 0x24003010;
/* Reset HSEBYP bit */
RCC->CR &= (uint32_t)0xFFFBFFFF;
/* Disable all interrupts */
RCC->CIR = 0x00000000;
#ifdef DATA_IN_ExtSRAM
SystemInit_ExtMemCtl();
#endif /* DATA_IN_ExtSRAM */
/* Configure the System clock source, PLL Multiplier and Divider factors,
AHB/APBx prescalers and Flash settings ----------------------------------*/
SetSysClock();
/* Configure the Vector Table location add offset address ------------------*/
#ifdef VECT_TAB_SRAM
SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
#else
SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
#endif
}
①:
/* Reset the RCC clock configuration to the default reset state ------------*/
/* Set HSION bit */
RCC->CR |= (uint32_t)0x00000001;
這裏是什麼意思?不懂我們就看看stm32f207上面是怎麼說CR寄存器的:
這句代碼對應的寄存器如上,他其實要做的事情就是一個,打開HSI(內部高速晶振).我們再大致看看HISION說明:大概意思就是我們不能夠將這一位清零,爲啥?
他說,當我們離開待機模式的時候硬件強制將HISION置1,或者當我們外部晶振起振失敗,我們也會直接或者間接使用到HSI。所以意思就是,我們只能開,不能關。
其實我們也可以反問自己一句,我們復位的時候還沒有啓動外部晶振同時也沒有手動將HISON打開,爲什麼我們CPU能夠跑,他是用的HSI 還是LSI?這個問題,我也不知道,
只能下來看看。能夠想到這點就可以了。
②
/* Reset CFGR register */
RCC->CFGR = 0x00000000;
這裏來了個新的寄存器CFGR,他說將CFGR復位,爲啥復位成0,不是FFF,不是DDDD,那也要看看datasheet裏面每一項怎麼寫的,再看手冊之前,先說一下
CFGR的作用就是如下圖:
是的,CFGR的作用就是配置SYSCLK的,其實我們現在不看手冊自己也會有幾個疑問,如果系統啓動,我們系統時鐘是多少?時鐘源是什麼?所以這裏就會有答案
我們上一張圖片說的大概意思就是CFGR作用是選擇系統時鐘源什麼的,現在這張圖片就是寫了CFGR有哪些位,我們肉眼看看也能夠知道SW代表switch,pre代表預分頻,所以我們知道
這裏肯定是做的是系統時鐘相關的時鐘源選擇切換和預分頻處理相關動作,那麼我們要好好看看一下sw0,sw1...,看了之後就知道爲什麼上電覆位成爲0了。
sw=0,表示系統時鐘使用的是HSI。sws=0,也是同樣意思,其實sws不能夠設置,只能夠查看。
下面我將列出其他位代表的意思:
HPRE:0000 代表不對系統時鐘進行分頻,時鐘樹裏面中間框框AHB PRESC
PPREX(1,2):0000 代表APB2,APB1時鐘來源都直接是AHB,並沒有經過AHB分頻,上面時鐘樹
RTCPRE:0000 不將HSE時鐘提供給RTC,因爲現在時鐘本來就不精確,所以上電就給RTC,沒有這個必要
I2SSC: 0000 選擇PLLI2S時鐘爲I2S的時鐘
好了,這句話,我們就引出了這麼多內容,先說明:我在寫文章的時候是邊寫邊查,所以希望初學者按照我的思路來走,不要覺得文章太長沒意思,有意思的文章不多,
也不是我能夠一時半會兒寫得出來的,所以請將就一下,至少對你會有很大幫助。
③
/* Reset HSEON, CSSON and PLLON bits */
RCC->CR &= (uint32_t)0xFEF6FFFF;
又來操作CR了,上面我們的CFGR主要做的是時鐘源的設置,這個CR主要做的事情就是打開某些東西,比如PLLCSS,HSE等,至於爲什麼要先設置CFGR再設置CR,
很明顯了,我們剛纔設置CFGR目的是讓系統先跑起來,使用HSI爲系統時鐘,跑起來之後再進行HSE,PLL等設置,這也合情合理。
我們知道&=的作用主要是清零,|=的作用主要是置一,那麼我們看看這裏CR想要將哪幾位清零呢,爲什麼清零
0XFEF6FFFF=
主要是講bit15之上的某些位給置零了。
其實這些值的大概意思就是上面備註寫的:reset HSEON CSSON PLLON具體這些做什麼用,除了CSSON以外,我覺得新手都應該看得懂。
CSSON,大概就是啓用安全時鐘系統,我理解爲當HSE運行穩定了,打開這個,它相當於是去檢測HSE是否正常工作。老手看到請指證
④
/* Reset PLLCFGR register */
RCC->PLLCFGR = 0x24003010;
上面有個CFGR事用來配置系統時鐘的,主要是系統時鐘預分頻器還有就是各種switch,那麼PLLCFGR是什麼意思就很好理解了,當然是
對鎖相環進行操作的寄存器。具體每個值是多少,以及這個寄存器的作用是什麼,我們後面來看,因爲在sysclock函數裏面要對每個值進行設置。所以這裏只需要知道,這裏是進行了PLLCFG的復位操作
⑤
/* Reset HSEBYP bit */
RCC->CR &= (uint32_t)0xFFFBFFFF;
這裏說說HSE bypass是什麼意思,bypass的意思就是直通,hse bypass就是說,信號源不是來自晶振了,而是另外的時鐘源,比如信號發生器等。這裏意思肯定是禁止bypass,如果我們打開,那麼我們晶振就可以
不用初始化了。
⑥
/* Disable all interrupts */
RCC->CIR = 0x00000000;
這裏說的是關閉中斷,其實這個要分開理解,我們一般理解的終端是在終端向量表裏面列出來的終端,比如定時器,外部中斷,但是這裏的中斷是什麼呢,主要是一些和時鐘相關的中斷。這裏注意一下就可以了,
後面我們會看到另外一個關中斷操作。
⑦
SetSysClock();
這個函數主要就是重新操作我們上面列出的一些寄存器,具體操作我們暫時和systemInit函數分開,我們下一節來講這個SetSysClock.
⑧
/* Configure the Vector Table location add offset address ------------------*/
#ifdef VECT_TAB_SRAM
SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
#else
SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
#endif
設置中斷向量表,這個地方我們會參考另外一個PDF文檔<Cortex M3權威指南.pdf>
OK,做一個總結,其實SystemInit()這個函數只有這麼幾句話,但是用了很大篇幅來寫,爲什麼,爲的就是了解STM32相關的寄存器,不是說我們以後每次
使用STM32都必須親自設置,而是我們要對此有個比較清晰的瞭解,技術,就要死磕到底。