當(dāng)前位置:首頁(yè) > 單片機(jī) > 單片機(jī)
[導(dǎo)讀]//======================================================//**基于學(xué)習(xí)STM32有一段時(shí)間了,特意寫下一篇關(guān)于一個(gè)簡(jiǎn)單的跑馬燈的例程,梳理思路,也希望我自己的理解能幫到一些學(xué)習(xí)STM32的初學(xué)者//================

//======================================================//

**基于學(xué)習(xí)STM32有一段時(shí)間了,特意寫下一篇關(guān)于一個(gè)簡(jiǎn)單的跑馬燈

的例程,梳理思路,也希望我自己的理解能幫到一些學(xué)習(xí)STM32的初學(xué)者

//======================================================//

首先,GPIO的配置種類有8種。分別為模擬輸入、浮空輸入,上拉輸入、下拉輸入、開(kāi)漏輸出、推挽輸出、復(fù)用開(kāi)漏輸出、復(fù)用推挽輸出。

下面將以實(shí)例的方式講解GPIO的設(shè)置及實(shí)現(xiàn)過(guò)程。

事例1:跑馬燈實(shí)驗(yàn)

跑馬燈實(shí)驗(yàn)的功能:LED燈進(jìn)行有規(guī)律閃爍。(下面的LED燈的數(shù)量都為2個(gè),所以關(guān)于寄存器的配置也將以兩組的方式進(jìn)行講解)

首先要知道普通的IO就兩種功能一個(gè)為輸入,一個(gè)為輸出。然后再以輸入和輸出細(xì)分為以哪種模式輸出、以哪種模式輸入。要設(shè)置IO的模式這時(shí)就要使用到寄存器進(jìn)行設(shè)置,STM32的IO端口一般由7個(gè)寄存器來(lái)進(jìn)行控制。

分別為

(1)配置模式的2個(gè)32位的端口配置寄存器 CRL 和 CRH;

(2)2 個(gè) 32 位的數(shù)據(jù)寄存器 IDR 和 ODR;

(3)1 個(gè) 32 位的置位/復(fù)位寄存器BSRR;

(4)1個(gè) 16 位的復(fù)位寄存器 BRR;

(5)1 個(gè) 32 位的鎖存寄存器 LCKR;

而我們常用的 IO 端口寄存器只有 4 個(gè):CRL、CRH、IDR、ODR。

首先,一般一個(gè)程序的開(kāi)始都會(huì)從入口main函數(shù)開(kāi)始執(zhí)行,而一個(gè)功能的實(shí)現(xiàn)之前都需要做一些準(zhǔn)備工作,當(dāng)然跑馬燈也不例外,在程序執(zhí)行前,IO需要初始化,而初始化要做的就是對(duì)程序需要用到的GPIO的寄存器進(jìn)行配置。然后設(shè)定輸出設(shè)備的初始狀態(tài),即跑馬燈的初始狀態(tài)。一般程序在執(zhí)行前,輸出設(shè)備都會(huì)是處于關(guān)閉狀態(tài)。最后增加延時(shí)函數(shù),讓LED燈在亮與滅之間有一段時(shí)間的狀態(tài)保留,不然時(shí)間過(guò)快,人類的視覺(jué)根本捕抓它的狀態(tài)變化。

下面來(lái)講一下實(shí)現(xiàn)跑馬燈效果的IO要怎么配置。首先先說(shuō)一下使用LED來(lái)進(jìn)行跑馬功能的話只需要用到RCC->APB2ENR、GPIOX->CRL、GPIOX->ODR三個(gè)寄存器(GPIOX中的X表示為GPIO的組別,例如GPIOB表示在GPIO的B組上,因?yàn)橐话銌纹瑱C(jī)上的GPIO一般都會(huì)有很多組的,這樣也只是為了區(qū)分這些IO罷了)

CRL 和 CRH 控制著每個(gè) IO 口的模式及輸出速率。

這里需要注意的是在配置GPIO前,都需要先使能該GPIO的時(shí)鐘?。赡苡腥藭?huì)問(wèn)“為什么一定要是使能時(shí)鐘呢?”答案是:GPIO也是外設(shè)的一種,然后外設(shè)是需要提供時(shí)鐘信號(hào)工作,以便于設(shè)置GPIO的數(shù)據(jù)傳輸速度的高速/低速輸出,所以有關(guān)數(shù)據(jù)的傳輸都是在時(shí)鐘信號(hào)的基礎(chǔ)上的。51單片的IO口也有時(shí)鐘,只是為了方便,默認(rèn)開(kāi)啟的,ST的為了更好的控制功耗,電路上做的可以選擇開(kāi)關(guān)時(shí)鐘,降低功耗。補(bǔ)充網(wǎng)友的答案:“寄存器是基于觸發(fā)器的,觸發(fā)器的賦值是一定需要時(shí)鐘的,而寄存器的時(shí)鐘是由總線時(shí)鐘提供的,就是說(shuō)沒(méi)有總線時(shí)鐘的話,你給寄存器值它是不會(huì)讀入的”)

