天天看點

STM32F030 Nucleo-讓MCU全速點燈,其中隐藏的含義(一)

作者:嵌入式小美老師

隻要是有點基礎的騷友,點個燈就是個小KS!但是,我卻發現一些存在某種問題或陰謀!!!先看程式:

從牛卡闆卡的硬體原理圖得知LD1為ST-Link的RGB訓示燈,LD3為牛客闆卡的電源訓示燈,那麼隻剩下LD2了,LD2為有主要MCU(STM32F030)控制的LED燈,

如下圖:

STM32F030 Nucleo-讓MCU全速點燈,其中隐藏的含義(一)

I/O:LD2--------GPIOA5

條件:SB21、SB42焊接或短路

點亮LD2條件:GPIOA5輸出高電平

以上是從原理圖中得到的資訊,在檢查牛卡闆卡!OK!SB21、SB42已經用0歐電阻連接配接了!那麼硬體電路沒問題了!(其實闆卡一上電,預設的程式就使LD2閃爍了,我在這裡主要隻是表現一下分析思路。

那麼我的程式如下:

STM32F030 Nucleo-讓MCU全速點燈,其中隐藏的含義(一)

Main.c

STM32F030 Nucleo-讓MCU全速點燈,其中隐藏的含義(一)

程式寫好後!嗨!跑的蠻快啊!牛客闆卡中STM32F030沒有焊接8M(4~36M)晶振,隻有一個很黑一坨的32.768KHz大小的晶振作為RTC的振蕩源。而且我故意延時了那麼久!它居然跑的很快!!!

唉!不管了,先驗證一下看會不會跑的更快!

然後我就再寫了一個函數:

如下:

STM32F030 Nucleo-讓MCU全速點燈,其中隐藏的含義(一)

上圖的函數中,我使用了STM32的内部RC振蕩器作為系統鎖相環PLL的時鐘源,配置思路如下:

(1)開啟内部RC振蕩器HSI,作為時鐘源

(2)打開Flash的存取BUFF

(3)配置HCLK為四天時鐘SYSCLK的1分頻

(4)配置PCLK為HCLK的1分頻

(5)HSI的2分頻作為鎖相環(PLL)的時鐘源,并倍頻為12,即設定鎖相環的時鐘為48MHz,并使能鎖相環,等待鎖相環啟動成功

(6)設定鎖相環時鐘為系統時鐘

(7)等待時鐘啟動成功

從以上的設定來看,AHB和APB總線的時鐘都為48M,依據是:在DataSheet中表21說明AHB、APB、HCLK、PCLK可以大能達到48MHz。如下圖:

STM32F030 Nucleo-讓MCU全速點燈,其中隐藏的含義(一)

是以肯定要跑的快!哈哈!

那麼時鐘設定的思路源于什麼呢???

三個字“時鐘樹”即“Clock Tree”.見下圖:

STM32F030 Nucleo-讓MCU全速點燈,其中隐藏的含義(一)

以上程式的思路就源于此圖的綠色線條了!哈哈!而且在時鐘樹中明明白白的标出了,當使用HSI作為PLL的時鐘源時,必須2分頻,是以就有:(8M/2) * 12 = 40MHz了。當然!其實STM32預設是走藍色線的,也就是當沒有任何設定是,系統預設時鐘為8MHz,其他的就看分頻了。

那麼其實還需要注意一點:在看時鐘樹的時候,寫程式的時候要注意看看圖或者表在上面和下面的說明,别傻乎乎的就直接操作了,萬一碰到人家逆鱗了,人家就不給你工作了。上面的要找對自己的MCU(因為手冊都是以系列劃分的,差別是封裝、資源和記憶體(Flash和RAM)大小不同)。

STM32F030 Nucleo-讓MCU全速點燈,其中隐藏的含義(一)

對的!這個圖就是我們的STM32F030R8T6的時鐘樹下面的說明了。意思是,對于LSI/LSE不适用與STM32F030x8這個系列的MCU,是以當我們使用到STM32F030x8 MCU的時候,就别亂玩LSI和LSE這東西。比如牛客闆上的STM32F030R8T6就不行。

OK!程式寫好了!那麼調用驗證一下呗!看看是不是跑的更快了!

速度一樣的!沒變!啥情況呢????

其實!原因是這樣的!在程式進入Main開始執行之前,就已經配置過時鐘了!并且配置的效果和我上面那個函數:void RCC_Configuration(void)的效果是一樣的。

也就是說,就算我們不自己配置系統時鐘,ST也預設幫我們配置好了!使用HSI作為振蕩源,PLL作為系統時鐘源,是以跑起來SYSCLK也是48MHz,是以跑的速度也就一樣快了啊!

在這裡廢話幾句:上面/下面所說的跑的快,其實就是MCU的運作速度,執行指令的速度,那麼在我上面的程式的效果就是,LD2閃爍的速度!那麼怎麼驗證我上面的正确性呢??其實很簡單!調用如下:

STM32F030 Nucleo-讓MCU全速點燈,其中隐藏的含義(一)

進入main函數之後,第一件事就是把系統時鐘恢複預設值,在燒錄程式,再看效果!就能很明顯的看到,這LD2閃爍的是有多慢了!

RCC_DeInit();是外設标準庫提供的函數,當然,想操作寄存器就自己寫吧!哈哈!具體的位置就是stm32f0xx_rcc.h,stm32f0xx_rcc.c檔案中。所有關于RCC的内容都在這兩個檔案中找到,(其實ST提供了庫函數手冊,這個更友善了)。

那麼問題就止于此了嗎????不是的!這隻是問題的開始!哈哈哈!否則點個燈我就沒必要廢話那麼多了!

我們要分析一下,到底在進入Main之前都幹了啥???為什麼把時鐘都設定了。

或許有些童鞋就說了,上課時/在很多C語言書上不是說C語言是從main函數開始執行的麼??我簡單的回答一下這個問題:首先,我們初學時的C語言是标準的ANSI C語言,它運作的平台通常是在作業系統之上,那麼也就是所,我們使用者編寫的使用者程式肯定是從main開始了啊,因為在main之前的東西普通程式員是看不到的啊,比如PC機的BIOS和Windows核心我們也看不到也沒必要看,也不用關心,是以使用者程式肯定是從main開始執行的。但是作為嵌入式驅動開發工程師,那麼main之前的是就需要連接配接、了解了,否則寫毛驅動啊!在main之前通常都是一下彙編代碼或者内嵌彙編代碼。一個硬體的啟動應該是這樣的:

(1)異常向量表/中斷向量表的建立

(2)必要的硬體、寄存器、記憶體等初始化,這部分通常是有彙編代碼實作

(3)堆棧的初始化

(4)進入使用者程式前的初始化

真實的CPU啟動要複雜很多,但是也就大概是這麼個意思,以上隻是我個人對MCU啟動的了解。

嵌入式物聯網需要學的東西真的非常多,千萬不要學錯了路線和内容,導緻工資要不上去!

分享大家一個資料包,差不多150多G。裡面學習内容、面經、項目都比較新也比較全!

掃碼進群領資料

STM32F030 Nucleo-讓MCU全速點燈,其中隐藏的含義(一)