明解STM32—GPIO理論基礎知識篇之暫存器原理

2023-04-03 06:00:54
 一、前言

        在之前的STM32的GPIO理論基礎知識中,分別對基本結構和工作模式進行了詳細的介紹。GPIO基本結構中主要對GPIO內部的各個功能電路逐一的進行的分析;GPIO工作模式中主要介紹GPIO應用在不同的使用場景下,GPIO埠的靜態特徵設定和動態的工作模式,同時對訊號的工作流進行了分析。

        這一篇主要對GPIO模組使用到的暫存器進行詳細的分析介紹,適當瞭解GPIO暫存器的相關知識,可以對GPIO最底層的一些設定和工作原理有更好的認識,有助於加深對GPIO基本結構及工作模式的理解,同時對後續介紹到的GPIO在應用設計中有較好的幫助。


二、暫存器概述

        圖1為STM32的GPIO模組中暫存器的概述,總共有5種型別的暫存器。這裡需要了解的是GPIO模組的port和pin的概念。其中暫存器名稱中GPIOx的x表示不同的GPIO埠port,比如STM32晶片支援的port可以從A到I,GPIOA,GPIOB就表示了不同的埠;pin就是不同的port下支援的引腳,比如GPIOA下的引腳數從pin0到pin15。因此port就是pin的集合,不同的port都有它自己的如下圖列出來的暫存器。

圖1 GPIO暫存器概述


三、暫存器詳述

        本節對暫存器位、暫存器偏移地址、復位值、暫存器功能定義進行介紹。可通過位元組(8 位)、半字(16 位)或字(32 位)對 GPIO 暫存器進行存取。

(1)埠模式暫存器GPIOx_MODER

        本暫存器的功能為設定GPIO埠的方向和模式,總共0到32位元,每兩位就是該port下的pin值,例如將GPIOA_MODER的MODER0[1:0]設定為00,就是將GPIOA的pin0管腳功能設定為輸入型別的管腳,將GPIOA_MODER的MODER1[1:0]設定為00,就是將GPIOA的pin1管腳功能設定為輸入型別的管腳,以此類推。

圖2 GPIOx_MODER暫存器定義

(2)埠輸出型別暫存器GPIOx_OTYPER

        本暫存器設定GPIO埠的輸出型別,前提是該埠中的pin已經設定成輸出功能。該暫存器只有0到15位有效,每一位就是對應的pin值,例如將GPIOA_OTYPER的OT0設定為1,就是將GPIOA的pin0管腳設定為輸出開漏的型別。

 

圖3 GPIOx_OTYPER暫存器定義

