1. 程式人生 > >大白帶你重玩STM32系列(三)------STM32的通用GPIO口(暫存器法操作)

大白帶你重玩STM32系列(三)------STM32的通用GPIO口(暫存器法操作)

轉載自——

在上一講中,我們學習了MDK的安裝以及破解。這一講中,我們就開始認認真真的談一談,STM32可愛的GPIO口。

本文中,通過對點亮一個LED燈的操作,我們來講解一下,如何操作GPIO口。就像學各類軟體程式設計的同學們言必談HelloWorld一樣,學微控制器的最基本操作就是點燈了。這也是操作一款微控制器最最基礎的任務。而由於STM32的強大的功能,和晶片複雜的內部結構。對它的GPIO口的操作,相對於51微控制器的IO口來說,使用起來要稍微繁瑣了那麼一點。

本節當中,通過操作暫存器的方式,來操作STM32的GPIO口。從而實現點亮LED燈的操作。在下一講當中,再介紹如何使用庫函式來操作GPIO口。

既然是暫存器法點亮LED燈,那麼就不得不說到,和點亮LED燈相關的暫存器了。在這之前,我們先上開發板的電路原理圖。

由電路原理圖我們可以看出,開發板上使用的是一個RGB全綵LED燈,具有紅色,綠色,和藍色三原色。也就是說這個LED燈內部具有三個不同顏色的LED燈,分別為紅綠藍,並分別接在PB5,PB0,PB1這三個GPIO口上。並且要想使他們發光,這三個GPIO口都要輸出低電平才OK。

那麼,要想使這三個GPIO口能夠輸出低電平或者是高電平。需要哪些步驟呢?

1)開啟這些GPIO口所對應埠的時鐘;

2)配置PB5PB0PB1這三個GPIO口的工作模式;

3)令PB5

PB0PB1這三個GPIO口輸出高低電平以熄滅或點亮對應的LED發光管。

首先對第(1)步進行說明。

經過對原理圖的分析,我們可以看出PB5,PB0,PB1這三個GPIO口是我們需要使用的三個IO口,而他們又都掛在APB2總線上,如圖。

因此我們第一步首先要把GPIOB埠的時鐘使能。通過查詢微控制器參考手冊。找到和GPIOB埠相關的暫存器RCC_APB2ENR,如圖所示。通過查詢我們發現,這個暫存器中的第三位為GPIOB埠的使能位。

再往下查對暫存器RCC_APB2ENR第三位的說明,可以得知,此位為0的時候,埠B的時鐘關閉,此位設定成1的時候,表示開啟IO埠B的時鐘。

那麼我們想使用這個埠的三個引腳PB5,PB0,PB1,就先要把埠B的時鐘開啟。因此程式如下:

RCC->APB2ENR |= (1<<3); //令GPIOB埠時鐘使能

其次對第(2)步進行分析。

在使能過GPIOB埠的時鐘之後,接下來我們就要配置PB5,PB0,PB1這三個引腳的工作模式了。由於這三個引腳是用來點亮LED發光管的,因此要設定成推輓輸出的模式;同時將其輸出的最大頻率設定為50MHz

通過查STM32F10x微控制器參考手冊我們得知,配置GPIO口工作模式和兩個暫存器相關。哪兩個呢?一個叫做GPIOx_CRL,另一個叫做GPIOx_CRH。(其中x=A,B,C....)這兩個暫存器中的L表示低,H表示高。因此顧名思義,GPIOx_CRL這個暫存器管的是0~7這底八個埠的配置,而GPIOx_CRH這個暫存器管的是8~15這個高八個埠的配置。

由於PB5,PB0,PB1這三個引腳都屬於GPIOB_CRL暫存器的配置範疇,因此我們只需要對GPIOB_CRL這個暫存器進行相關配置就好。通過查微控制器參考手冊,我們發現我們應該分別對GPIOB_CRL的0~3位(PB0)、4~7位(PB1)、20~23位(PB5)進行配置。如下圖所示。

同時,通過對其對應位的說明,如要將PB5,PB0,PB1配置成推輓輸出,50MHz的模式,應該將其對應的4位寫入0011(即0x03)即可。

因此寫出程式如下:

//初始化PB0 PB1 PB5為推輓輸出,輸出頻率最大為50MHz

//先清零,再賦值。以下三行為將對應位清零操作

GPIOB->CRL &= ~( 0x0F<< (4*0));

GPIOB->CRL &= ~( 0x0F<< (4*1));

GPIOB->CRL &= ~( 0x0F<< (4*5));

//以下三行分別將PB0 PB1 PB5,設定為推輓輸出50MHz

GPIOB->CRL |= (3<<4*0);

GPIOB->CRL |= (3<<4*1);

GPIOB->CRL |= (3<<4*5);

最後對第(3)步進行分析。

通過原理圖,我們可以看出。要想使這三個LED燈發光,那麼我們需要讓PB5,PB0,PB1這三個引腳輸出一個低電平訊號。通過查微控制器參考手冊,我們可以選擇使用埠輸出資料暫存器(GPIOx_ODR) (x=A..E)來對這三個引腳輸出高低電平進行控制。

對於GPIOB_ODR的用法就是,將對應的位寫0,其對應的管腳輸出低電平訊號。反之,輸出高電平訊號。因此要想將紅綠藍三個LED燈依次點亮,那麼程式如下:

While(1)

{

GPIOB->ODR &= ~(1<<5); //令PB5輸出低電平,點亮紅色LED燈

Delay(1000000);

GPIOB->ODR |= (1<<5); //令PB5輸出高電平,熄滅紅色LED燈

GPIOB->ODR &= ~(1<<0); //令PB0輸出低電平,點亮綠色LED燈

Delay(1000000);

GPIOB->ODR |= (1<<0); //令PB0輸出高電平,熄滅綠色LED燈

GPIOB->ODR &= ~(1<<1); //令PB1輸出低電平,點亮藍色LED燈

Delay(1000000);

GPIOB->ODR |= (1<<1); //令PB1輸出高電平,熄滅藍色LED燈

}

經過以上(1)(2)(3)三個步驟的配置之後,我們將程式編譯燒寫到開發板中,可以看到如下現象:

視訊連線