Skip to content

[STM32學習記錄-2] 基本輸入與輸出教學-GPIO相關暫存器簡介

發佈

前言

MCU控制最基本的就是輸入與輸出,此篇就來簡單介紹最基本的輸出入相關暫存器。

首先我們要來認識STM32F10x和輸出入有關的暫存器。每個GPIO有:(以下x為Port名稱,也就是A,B,C,D或E)

  1. 兩個32位元的設置暫存器(GPIOx_CRH、GPIOx_CRL)
  2. 兩個32位元的資料暫存器(GPIOx_IDR、GPIOx_ODR)
  3. 一個32位元的位元設定/重置暫存器(GPIOx_BSRR)
  4. 一個16位元的位元重置暫存器(GPIOx_BRR)
  5. 一個32位元的設置鎖定暫存器(GPIOx_LCKR)

一、設置暫存器CRH、CRL

CRH和CRL分別是Configuration Register High與Configuration Register Low的縮寫。CRL負責0~7號接腳,CRH負責8~15號接腳,而每隻接腳使用4個位元。接腳可以透過這4個位元設定成不同的功能。其設定方法如下。

而CRH和CRL的格式如下。CNF和MODE後面的數字就是腳位標號,可以看出每隻接腳由4個位元進行設置,如CRH的31到28位元控制第15腳、CRL的15到12位元控制第3腳。而且所有位元都是可讀寫的。

範例:

GPIOB->CRH = 0x004411EE;
// 將Port B的15、14腳設為類比輸入,
// 13、12腳設為浮空輸入,
// 11、10腳設為最快10MHz的推挽通用輸出,
// 9、8腳設為最快2MHz的汲極開路复用輸出.
 
GPIOA->CRL = 0x22222222;
// 將Port A的7到0腳都設為最快2MHz的推挽通用輸出

至於各個輸出入模式有什麼差別,我簡單的以我找到的資料說明一下:

※推挽和汲極開路

這兩者根本的差異在於電路結構不同。

如果以上還是不瞭解的話,一般就用推挽輸出就好了。詳細可以觀看:

  1. 【Cary-生活筆記】Open-Drain 與 Push-Pull輸出方式有什麼不一樣?
  2. 【CSND】open drain和push pull
  3. 【Wiki維基百科】集電極開路

※通用輸出與复用輸出

如果以上還是不瞭解的話,一般就用通用輸出就好了。詳細可以觀看:

  1. 挽输出、开漏输出、复用开漏输出、复用推挽输出 以及上拉输入、下拉输入、浮空输入、模拟输入的区别

※四種輸入模式

如果以上還是不瞭解的話,一般就用浮接輸入,然後自己外加上/下拉電阻就好了。詳細可以觀看:

  1. 大家来说说自己对GPIO 浮空输入的理解(已解决)
  2. stm32的输入分浮空,上拉,下拉。帮忙教教我这是啥意思。

二、輸出與輸入資料暫存器

ODR與IDR分別是Output Data Register和Input Data Register的縮寫。這兩個暫存器各自控制15到0號腳的輸出入資料。觀察下表可以發現ODR是可讀寫的,而IDR是唯讀的。且兩個暫存器都只是用0到15位元,16到31位元是保留的。

範例:

GPIOB->ODR = 0x0000;        // 將Port B的0到15腳都輸出為低準位
GPIOC->ODR = 0xF8A1;        // 將Port C的15到11、7、5和0號腳設為高準位,其餘為低準位
 
if (GPIOA->IDR & 0x0020)    // 如果PA5是輸入高準位的話
 GPIOC->ODR = 0x2000;       // PC13輸出高準位,其它為低準位
else
 GPIOC->ODR = 0x0000;       // PC13全部輸出低準位
 
if (!(GPIOA->IDR) & 0x0040) // 如果PA6是輸入低準位的話
... //下略

三、位元設置/重置暫存器

BSRR與BRR分別是Bit Set/Reset Register和Bit Reset Register的縮寫。BSRR的31到16位元分別控制15到0號腳的重置功能,如果該位元被設置為1的話,對應的腳位就會被重置為0。而BSRR的15到0位元分別控制15到0號腳的設置功能,如果該位元被設置為1的話,對應的腳位就會被設置為1。

而設置的權重比重置高,所以如果該腳位同時被設置又被重置的話,其結果是該腳位會被設置為1。而BRR的功能和BSRR的31到16位元一樣。而可以注意到的是BSRR和BRR所有位元都是唯寫的。

範例:

GPIOB->BSRR = 0x30000A00; // 將Port B的13和12腳重置為0;11和9腳設置為1
GPIOB->BRR = 0xFFFF;      // 將Port B的所有腳位重置為0

四、設置鎖定暫存器

LCKR是Configuration Lock Register的縮寫。其中15到0位元分別控制15到0號腳的設置(CRH、CRL)鎖定狀態,0是未鎖定,1是鎖定,這16位元只能在LCKK為0時寫入。而第16位元是LCKK(Lock Key)位元,用來鎖定LCKR暫存器,0代表未鎖定,1代表鎖定,直到下次系統重置前LCKR暫存器都會被鎖定。

要特別注意到是這個鎖定的功能是用來鎖定腳位的輸出入模式設置,也就是鎖CRH和CRL的設置,不是用來鎖定腳位的高低準位的。

而LCKR的寫法比較特別,我也還不是很清楚,只知道要照著以下的格式進行寫入。日後如果有找到寫法的話我再來更新。

WR LCKR[16] = ‘1’ + LCKR[15:0]
WR LCKR[16] = ‘0’ + LCKR[15:0]
WR LCKR[16] = ‘1’ + LCKR[15:0]
RD LCKR
RD LCKR[16] = ‘1’(非必要,但可以確保)

五、 APB2外圍設備時鐘致能暫存器

除了以上5種暫存器外,還要在加上一個RCC_APB2ENR暫存器,腳位才能正常的使用。

APB2ENR是APB2 Peripheral Clock Enable Register的縮寫。每個位元都代表一個外圍設備,而當該位元為1時代表對應的功能致能(開啟),反之設為0代表禁能(關閉)。

而我們寫APB2ENR時通常使用OR的方式,請看範例:

RCC->APB2ENR = RCC->APB2ENR | 0x0004;   // 開啟Port A的時鐘
RCC->APB2ENR |= 0x0004;                 // 同上行
RCC->APB2ENR |= (1<<2);                 // 同上行

[STM32學習記錄-3] 基本輸入與輸出教學-GPIO相關程式寫法
DaVinci Resolve 15 小功能介紹

留言可能不會立即顯示。若過了幾天仍未出現,請 Email 聯繫:)