(3)埠輸出速度暫存器GPIOx_OSPEEDR

        本暫存器設定GPIO的輸出速度頻率,前提是該埠中的pin已經應用作為輸出功能管腳。

        這個速度是指輸出驅動電路的響應速度:(晶片內部在I/O口的輸出部分安排了多個響應速度不同的輸出驅動電路,使用者可以根據自己的需要選擇合適的驅動電路,通過選擇速度來選擇不同的輸出驅動模組,達到最佳的噪聲控制和降低功耗的目的。可理解為輸出驅動電路的頻寬:即一個驅動電路可以不失真地通過訊號的最大頻率。

        速度高的IO耗電大、噪聲也大,速度低的IO耗電小、噪聲也小。使用合適的速度可以降低功耗和噪聲。高頻的驅動電路,噪聲也高,當不需要高的輸出頻率時,請選用低頻驅動電路,這樣非常有利於提高系統的EMI效能,也可以降低功耗。當然如果要輸出較高頻率的訊號,但卻選用了較低頻率的速度,很可能會得到失真的輸出訊號。關鍵是GPIO的引腳速度跟應用匹配。

        比如:

        ①USART串列埠,若最大波特率只需115.2k,那用2M的速度就夠了,既省電也噪聲小。

        ②I2C介面,若使用400k波特率,若想把餘量留大些,可以選用10M的GPIO引腳速度。

        ③SPI介面,若使用18M或9M波特率,需要選用50M的GPIO的引腳速度。

        當為該埠下暫存器值的pin設定為11時,輸出速度和電容C有關,這是指對於CMOS工藝的積體電路而言,輸入阻抗是非常高的,主要功耗來自於絕緣柵等效的電容充放電效應。既然是電容的充放電,考慮訊號源的內阻(基於標準CMOS電路的輸出),根據RC充電常數和邏輯閘限電平就能得出一個最小週期,其對應一個最高IO頻率。

圖4 GPIOx_OSPEEDR暫存器定義

(4)埠上拉/下拉暫存器GPIOx_PUPDR

        該暫存器是設定埠對應的pin上是否需要設定晶片內部的上拉或者下拉電阻。

圖5 GPIOx_PUPDR暫存器定義

        STM32晶片GPIO的上拉電阻和下拉電阻最小值,典型值和最大值如下:

 

(5)埠輸入資料暫存器 GPIOx_IDR

        本暫存器讀取GPIO埠引腳的訊號電平值。該暫存器只有0到15位有效,每一位就是對應的pin值,例如GPIOA_OTYPER的IDR00值為1,就是此時讀到GPIOA的pin0管腳值為1高電平訊號。

圖6 GPIOx_IDR暫存器定義

(6)GPIO 埠輸出資料暫存器 GPIOx_ODR

        本暫存器可以設定GPIO埠引腳的訊號值。前提是該引腳為普通的IO輸出引腳。該暫存器只有0到15位有效,每一位就是對應的pin值,例如設定GPIOA_OTYPER的ODR0值為1,就是此時輸出GPIOA的pin0管腳值為1高電平訊號。

圖7 GPIOx_ODR暫存器定義

(7)GPIO 埠置位/復位暫存器GPIOx_BSRR

        本暫存器可以通過寫入GPIOx_BSRR暫存器值,可以對GPIOx_ODR的對應位進行置位和復位。既然GPIOx_ODR 能控制管腳高低電平,為什麼還需要GPIOx_BSRR暫存器?

        原因是GPIOx_BSRR去改變管腳狀態的時候是原子操作置位/復位,沒有被中斷打斷的風險。也就不需要關閉中斷,關閉中斷明顯會延遲或丟失一事件的捕獲,所以控制GPIO的狀態最好可以用GPIOx_BSRR。

        該暫存器的0到15位為置位功能,16到31位元為復位功能。例如設定GPIOA_BSRR的BS0值為1,相當於輸出GPIOA的pin0管腳值為1高電平訊號;設定GPIOA_BSRR的BR0值為1,相當於輸出GPIOA的pin0管腳值為0低電平訊號。

 

圖8 GPIOx_BSRR暫存器定義

(8)GPIO 埠設定鎖定暫存器GPIOx_LCKR

        本暫存器用於鎖定當前管腳的設定,可以保持管腳當前的狀態,保護管腳不受干擾,要使用該暫存器,需要先啟用「鎖定」功能。當執行正確的寫序列設定了位16(LCKK)時,鎖定功能被啟用,LCKK位的寫序列為:寫1 -> 寫0 -> 寫1 -> 讀0 -> 讀1。最後一個讀可省略,但可以用來確認鎖鍵已被啟用。被鎖定的管腳pin只有等到下次MCU復位才能被解鎖。

        LCK0到LCK15為對應的pin0到pin15的鎖定設定,當需要鎖定對應的管腳pin時,在執行LCKK寫序列操作時,將對應的LCK位寫1。

 

  

 圖9 GPIOx_LCKR暫存器定義

(9)GPIO 複用功能低位暫存器GPIOx_AFRL

        本暫存器可以設定GPIO埠引腳的複用功能,比如將該引腳設定成USART或者SPI型別的功能管腳,本暫存器AFRL0~AFRL7分別對應引腳pin0~pin7,每個引腳又有4位元可選,因此一個引腳可以在16中複用功能中選擇,例如將GPIOA_AFRL的AFRL0[3:0]=0001,就是將GPIOA的pin0管腳應用成第2種複用功能AF1。

 

 圖10 GPIOx_AFRL暫存器定義

(10)GPIO 複用功能高位暫存器GPIOx_AFRH

        本暫存器可以設定GPIO埠引腳的複用功能,本暫存器AFRL0~AFRL7分別對應引腳pin0~pin7,功能上和複用功能低位暫存器GPIOx_AFRL一樣。

圖11 GPIOx_AFRH暫存器定義

四、總結

        本篇對STM32的GPIO對應的暫存器分別進行了介紹,瞭解了各個暫存器的功能和對應暫存器位的定義可以更方便的去理解在實際使用GPIO時的設定功能,後續篇章將對GPIO在實際開發中的設計設定及應用進行詳細的分析。


更多技術內容和書籍資料獲取,入群技術交流敬請關注公眾號「明解嵌入式」