[STM32學習記錄-3] 基本輸入與輸出教學-GPIO相關程式寫法

系列:STM32學習記錄 Posted on 2018-09-08

先前已經介紹過GPIO相關暫存器的用法了,現在我來介紹幾個最基本的輸出入程式寫法。

由於我使用的開發板NUCLEO-F103RB上有内建LED燈(PA5)和按鈕(PC13),所以以下的程式我就直接使用這兩隻腳位。

 1// 基本輸出
 2#include "stm32f10x.h"
 3
 4void Delay(__IO u32 nCount);
 5
 6int main(void)
 7{
 8   RCC->APB2ENR |= 0x00000004; // 啟用GPIOA時鐘
 9   GPIOA->CRL = 0x00200000;    // 設定PA5為推挽輸出,最高輸出頻率為2MHz
10   while(1)
11   {
12     GPIOA->ODR = 0X0020;      // PA5 = 1
13     Delay(6400000);           // Delay
14     GPIOA->ODR = 0X0000;      // PA5 = 0
15     Delay(6400000);           // Delay
16   }
17}
18
19void Delay(__IO u32 nCount)
20{
21   for (; nCount != 0; nCount--);
22}

▲ 基本輸出-中間的綠色LED會不斷閃爍。

▲ 基本輸出-中間的綠色LED會不斷閃爍。

 1// 基本輸出
 2#include "stm32f10x.h"
 3
 4int main(void)
 5{
 6   RCC->APB2ENR |= 0X00000044;  // 啟用GPIOA、GPIOE時鐘
 7   GPIOA->CRL = 0x00200000;     // 設定PA5為推挽輸出,最高輸出頻率為2MHz
 8   GPIOC->CRH = 0x00400000;     // 設定PC13為浮空輸入
 9
10   while(1)
11   {
12     if(GPIOC->IDR & 0x2000)    // if PC13 = 1
13       GPIOA->ODR = 0X0020;     // PA5 = 1
14     else
15       GPIOA->ODR = 0X0000;     // PA5 = 0
16   }
17}

▲ 基本輸入-按下按鈕後中間的綠色LED熄滅,否則亮起。

▲ 基本輸入-按下按鈕後中間的綠色LED熄滅,否則亮起。

基本輸出入除了以上這種直接寫入暫存器的方法外還可以使用函數的方式來達成,而這些函數都在stm32f10x_rcc.c和stm32f10x_gpio.c中(參考路徑:Libraries\STM32F10x_StdPeriph_Driver\src),有興趣的可以參考研究。

如果將上面的基本輸入程式改用函數的話,寫法如下。

 1// 基本輸入-使用各種函數來達成
 2#include "stm32f10x.h"
 3
 4int main(void)
 5{
 6    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);    // 啟用GPIOA時鐘
 7    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);    // 啟用GPIOC時鐘
 8
 9    // 宣告一個GPIO_InitTypeDef類型的結構GPIO_InitStructure
10    GPIO_InitTypeDef GPIO_InitStructure;
11
12    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;             // 使用Pin_5
13    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;      // 設定為推挽式輸出
14    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;      // 設定最高輸出頻率為2MHz
15    GPIO_Init(GPIOA, &GPIO_InitStructure); // 選為GPIO Port-A,傳入以上設定
16
17    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;            // 使用Pin_13
18    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; // 設定為浮空輸入
19    GPIO_Init(GPIOC, &GPIO_InitStructure); // 選爲GPIO Port-C,傳入以上設定
20
21    while (1)
22    {
23        if(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_13) == 1) // if PC13 = 1
24            GPIO_SetBits(GPIOA,GPIO_Pin_5);           // PA5 = 1
25        else
26            GPIO_ResetBits(GPIOA,GPIO_Pin_5);         // PA5 = 0
27    }
28}

以下個別介紹使用到的函數:


RCC_APB2PeriphClockCmd

  • 函數原型:void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState)
  • 功能:致能(使用)或禁能(關閉)APB2外圍設備時鐘。
  • 輸出參數1:RCC_APB2Periph,選擇要設定的外圍設備(詳細用法請見下方表格整理)。
  • 輸入參數2:NewState,選擇要使用還是關閉時鐘(詳細用法請見下方表格整理)。
  • 輸出參數:無
  • 返回值:無
  • 先決條件:無
  • 被調用函數:無