然后設(shè)置兩個(gè)LED的GPIO的模式,因?yàn)長(zhǎng)ED是輸出設(shè)備,所以GPIO將設(shè)置成輸出模式,其中配置模式要用到的寄存器為配置寄存器CRL和CRH。其中CRH為高位寄存器,CRL為低位寄存器。(有人可能有疑問(wèn)為什么用的是32位的寄存器為什么還要為兩個(gè)寄存器來(lái)管理呢?難道是32位還不夠配置嗎?答案是:是的,不夠用。配置寄存器對(duì)一個(gè)GPIO的配置要用4個(gè)位來(lái)完成。一組GPIO有16個(gè)引腳,一個(gè)引腳要4位的話,那么16個(gè)引腳就要16*4=64,那么就要2個(gè)32位的寄存器來(lái)實(shí)現(xiàn),所以就干脆把高八位給一個(gè)寄存器,低八位給另外一個(gè)寄存器,這就出現(xiàn)了CRL和CRH。也許有人還會(huì)有疑問(wèn)說(shuō)為什么一定要用4位來(lái)對(duì)一個(gè)引腳的配置呢?答案是肯定的,因?yàn)榍懊嬲f(shuō)了,對(duì)GPIO的配置首先配置為輸入模式或者輸出模式,然后再對(duì)輸入、輸出配置為哪種輸出,哪種輸入,是推挽輸出呢,還是開(kāi)漏輸入呢,這都是需要至少2個(gè)位來(lái)進(jìn)行配置,而且輸入、輸出模式各有4種模式,共8中,這樣要以最少的資源來(lái)實(shí)現(xiàn)的話,用00、01、10、11這種2個(gè)位來(lái)實(shí)現(xiàn)是最省資源的,所以2*2=4,所以對(duì)于1個(gè)GPIO的模式的配置至少也就要4位了。)

接著就是查看LED的GPIO的引腳接在IC哪個(gè)引腳上。怎么查看LED的引腳到底接在哪呢?這個(gè)要看開(kāi)發(fā)板的原理圖,不同的板子來(lái)說(shuō)或者對(duì)于不同的商家來(lái)說(shuō)在GPIO的引腳接線上會(huì)有不同,以我的開(kāi)發(fā)板的原理圖可以發(fā)現(xiàn)LED燈的GPIO分別接在了GPIOB的pin5和GPIOE的pin5上,根據(jù)電路性質(zhì),一般會(huì)將LED設(shè)置為推挽輸出模式(可能這時(shí)就會(huì)有人問(wèn)了,為什么就是推挽呢?為什么不是開(kāi)漏呢?我的理解是:這是有電路性質(zhì)決定的,推挽顧名思義就是灌電流與拉電流都可以輸出,通俗地講就是輸出高低電平。而開(kāi)漏是一直輸出低電平,當(dāng)你要輸出高電平的時(shí)候需要加上拉)

通過(guò)查閱寄存器的數(shù)據(jù)手冊(cè)可知,00位通用推挽模式,那么

//======================================================//

GPIOB->CRL |= 3 << 20;//設(shè)置模數(shù)數(shù)據(jù)傳輸速率

GPIOB->CRL &=~(3 << 22);//設(shè)置GPIO模式

//======================================================//

這樣就把GPIOB組的pin5設(shè)置成了通用推挽模式,前面說(shuō)了一個(gè)引腳需要4個(gè)位來(lái)配置,查看寄存器數(shù)據(jù)手冊(cè)可看到,前面2個(gè)位是設(shè)置通用推挽模式的,后面2個(gè)位是基于這種模式的數(shù)據(jù)傳輸速率,在這里我們懸著的是“最大速度50MHz”,而GPIOB->CRL|=3<<20;就是設(shè)置數(shù)據(jù)傳輸速率為最大速度50MHz,GPIOB->CRL&=~(3<<22);為設(shè)置GPIOB的pin5為通用推挽模式。

最后就是設(shè)置LED的初始狀態(tài)了,再說(shuō)之前先說(shuō)一下ODR寄存器。

ODR是一個(gè)端口輸出數(shù)據(jù)寄存器,也只用了低16位。該寄存器為可讀寫,從該寄存器讀出來(lái)的數(shù)據(jù)可以用于判斷當(dāng)前IO 口的輸出狀態(tài)。而向該寄存器寫數(shù)據(jù),則可以控制某個(gè) IO 口的輸出電平。

