野火STM32學習筆記(構(gòu)建庫函數(shù)模型第五節(jié)課)

解釋初始化函數(shù)是怎么運作的
? ? ? ? 第四節(jié)課我們已經(jīng)了解了如何通過固件庫編程的方式初始化一個GPIO口,配置其速度,工作模式等等,這一切都有一個“幕后黑手”就是那一個一百多行的GPIO_Init()函數(shù)。我們再來一睹一下芳容:

第一部分
我們從第一行開始看:

? ? ? ? 大括號內(nèi)第一二行都是存放這些變量的初始值,可以不用太在意。再看下面模式配置那邊,第一行注釋是把模式的低四位存入變量currentmode,這樣做的目的是取出這些值(與0x0F相與取值),再判斷它的bit4位是幾(如下圖),是0則是輸入,是1則是輸出,判斷方式也很簡單,即賦值給currentmode的值和0x10(二進制00010000)與運算,看看是不是0就知道是輸入還是輸出了。如果是輸出就要配置工作速度,可以看到if下面那個括號里就是配置工作速度的,把想要設(shè)置的代表速度的值,加到變量currentmode里面去。

第二部分
下面我們要判斷是低八位的io還是高八位的,這就需要我們通過結(jié)構(gòu)體GPIO_Pin確定

? ? ? ? ?可以看到第一行if里面,32位的結(jié)構(gòu)體成員GPIO_Pin(在結(jié)構(gòu)體GPIO_InitTypeDef里,用GPIO_InitStruct這個名字代表)和0x00FF(二進制數(shù)0000000011111111)與運算,看看是不是等于0。如果不等于0,就先把低八位寄存器備份到變量tmpreg中,再執(zhí)行for循環(huán)里面的內(nèi)容。
? ? ? ? for循環(huán)里,設(shè)置記錄GPIO_Pin口的位置的變量初值為0x00,設(shè)置循環(huán)8次,每循環(huán)一次+1。循環(huán)里面pos的值設(shè)置為1,并且左移pinpos位,每次的得到的值和結(jié)構(gòu)體成員GPIO_Pin做與運算,并且賦值給變量currentpin。如果currentpin和pos相等,則說明(GPIO_InitStruct->GPIO_Pin)&pos等于pos,即GPIO_InitStruct->GPIO_Pin是1,就是說這個GPIO口我們會取到。
? ? ? ? 這個時候if(currentpin==pos)這個條件成立,執(zhí)行if里面的內(nèi)容。第一行pos = pinpos << 2;注釋是?pinpos的值左移兩位(乘以4),因為寄存器中4個寄存器位配置一個引腳,它的作用具體來說是由于pinpos是從0開始,0對應著第一個寄存器位PX0,四個位對應一個IO口,例如PB1它是端口配置低寄存器CRL的第4567四個位控制的。如果我想通過pinpos控制他,就要把他左移兩位(1→100→乘4)來控制PB1口。簡單描述就是數(shù)值對應的口,是從0開始的,而寄存器必須從第一個bit開始就算他是PB0,因此每控制一個寄存器口就要pinpos左移四個bit,即乘4,即pinpos左移兩位。

? ? ? ?下面兩行是清零操作,和寄存器編程的折這部分作用相同。

? ? ? ? ?下面這一行是把將要配置的引腳位,引腳模式寫入變量currentmode里面去,再賦值給tmpreg里面,多次循環(huán)之后再判斷是上拉還是下拉輸入,就可以把currentmode的臨時變量存入CRL寄存器中了(見第一張圖的最后一行)。

寄存器初始化函數(shù)到此就結(jié)束了,謝謝大家。