入手STM32有一段時間了,感覺剛?cè)腴T時很難,無處下手,現(xiàn)在學(xué)到了點皮毛,寫出來和大家分享一下。首先,什么叫GPIO?這個問題,答案是我也不知道!至少目前我沒有必要知道,我只要知道他其實就是51單片機的那種IO口而已,不同的是,51單片機的IO口是不需要配置模式的,而STM32的IO口(哦,不,應(yīng)該說是GPIO口,╮(╯▽╰)╭,真繞舌頭)是需要配置模式和時鐘的(好吧,又冒出一個時鐘來,夠麻煩的),在這里要說明一下,STM32的GPIO,如果你要用它,就要做兩步工作,第一是配置模式、速度,第二是配置其時鐘并使能(貌似說兩步有點牽強)。估計現(xiàn)在大家已經(jīng)糊涂了,好吧,別急,我一點一點給大家解釋解釋;
本文引用地址:http://butianyuan.cn/article/201611/321731.htm我們第一步要知道GPIO的那八種模式是什么,怎么用。GPIO的八種模式如下:
(1)浮空輸入:In_Floating
(2)帶上拉輸入:IPU(In Push_Up)
(3)帶下拉輸入:IPD(In Push_Down)
(4)模擬輸入:AIN(Anolog In)
(5)開漏輸出:OUT_PD(OD 代表開漏,既Open Drain,OC代表開集,Open Collect)
(6)推挽輸出:OUT_PP(PP代表推挽式,Push_Pull)
(7)復(fù)用功能推挽輸出:AF_PP(AF代表復(fù)用功能,Alternate-Fuction)
(8)復(fù)用功能開漏輸出:AF_OD
好吧,就這八種模式,打字打得我手都酸了、、、、、、
這八種模式什么時候用哪種,這個問題值得研究,不過也不用現(xiàn)在就玩命地研究,以后在使用過程中慢慢就體會到了,所以在這里我就不多說了。
再就是配置GPIO的翻轉(zhuǎn)速度了,有10M、2M和50M,具體配置方式等最后我們貼個完整的代碼就明白了。
GPIO配置說完了,再說說時鐘配置,時鐘配置其實就是一堆讓初學(xué)者看不懂的代碼,不過看多了慢慢體會,你就明白他到底是在說什么了,在寫程序的時候可以直接從他給的工程中移植過來,然后修改一下相關(guān)的配制就行了,先貼個代碼,然后再解釋。
上圖是配置時鐘的代碼,我挨著行解釋一下:
SystemInit();看名字就知道這個是系統(tǒng)初始化,到底初始化了些什么,我的意思是不知道,目前也不用知道,你就寫這么一句就行了;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA
|RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC
|RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE
|RCC_APB2Periph_ADC1 | RCC_APB2Periph_AFIO
|RCC_APB2Periph_SPI1, ENABLE );
這幾句有點長,看著就頭暈,但是我們不怕,一句一句看,RCC_APB2PeriphClockCmd()這個函數(shù)名字有點怪,它叫做使能或失能APB2外設(shè)時鐘(這名字夠繞嘴的),不用管它,直接復(fù)制過來就行,再看括號里面的,RCC_APB2Periph_USART1,這個代表的是USART1的時鐘是和APB2的一樣,下面的幾個都是這么個意思,用或符號連接在一起,然后再加上個ENABLE,這就算使能了你想要用的管腳,大家要注意啊,上面的代碼是我隨便找的,在實際使用過程中,具體是能什么,要看你用到什么,就使能什么,不用最好別使能,免得造成不必要的干擾和麻煩。
好了,我們一開始說的兩個問題說完了,下面說一下如何讓GPIO輸出高低電平吧。其實吧這個問題很簡單,很多的資料一提到這個問題,就開始講寄存器,一講寄存器,就涉及到內(nèi)部原理,好吧,終于,初學(xué)者不淡定了,腦子成了一堆漿糊,然后信心受挫,然后就降低了學(xué)習(xí)效率,其實我個人認(rèn)為大不必,既然有庫函數(shù),那我們就先用庫函數(shù),等庫函數(shù)用熟了,再自己慢慢領(lǐng)悟庫函數(shù)里面的寄存器操作??聪旅鎯蓷l語句:
GPIO_SetBits(GPIOD, GPIO_Pin_9);
GPIO_ResetBits(GPIOD, GPIO_Pin_9);
第一句的意思是將GPIOD9口置位(我們假定這個口的模式是輸出模式),第二句的意思是將GPIOD9口清零(同樣的假定)。哈哈,怎么樣,簡單吧,這就是基本的IO口操作,這樣,你就能成功點亮或者熄滅指定的LED了,下面附上一段例程,大家自己慢慢研究。
#include "stm32f10x.h"
//-------------------------------------------GPIO初始化-----------------------------------------//
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOD, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
//--------------------------------------配置系統(tǒng)時鐘,使能各外設(shè)時鐘---------------------------------//
void RCC_Configuration(void)
{
SystemInit();
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB
| RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOD
| RCC_APB2Periph_GPIOE, ENABLE );
}
//-----------------------------------配置所有外設(shè)------------------------------//
void Init_All_Periph(void)
{
RCC_Configuration();
GPIO_Configuration();
}
//----------------------------------------延時函數(shù)--------------------------------------------//
void Delay(vu32 nCount)
{
for(; nCount != 0; nCount--);
}
//------------------------------------------主函數(shù)--------------------------------------------//
int main(void)
{
Init_All_Periph();
while(1)
{
GPIO_SetBits(GPIOD, GPIO_Pin_8);
GPIO_ResetBits(GPIOD, GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11);
Delay(0xEFFFF);
GPIO_SetBits(GPIOD, GPIO_Pin_9);
GPIO_ResetBits(GPIOD, GPIO_Pin_8 | GPIO_Pin_10 | GPIO_Pin_11);
Delay(0xEFFFF);
GPIO_SetBits(GPIOD, GPIO_Pin_10);
GPIO_ResetBits(GPIOD, GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_11);
Delay(0xEFFFF);
GPIO_SetBits(GPIOD, GPIO_Pin_11);
GPIO_ResetBits(GPIOD, GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10);
Delay(0xEFFFF);
GPIO_ResetBits(GPIOD, GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10);
}
}
評論