所以在配置LED初始化的時(shí)候就需要調(diào)用這個(gè)寄存器設(shè)置LED的初始狀態(tài)。

//======================================================//

GPIOE->ODR|=1<<5;//設(shè)置LED的初始化狀態(tài)為1(1為到電平,亮滅有其電路決定,我的開(kāi)發(fā)板由于接了上拉,使得低電平才是有效的,即0為L(zhǎng)ED燈亮,1為L(zhǎng)ED燈滅)

//======================================================//

這樣初始化函數(shù)就完成了。

具體初始化代碼如下:

//=======================led.c===============================//

#include "stm32f10x.h"

#include "led.h"

void led_Init(void)

{

RCC ->APB2ENR |= 1 << 3;//使能 PORTB 時(shí)鐘

RCC ->APB2ENR |= 1 << 6;//使能 PORTE 時(shí)鐘

GPIOB ->CRL |= 3 << 20;

GPIOB ->CRL &=~ (3 << 22);//PB.5 推挽輸出

GPIOB ->ODR |= 1 << 5;//PB.5 輸出高

GPIOE ->CRL |= 3 << 20;

GPIOE ->CRL &= ~(3 << 22);//PE.5 推挽輸出

GPIOE ->ODR |= 1 << 5;//PE.5 輸出高

}

//======================================================//

其頭文件如下:

//=========================led.h=============================//

#ifndef __LED_H_

#define __LED_H_

extern void led_Init(void);

#endif

//======================================================//

接下來(lái)說(shuō)一下初始化好了,主函數(shù)要怎么寫。

第一需要的是點(diǎn)亮LED的語(yǔ)句,在初始化中有提到,設(shè)置LED初始化狀態(tài)即:GPIOB ->ODR |= 1 << 5;//PB.5 輸出高

那么同時(shí)也能使用這句來(lái)進(jìn)行LED的亮滅控制。代碼如下:

//==========================main.c============================//

#include "stm32f10x.h"

#include "led.h"

int main(void)

{

int i=0;

led_Init();//LED初始化

while(1)

{

GPIOB ->ODR &= ~ (1 << 5);//PB.5輸出低電平,即點(diǎn)亮LED

GPIOE ->ODR &= ~(1 << 5);//PB.5輸出低電平,即點(diǎn)亮LED

for(i=0;i<1000000;i++);//延時(shí)

GPIOB ->ODR |= 1 << 5;//PE.5輸出高電平,即滅掉LED

GPIOE ->ODR |= 1 << 5;//PB.5輸出高電平,即滅掉LED

for(i=0;i<1000000;i++);//延時(shí)

}

}

//======================================================//

整個(gè)跑馬燈的工程就只需這三個(gè)文件,就能簡(jiǎn)單實(shí)現(xiàn)跑馬的功能,如果你想要延時(shí)的時(shí)間是規(guī)律的,那么你就要去使用定時(shí)器了。因?yàn)槎〞r(shí)器定時(shí)的時(shí)間是準(zhǔn)時(shí)的,軟件延時(shí)第一消耗CPU的資源,然后時(shí)間也不夠精確,所以一般在對(duì)時(shí)間要求沒(méi)有很精確的要求是才會(huì)使用軟件延時(shí)的做法。


本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫?dú)角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

倫敦2024年8月29日 /美通社/ -- 英國(guó)汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開(kāi)發(fā)耗時(shí)1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動(dòng) BSP

北京2024年8月28日 /美通社/ -- 越來(lái)越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運(yùn)行,同時(shí)企業(yè)卻面臨越來(lái)越多業(yè)務(wù)中斷的風(fēng)險(xiǎn),如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報(bào)道,騰訊和網(wǎng)易近期正在縮減他們對(duì)日本游戲市場(chǎng)的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)開(kāi)幕式在貴陽(yáng)舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語(yǔ)權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點(diǎn): 有效應(yīng)對(duì)環(huán)境變化,經(jīng)營(yíng)業(yè)績(jī)穩(wěn)中有升 落實(shí)提質(zhì)增效舉措,毛利潤(rùn)率延續(xù)升勢(shì) 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長(zhǎng) 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競(jìng)爭(zhēng)力 堅(jiān)持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競(jìng)爭(zhēng)優(yōu)勢(shì)...

關(guān)鍵字: 通信 BSP 電信運(yùn)營(yíng)商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺(tái)與中國(guó)電影電視技術(shù)學(xué)會(huì)聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會(huì)上宣布正式成立。 活動(dòng)現(xiàn)場(chǎng) NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長(zhǎng)三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會(huì)上,軟通動(dòng)力信息技術(shù)(集團(tuán))股份有限公司(以下簡(jiǎn)稱"軟通動(dòng)力")與長(zhǎng)三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