GPIO_Init

  • 函數原型:void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)
  • 功能:設定GPIO的模式,也就是設定CRH、CRL暫存器。
  • 輸入參數1:GPIOx,選擇GPIO。
  • 輸入參數2:GPIO_InitStruct,選擇GPIO模式。爲指向GPIO_InitTypeDef的指標。GPIO_InitTypeDef類型的結構有以下3個成員(詳細用法請見下方表格整理)。
    • GPIO_Pin
    • GPIO_Speed
    • GPIO_Mode
  • 輸出參數:無
  • 返回值:無
  • 先決條件:無
  • 被調用函數:無

GPIO_ReadInputDataBit

  • 函數原型:uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
  • 功能:讀取指定端口的輸入值。
  • 輸入參數1:GPIOx,選擇GPIO(詳細用法請見下方表格整理)。
  • 輸入參數2:GPIO_Pin,選擇GPIO_Pin(詳細用法請見下方表格整理)。
  • 輸出參數:無
  • 返回值:端口的輸入值,1或是0。
  • 先決條件:無
  • 被調用函數:無

GPIO_SetBits

  • 函數原型:void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
  • 功能:將端口設置為1。
  • 輸入參數1:GPIOx,選擇GPIO(詳細用法請見下方表格整理)。
  • 輸入參數2:GPIO_Pin,選擇GPIO_Pin(詳細用法請見下方表格整理)。
  • 輸出參數:無
  • 返回值:無
  • 先決條件:無
  • 被調用函數:無

GPIO_ResetBits

  • 函數原型:void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
  • 功能:將端口重置為0。
  • 輸入參數1:GPIOx,選擇GPIO(詳細用法請見下方表格整理)。
  • 輸入參數2:GPIO_Pin,選擇GPIO_Pin(詳細用法請見下方表格整理)。
  • 輸出參數:無
  • 返回值:無
  • 先決條件:無
  • 被調用函數:無

RCC_APB2Periph描述
RCC_APB2Periph_AFIO复用功能
RCC_APB2Periph_GPIOAGPIO A
RCC_APB2Periph_GPIOBGPIO B
RCC_APB2Periph_GPIOCGPIO C
RCC_APB2Periph_GPIODGPIO D
RCC_APB2Periph_GPIOEGPIO E
RCC_APB2Periph_ADC1ADC1
RCC_APB2Periph_ADC2ADC2
RCC_APB2Periph_TIM1TIM1
RCC_APB2Periph_SPI1SPI1
RCC_APB2Periph_USART1USART1
RCC_APB2Periph_ALL全部

備註:可以用“|”符號(也就是OR運算)一次選取多個功能。例如:

1// 啟用Port-A、C時鐘
2RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |
3                       RCC_APB2Periph_GPIOC ,
4                       ENABLE);                   
NewState描述
ENABLE致能(使用)
DISABLE禁能(關閉)
GPIO_Pin描述
GPIO_Pin_0選擇Pin_0
GPIO_Pin_1選擇Pin_1
GPIO_Pin_2選擇Pin_2
GPIO_Pin_3選擇Pin_3
GPIO_Pin_4選擇Pin_4
GPIO_Pin_5選擇Pin_5
GPIO_Pin_6選擇Pin_6
GPIO_Pin_7選擇Pin_7
GPIO_Pin_8選擇Pin_8
GPIO_Pin_9選擇Pin_9
GPIO_Pin_10選擇Pin_10
GPIO_Pin_11選擇Pin_11
GPIO_Pin_12選擇Pin_12
GPIO_Pin_13選擇Pin_13
GPIO_Pin_14選擇Pin_14
GPIO_Pin_15選擇Pin_15
GPIO_Pin_All選擇全部

備註:可以用“|”符號一次選取多個功能。例如:

1GPIO_SetBits(GPIOA, GPIO_Pin_10 | GPIO_Pin_15); // 將PA10、PA15設置為1
GPIO_Speed描述
GPIO_Speed_10MHz設定最高輸出頻率為10MHz
GPIO_Speed_2MHz設定最高輸出頻率為2MHz
GPIO_Speed_50MHz設定最高輸出頻率為50MHz
GPIO_Mode描述
GPIO_Mode_AIN類比輸入
GPIO_Mode_IN_FLOATING浮空輸入
GPIO_Mode_IPD下拉輸入
GPIO_Mode_IPU上拉輸入
GPIO_Mode_Out_OD汲極開路通用輸出
GPIO_Mode_Out_PP推挽通用輸出
GPIO_Mode_AF_OD汲極開路复用輸出
GPIO_Mode_AF_PP推挽复用輸出


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

comments powered by Disqus