- 實(shí)驗(yàn)?zāi)康?/font> .2
- 實(shí)驗(yàn)板原理圖.2
- GPIO寄存器…2
- GPIO控制函數(shù)…3
- 時(shí)鐘使能函數(shù)…9
- 流水燈實(shí)現(xiàn)程序…10
- 本人做實(shí)驗(yàn)的嘗試、問(wèn)題與思考….11
- 使用HAL庫(kù)編寫(xiě)的流水燈(STM32cubeMX配合KEIL編程)……12
- 實(shí)驗(yàn)?zāi)康?/font>
通過(guò)對(duì)GPIO口的設(shè)置使LED燈亮滅,初步認(rèn)識(shí)GPIO(通用輸入輸出寄存器)的性質(zhì)和相關(guān)控制函數(shù)。對(duì)時(shí)鐘使能有一定概念。 1. 可以看到,板上放置在一起的共有五個(gè)LED燈,可以看到,燈五右接電阻、電源左接地,并不受引腳控制,即開(kāi)啟開(kāi)發(fā)板電源即自動(dòng)點(diǎn)亮。 2. 燈1、2、3、4分與STM32引出的PD9、10、11、12相連。待會(huì)兒我們即控制該四個(gè)引腳輸出高低電平達(dá)到控制燈亮滅的目的。 - STM32F407系列有GPIOA-GPIOK共11個(gè)GPIO接口,每個(gè)接口又引出0-15共十六個(gè)引腳,引腳即可以單一外接某一器件,也可以多接(這時(shí)選擇讀入輸出信號(hào)的對(duì)象要使用復(fù)用功能選擇,本點(diǎn)燈過(guò)程不接觸)。
- 以下是我們要設(shè)置到的GPIO寄存器,關(guān)于GPIO所有寄存器的信息可以在官方提供的《STM32F4XX參考手冊(cè)》中找到。
- GPIO端口模式寄存器(Mode Register)可控制各引腳使輸入、輸出、復(fù)用功能還是模擬模式,我們控制LED燈要使引腳處于輸出模式。
- 端口輸出類型寄存器(Output Type Register)可選擇開(kāi)漏或推挽模式。在推挽模式下,輸出的高低電平與STM32對(duì)引腳的設(shè)置一致(與輸出數(shù)據(jù)寄存器中設(shè)置的狀態(tài)一致);而在開(kāi)漏模式下,高電平輸出為高阻態(tài)(可理解為非高或低電平或高低電平不確定不予響應(yīng))。們控制LED燈要使引腳處于推挽模式。
- 上下拉寄存器(PullUpPullDown Register),上拉時(shí)引腳高電平,下拉時(shí)引腳低電平,既不上拉也不下拉時(shí)為介于高低電平中的不定電壓值。
- 輸出速度寄存器(Output Speed Register),設(shè)置其輸出頻率。
- 輸入數(shù)據(jù)寄存器和輸出數(shù)據(jù)寄存器即設(shè)置為輸入模式時(shí)數(shù)據(jù)的存入處和設(shè)置為輸出模式時(shí)外部對(duì)數(shù)據(jù)進(jìn)行讀入處。這兩個(gè)寄存器如圖都是低十六位有效的(高十六位保留),一一對(duì)應(yīng)每個(gè)GPIO的十六個(gè)引腳。
- 置位復(fù)位寄存器:我們修改輸出數(shù)據(jù)寄存器時(shí)不直接對(duì)其操作,而是通過(guò)置位復(fù)位寄存器對(duì)它進(jìn)行設(shè)置。
該寄存器低十六位相應(yīng)位置1使輸出數(shù)據(jù)寄存器對(duì)應(yīng)位為1,高十六位相應(yīng)位置1使對(duì)應(yīng)位為0。這高低十六位置0對(duì)輸出數(shù)據(jù)寄存器則無(wú)作用。 - 在哪兒查看這些函數(shù)的相關(guān)信息?控制函數(shù)定義在哪兒?
- STM官方提供了詳細(xì)介紹所有標(biāo)準(zhǔn)庫(kù)函數(shù)的文檔(稱為固件庫(kù)),這個(gè)文檔是相關(guān)程序自動(dòng)生成的(生成原理不必了解),里面詳細(xì)的提及了函數(shù)的定義、功能、對(duì)應(yīng)參數(shù)的可選范圍、宏定義以及他們的源代碼都在哪些文件中。
- STM32F407的固件庫(kù)名為
《STM32F40x/41x/427/437/429/439/401/410/411xE/412xG/413xx/423xx/446/469/479 DSP and Standard Peripherals Library》 - 本次要使用的GPIO控制函數(shù)在文檔中的路徑為
Moudles->STM32F4xx_StdPeriph_Driver->GPIO->Functions 要使用的函數(shù)如下 可以看到函數(shù)被定義在stm32f4xx_gpio.c文件中。結(jié)構(gòu)體類型和相應(yīng)的宏分別被定義在stm32f4xx_gpio.h和stm32f4xx.h頭文件中。 重點(diǎn)在看看GPIO_Init函數(shù)中的一個(gè)參數(shù)GPIO_InitTypeDef的結(jié)構(gòu)體類型。包含了,GPIO_Mode、GPIO_Otype、GPIO_Pin、GPIO_PuPd、GPIO_Speed五個(gè)成員,對(duì)這五個(gè)成員可賦的實(shí)參已經(jīng)在途中列出,例如GPIO_Pin的十五個(gè)引腳的宏定義。
- 看過(guò)上面的函數(shù)定義和結(jié)構(gòu)體定義后,這三個(gè)函數(shù)的參數(shù)一目了然如上一般。
功能分別是對(duì)輸出數(shù)據(jù)寄存器相應(yīng)位置零、置一和反轉(zhuǎn)。即在初始化GPIO口后,用這三個(gè)函數(shù)控制燈的亮滅。
以上的函數(shù)使完全能夠控制燈了,但實(shí)際控制燈之前還有一件事要做,就是使能時(shí)鐘。CPU是有工作時(shí)序的,可以理解為每一個(gè)操作都是單位時(shí)間的整數(shù)倍,設(shè)置好這個(gè)單位時(shí)間(對(duì)內(nèi)的CPU工作,對(duì)外每類接口、外設(shè)的 這個(gè)單位時(shí)間未必相同),即時(shí)鐘頻率的倒數(shù),放能工作。 但目前我們還未正式學(xué)到時(shí)鐘的配置,所以只需要使能對(duì)應(yīng)外設(shè)口的時(shí)鐘,頻率由STM32自動(dòng)設(shè)置。 現(xiàn)在來(lái)看一下這個(gè)時(shí)鐘使能函數(shù)- 我們開(kāi)啟GPIOD對(duì)應(yīng)的時(shí)鐘,另一個(gè)參數(shù)為ENABLE。
- 現(xiàn)在我們做好了所有的準(zhǔn)備工作,可以來(lái)跑流水燈了。
(函數(shù)部分由兩個(gè)右括號(hào)沒(méi)有截圖下來(lái),但不影響閱讀)
- 由于子函數(shù)只有兩個(gè),所以就直接定義在main函數(shù)之上了。
- 子函數(shù)一個(gè)用于延時(shí),一個(gè)用于點(diǎn)亮對(duì)應(yīng)燈,延時(shí)等待亮一會(huì)兒,然后關(guān)閉。
- 主函數(shù)無(wú)非分為三個(gè)步驟,使能時(shí)鐘、初始化需要用到的與燈相連的GPIO引腳和做完這些準(zhǔn)備工作后正式開(kāi)始控制燈的亮滅。
- 本人做實(shí)驗(yàn)的嘗試、問(wèn)題與思考
- 在我第一次點(diǎn)燈的時(shí)候,突發(fā)奇想能否使用c語(yǔ)言中所學(xué)的隨機(jī)函數(shù)并聯(lián)合數(shù)組
設(shè)置電燈序列。由隨機(jī)函數(shù)設(shè)置一連串燈的亮滅控制。可控制的參數(shù)分別由選擇的燈、燈是亮是滅、燈的顏色(當(dāng)時(shí)使用的是F429的板子外接的燈是彩燈)。 那么這樣,在每次RESET板子重啟程序的時(shí)候,燈光的閃爍將是隨機(jī)的,將構(gòu)成一 支“燈光舞蹈”,那可能很有趣。 - 我滿懷興趣的去做了,但最終沒(méi)有成功。根本原因是C語(yǔ)言中隨機(jī)數(shù)本質(zhì)上是偽隨機(jī)數(shù),采用的是UNIX時(shí)鐘戳作為隨機(jī)種子生成隨機(jī)數(shù),每個(gè)種子多次生成的結(jié)果是一樣的,但由于時(shí)鐘戳讀取的當(dāng)前時(shí)間(從1970年1月1日起的每一秒都是一個(gè)的時(shí)鐘戳,本質(zhì)上是一個(gè)浮點(diǎn)數(shù))每秒都不一樣,所以也算是隨機(jī)數(shù)了。但STM32的標(biāo)準(zhǔn)庫(kù)中并不包括時(shí)間戳讀取函數(shù),所以必然無(wú)法這樣做了。
-
- 那么為什么會(huì)不包含這個(gè)函數(shù)呢?
其實(shí)這個(gè)問(wèn)題很無(wú)聊,沒(méi)有就是沒(méi)有嘛,用不到所以沒(méi)有。這個(gè)解釋實(shí)際上,真的沒(méi)毛病,相關(guān)的需要用到時(shí)間的操作通過(guò)系統(tǒng)時(shí)鐘的控制和定時(shí)器可以完成,這個(gè)似乎并沒(méi)有什么用處。另外我的一個(gè)看法是,本身芯片就只有1M甚至512KB的RAM,無(wú)用的函數(shù)越多,燒錄進(jìn)去時(shí)可用的空間越少。限于外部原因嵌入式編程代碼精簡(jiǎn)是應(yīng)該的。 - 后來(lái)我退而求其次,選擇宏定義一個(gè)時(shí)間種子,手動(dòng)修改,那么每個(gè)修改的數(shù)在程序中處理后也是一支不同的舞蹈了嘛。
- 你是否也有其他關(guān)于控制燈的想法呢?
如果用STM32cube來(lái)寫(xiě)就會(huì)稍微簡(jiǎn)單一些,而且在用標(biāo)準(zhǔn)庫(kù)寫(xiě)例程時(shí),我們僅僅使能了時(shí)鐘函數(shù),并沒(méi)有配置相關(guān)的分、倍頻等系數(shù),在STM32cubeMX中,我們簡(jiǎn)單的來(lái)配置一下。
- 打開(kāi)STM32CubeMX,創(chuàng)建一個(gè)新項(xiàng)目。
- 在搜索欄中找到我們的芯片STM32F407ZE系列,雙擊進(jìn)入配置
- 在芯片圖的右下角找到我們的PD9,PD10,PD11,PD12四個(gè)引腳,右鍵設(shè)置為輸出模式。
- 在左邊欄中找RCC設(shè)置,設(shè)置HSE為第三個(gè)選項(xiàng),如圖4
- 進(jìn)入
Clock Configuration,將時(shí)鐘相關(guān)選擇和系數(shù)因子設(shè)置如幾個(gè)圈中,大致介紹在圖中文字可見(jiàn)。 具體介紹要到后面學(xué)習(xí)RCC時(shí)鐘控制器方具體學(xué)習(xí)。- 進(jìn)入Configuration選項(xiàng)的GPIO選項(xiàng)。設(shè)置PD9,10,11,12的狀態(tài)都為低電平,推挽,上拉,低速模式,則程序燒入后立即全部燈都亮起來(lái)。
- 如圖所示創(chuàng)建工程,最后點(diǎn)擊Open Project打開(kāi)創(chuàng)建的工程,則軟件會(huì)自動(dòng)用KEIL打開(kāi)這個(gè)工程。
- 上面的main.c的程序是自動(dòng)生成的同時(shí)并不是全部,我只截取了部分,可以看的出來(lái),其中自動(dòng)生成的注釋非常的多。內(nèi)容也比較多,主要關(guān)注下左邊紅點(diǎn)標(biāo)注了的語(yǔ)句。
主函數(shù)里就三個(gè)部分,第一部分是根據(jù)我們?cè)赟TM32CubeMx中配置的時(shí)鐘關(guān)系來(lái)設(shè)置時(shí)鐘的SystemClock_Config();函數(shù)的使用。第二部分是根據(jù)我們?cè)谠O(shè)置的引腳狀態(tài)來(lái)配置引腳的MX_GPIO_Init()的使用。第三個(gè)是一個(gè)while(1)的空循環(huán)。 這三條語(yǔ)句執(zhí)行后的結(jié)果就是所有燈亮然后保持著直到RESET(滅了然后重啟程序)或關(guān)閉電源。- 我們?cè)賮?lái)看看定義在stm32f4xx_hal_gpio.c中的函數(shù)HAL_GPIO_WritePin()和HAL_GPIO_TogglePin()。前者你去生成該工程后,可以在MX_GPIO_Init()函數(shù)中發(fā)現(xiàn)它被調(diào)用。這兩個(gè)函數(shù)是不是很眼熟,其功能與標(biāo)準(zhǔn)庫(kù)中的GPIO_SetBits()和GPIO_ToggleBits()相同,只不過(guò)HAL庫(kù)中生成的函數(shù)的取名帶有
明顯的HAL庫(kù)的特征(如MX_GPIO_Init和HAL_GPIO_WritePin); - 在用STM32CubeMX生成工程后,這些個(gè)相關(guān)的頭文件,c文件都被自動(dòng)添加到了工程中,而要被用到函數(shù),宏定義的都在這些個(gè)文件里。本人暫時(shí)沒(méi)有找到類似標(biāo)準(zhǔn)庫(kù)的固件庫(kù)的HAL固件庫(kù)文檔,所以暫時(shí)采用找相關(guān)文件直接看里面的宏定義、函數(shù)代碼的方式來(lái)了解程序。
流水燈需要添加的內(nèi)容有:
1.找到HAL庫(kù)下用來(lái)置位復(fù)位的函數(shù),上圖的HAL_GPIO_WritePin和HAL_GPIO_TogglePin就剛剛好夠用。 - 做一個(gè)延時(shí)函數(shù)用于使燈亮一會(huì)兒后再滅之。(為了看的方便直接加在主函數(shù)下面且不截圖上面的聲明。)
完整的Word格式文檔51黑下載地址:
http://www.zg4o1577.cn/bbs/dpj-152520-1.html
|