<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > STM32學(xué)習(xí)筆記之GPIO口的使用

          STM32學(xué)習(xí)筆記之GPIO口的使用

          作者: 時(shí)間:2016-11-21 來源:網(wǎng)絡(luò) 收藏
          STM32 Cotex-M3 GPIO口簡介與配置

          一、GPIO口簡介

          本文引用地址:http://www.ex-cimer.com/article/201611/319282.htm

          1、 GPIO口輸入輸出模式

          1.1 一般來說STM32的輸入輸出管腳有以下8種配置方式:


          輸入

          ① 浮空輸入_IN_FLOATING——浮空輸入,可以做KEY識(shí)別

          ② 帶上拉輸入_IPU ——IO內(nèi)部上拉電阻輸入

          ③ 帶下拉輸入_IPD ——IO內(nèi)部下拉電阻輸入

          ④ 模擬輸入_AIN ——應(yīng)用ADC模擬輸入,或者低功耗下省電

          輸出
          ⑤ 開漏輸出_OUT_OD ——IO輸出0接GND,IO輸出1,懸空,需要外接上拉電阻,才能實(shí)現(xiàn)輸出高電平。

          當(dāng)輸出為1時(shí),IO口的狀態(tài)由上拉電阻拉高電平,但由于是開漏輸出模式,這樣IO

          口也就可以由外部電路改變?yōu)榈碗娖交虿蛔?。可以讀IO輸入電平變化,實(shí)現(xiàn)C51的

          IO雙向功能。

          ⑥ 推挽輸出_OUT_PP ——IO輸出0-接GND, IO輸出1 -接VCC,讀輸入值是未知的。

          復(fù)用輸出

          ⑦ 復(fù)用功能的推挽輸出_AF_PP ——片內(nèi)外設(shè)功能(I2C的SCL,SDA)

          ⑧ 復(fù)用功能的開漏輸出_AF_OD ——片內(nèi)外設(shè)功能(TX1,MOSI,MISO,SCK,SS)

          2、輸入輸出模式詳解

          一般我們平時(shí)用的最多的也就是推挽輸出、開漏輸出、上拉輸入,介紹如下:

          2.1推挽輸出:

          可以輸出高,低電平,連接數(shù)字器件;推挽結(jié)構(gòu)一般是指兩個(gè)三極管分別受兩互補(bǔ)信號(hào)的控制,總是在一個(gè)三極管導(dǎo)通的時(shí)候另一個(gè)截止。高低電平由IC的電源低定。

          推挽電路是兩個(gè)參數(shù)相同的三極管或MOSFET,以推挽方式存在于電路中,各負(fù)責(zé)正負(fù)半周的波形放大任務(wù),電路工作時(shí),兩只對稱的功率開關(guān)管每次只有一個(gè)導(dǎo)通,所以導(dǎo)通損耗小、效率高。輸出既可以向負(fù)載灌電流,也可以從負(fù)載抽取電流。推拉式輸出級(jí)既提高電路的負(fù)載能力,又提高開關(guān)速度。

          2.2開漏輸出:


          輸出端相當(dāng)于三極管的集電極。要得到高電平狀態(tài)需要上拉電阻才行。 適合于做電流型的驅(qū)動(dòng),其吸收電流的能力相對強(qiáng)(一般20mA以內(nèi))

          開漏形式的電路有以下幾個(gè)特點(diǎn):

          1、利用外部電路的驅(qū)動(dòng)能力,減少IC內(nèi)部的驅(qū)動(dòng)。當(dāng)IC內(nèi)部MOSFET導(dǎo)通時(shí),驅(qū)動(dòng)電流是從外部的VCC流經(jīng)R pull-up ,MOSFET到GND。IC內(nèi)部僅需很小的極驅(qū)動(dòng)電流。

          2、一般來說,開漏是用來連接不同電平的器件,匹配電平用的,因?yàn)殚_漏引腳不連接外部的上拉電阻時(shí),只能輸出低電平,如果需要同時(shí)具備輸出高電平的功能,則需要接上拉電阻,很好的一個(gè)優(yōu)點(diǎn)是通過改變上拉電源的電壓,便可以改變傳輸電平。比如加上上拉電阻就可以提供TTL/CMOS電平輸出等。(上拉電阻的阻值決定了邏輯電平轉(zhuǎn)換的沿的速度。阻值越大,速度越低功耗越小,所以負(fù)載電阻的選擇要兼顧功耗和速度。)

          3、 OPEN-DRAIN提供了靈活的輸出方式,但是也有其弱點(diǎn),就是帶來上升沿的延時(shí)。因?yàn)樯仙厥峭ㄟ^外接上拉無源電阻對負(fù)載充電,所以當(dāng)電阻選擇小時(shí)延時(shí)就小,但功耗大;反之延時(shí)大功耗小。所以如果對延時(shí)有要求,則建議用下降沿輸出。

          4、可以將多個(gè)開漏輸出的Pin,連接到一條線上。通過一只上拉電阻,在不增加任何器件的情況下,形成“與邏輯”關(guān)系。這也是I2C,SMBus等總線判斷總線占用狀態(tài)的原理。

          補(bǔ)充:什么是“線與”?:

          在一個(gè)結(jié)點(diǎn)(線)上, 連接一個(gè)上拉電阻到電源 VCC 或 VDD 和 n 個(gè) NPN 或 NMOS 晶體管的集電極 C 或漏極 D, 這些晶體管的發(fā)射極 E 或源極 S 都接到地線上, 只要有一個(gè)晶體管飽和,這個(gè)結(jié)點(diǎn)(線)就被拉到地線電平上。 因?yàn)檫@些晶體管的基極注入電流(NPN)或柵極加上高電平(NMOS), 晶體管就會(huì)飽和,所以這些基極或柵極對這個(gè)結(jié)點(diǎn)(線)的關(guān)系是或非 NOR 邏輯。 如果這個(gè)結(jié)點(diǎn)后面加一個(gè)反相器, 就是或 OR 邏輯。

          其實(shí)可以簡單的理解為:在所有引腳連在一起時(shí),外接一上拉電阻,如果有一個(gè)引腳輸出為邏輯0,相當(dāng)于接地,與之并聯(lián)的回路“相當(dāng)于被一根導(dǎo)線短路”,所以外電路邏輯電平便為0,只有都為高電平時(shí),與的結(jié)果才為邏輯1。

          2.3浮空輸入 :對于浮空輸入,一直沒找到很權(quán)威的解釋,只好從以下圖中去理解了。



          2.4 上拉輸入/下拉輸入/模擬輸入:這幾個(gè)概念很好理解,從字面便能輕易讀懂。

          2.5 復(fù)用開漏輸出、復(fù)用推挽輸出:可以理解為GPIO口被用作第二功能時(shí)的配置情況(即并非作為通用IO口使用)

          二、GPIO口配置

          1、根據(jù)具體應(yīng)用配置為輸入或輸出

          ① 作為普通GPIO輸入:

          根據(jù)需要配置該引腳為浮空輸入、帶弱上拉輸入或帶弱下拉輸入,同時(shí)不要使能該引腳對應(yīng)的所有復(fù)用功能模塊。

          ② 作為普通GPIO輸出:

          根據(jù)需要配置該引腳為推挽輸出或開漏輸出,同時(shí)不要使能該引腳對應(yīng)的所有復(fù)用功能模塊。

          ③ 作為普通模擬輸入:

          配置該引腳為模擬輸入模式,同時(shí)不要使能該引腳對應(yīng)的所有復(fù)用功能模塊。

          ④ 作為內(nèi)置外設(shè)的輸入:

          根據(jù)需要配置該引腳為浮空輸入、帶弱上拉輸入或帶弱下拉輸入,同時(shí)使能該引腳對應(yīng)的某個(gè)復(fù)用功能模塊。

          ⑤ 作為內(nèi)置外設(shè)的輸出:

          根據(jù)需要配置該引腳為復(fù)用推挽輸出或復(fù)用開漏輸出,同時(shí)使能該引腳對應(yīng)的所有復(fù)用功能模塊。

          2、輸出模式下,配置速度

          I/O口輸出模式下,有3種輸出速度可選(2MHz、10MHz和50MHz),這個(gè)速度是指I/O口驅(qū)動(dòng)電路的響應(yīng)速度而不是輸出信號(hào)的速度,輸出信號(hào)的速度與程序有關(guān)(芯片內(nèi)部在I/O口的輸出部分安排了多個(gè)響應(yīng)速度不同的輸出驅(qū)動(dòng)電路,用戶可以根據(jù)自己的需要選擇合適的驅(qū)動(dòng)電路)。通過選擇速度來選擇不同的輸出驅(qū)動(dòng)模塊,達(dá)到最佳的噪聲控制和降低功耗的目的。高頻的驅(qū)動(dòng)電路,噪聲也高,當(dāng)不需要高的輸出頻率時(shí),請選用低頻驅(qū)動(dòng)電路,這樣非常有利于提高系統(tǒng)的EMI性能。當(dāng)然如果要輸出較高頻率的信號(hào),但卻選用了較低頻率的驅(qū)動(dòng)模塊,很可能會(huì)得到失真的輸出信號(hào)。關(guān)鍵是GPIO的引腳速度跟應(yīng)用匹配。

          2.1對于串口,假如最大波特率只需115.2k,那么用2M的GPIO的引腳速就夠

          了,既省電也噪聲小。

          2.2對于I2C接口,假如使用400k波特率,若想把余量留大些,那么用2M的

          GPIO的引腳速度或許不夠,這時(shí)可以選用10M的GPIO引腳速度。

          2.3 對于SPI接口,假如使用18M或9M波特率,用10M的GPIO的引腳速度顯然不夠了,需要選用50M的GPIO的引腳速度。

          3、GPIO口初始化

          ①使能GPIO口的時(shí)鐘 ②配置模式設(shè)置(8種模式)

          STM32的GPIO的時(shí)鐘統(tǒng)一掛接在APB2上,具體的使能寄存器為RCC_APB2ENR該寄存器的第2位到第8位分別控制GPIOx(x=A,B,C,D,E,F,G)端口的時(shí)鐘使能。

          如打開PORTA時(shí)鐘 RCC->APB2ENR|=1<<2; //使能PORTA時(shí)鐘

          如果把端口配置成復(fù)用輸出功能,則還需開始復(fù)用端口時(shí)鐘,并進(jìn)行相應(yīng)配置。

          4、GPIO配置寄存器

          GPIO口配置是通過配置寄存器來進(jìn)行的,每個(gè)GPIO 端口有:

          兩個(gè)32位配置寄存器(GPIOx_CRL,GPIOx_CRH)分別控制每個(gè)端口的高八位和低八位。如果IO口是0-7號(hào)的話,則寫CRL寄存器;如果IO口是8-15號(hào)的話,則寫CRH寄存器。

          兩個(gè)32位數(shù)據(jù)寄存器(GPIOx_IDR,GPIOx_ODR)一個(gè)是只讀作輸入數(shù)據(jù)寄存器,一個(gè)是只寫作輸出寄存器。

          一個(gè)32位置位/復(fù)位寄存器(GPIOx_BSRR)。

          一個(gè)16位復(fù)位寄存器(GPIOx_BRR)。

          一個(gè)32位鎖定寄存器(GPIOx_LCKR)。

          常用的IO端口寄存器只有四個(gè):CRH,CRL,IDR,ODR。

          數(shù)據(jù)手冊中列出的每個(gè)I/O端口的特定硬件特征。 GPIO端口的每個(gè)位可以由軟件分別配置成多種模式。每個(gè)I/O端口位可以自由編程,然而I/0端口寄存器必須按32位字被訪問(不允許半字或字節(jié)訪問)。另外,STM32的每個(gè)端口使用前都要將其時(shí)鐘使能,STM32的GPIO的時(shí)鐘統(tǒng)一掛接在APB2上,具體的使能寄存器為RCC_APB2ENR,該寄存器的第2位到第8位分別控制GPIOx(x=A,B,C,D,E,F,G)端口的時(shí)鐘使能,當(dāng)外設(shè)時(shí)鐘沒有啟用時(shí),程序不能讀出外設(shè)寄存器的數(shù)值,如打開PORTA時(shí)鐘: RCC->APB2ENR|=1<<2; //使能PORTA時(shí)鐘

          總結(jié)一下GPIO功能:

          1、通用I/O(GPIO):最基本的功能,可以驅(qū)動(dòng)LED、可以產(chǎn)生PWM、可以驅(qū)動(dòng)蜂鳴器等等;

          2、單獨(dú)的位設(shè)置或位清除:方便軟體作業(yè),程序簡單。端口配置好以后只需GPIO_SetBits(GPIOx, GPIO_Pin_x)就可以實(shí)現(xiàn)對GPIOx的pinx位為高電平;

          3、所有端口都有外部中斷能力:端口必須配置成輸入模式,所有端口都有外部中斷能力;

          4、復(fù)用功能(AF):復(fù)用功能的端口兼有IO功能等。復(fù)位期間和剛復(fù)位后,復(fù)用功能未開啟,I/O 端口被配置成浮空輸入模式。

          5、 軟件重新映射I/O復(fù)用功能:為了使不同器件封裝的外設(shè)I/O 功能的數(shù)量達(dá)到最優(yōu),可以把一些復(fù)用功能重新映射到其他一些腳上。這可以通過軟件配置相應(yīng)的寄存器來完成。這時(shí),復(fù)用功能就不再映射到它們的原始引腳上了。

          6、 GPIO鎖定機(jī)制:當(dāng)在一個(gè)端口位上執(zhí)行了所定(LOCK)程序,在下一次復(fù)位之前,將不能再更改端口位的配置。

          5、GPIO寄存器詳解

          參見《STM32F10X中文手冊》

          三、GPIO輸出實(shí)驗(yàn)

          這里利用ST固件庫,就不需要自己對照配置寄存器寫代碼,直接利用庫函數(shù),非常方便。

          4個(gè)LED接在GPIOF管腳6、7、8、9,為推挽輸出

          Main.c

          #include "stm32f10x.h"

          #include "led.h"

          void Delay(u32 d_time);

          int main(void)

          {

          LED_Init();

          while(1)

          {

          GPIO_SetBits(GPIOF,GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9);

          Delay(3000000);

          GPIO_ResetBits(GPIOF,GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9);

          Delay(3000000);

          }

          }

          void Delay(u32 d_time)

          {

          for(;d_time>0;d_time--);

          }

          Led.h

          #ifndef __LED_H

          #define __LED_H

          void LED_Init(void);

          #endif

          Led.c

          #include "led.h"

          //LED IO初始化

          void LED_Init(void)

          {

          GPIO_InitTypeDef GPIO_InitStructure;

          RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOF, ENABLE);

          GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9;

          GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

          GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

          GPIO_Init(GPIOF, &GPIO_InitStructure);

          GPIO_ResetBits(GPIOF,GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9);

          }



          關(guān)鍵詞: STM32GPIO

          評論


          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();