GD32F103學習筆記(4)——GPIO接口使用

一交煞、簡介

最多可支持112個通用I/O引腳(GPIO),分別為PA0 ~ PA15斟或,PB0 ~ PB15素征,PC0 ~ PC15,PD0 ~ PD15缕粹,PE0 ~ PE15稚茅,PF0 ~ PF15和PG0 ~ PG15,各片上設備用其來實現(xiàn)邏輯輸入/輸出功能平斩。每個GPIO端口有相關的控制和配置寄存器以滿足特定應用的需求亚享。外設GPIO引腳上的外部中斷在中斷/事件控制器(EXTI)中有相關的控制和配置寄存器。GPIO端口和其他的備用功能(AFs)共用引腳绘面,在特定的封裝下獲得最大的靈活性欺税。GPIO引腳通過配置相關的寄存器可以用作備用功能引腳,備用功能輸入/輸出都可揭璃。每個GPIO引腳可以由軟件配置為輸出(推挽或開漏)晚凿、輸入、外設的備用功能或者模擬模式瘦馍。每個GPIO引腳都可以配置為上拉歼秽、下拉或無上拉/下拉。除模擬模式外情组,所有的GPIO引腳都具備大電流驅動能力燥筷。

二、API說明

2.1 外設寄存器說明

GPIO寄存器列表如下表所示:

寄存器名稱 寄存器描述
GPIOx_CTL0 端口控制寄存器0
GPIOx_CTL1 端口控制寄存器1
GPIOx_ISTAT 端口輸入狀態(tài)寄存器
GPIOx_OCTL 端口輸出狀態(tài)寄存器
GPIOx_BOP 端口位操作寄存器
GPIOx_BC 位清除寄存器
GPIOx_LOCK 端口配置鎖定寄存器
AFIO_EC 事件控制寄存器
AFIO_PCF0 AFIO端口配置寄存器0
AFIO_EXTISS0 EXTI源選擇寄存器0
AFIO_EXTISS1 EXTI源選擇寄存器1
AFIO_EXTISS2 EXTI源選擇寄存器2
AFIO_EXTISS3 EXTI源選擇寄存器3
AFIO_PCF1 AFIO端口配置寄存器1

2.2 外設庫函數(shù)說明

以下 GPIO 接口位于 GD32F10x_Firmware_Library_V2.2.2\Firmware\GD32F10x_standard_peripheral\Include\gd32f10x_gpio.h院崇。

2.2.1 gpio_init

功能 GPIO參數(shù)初始化肆氓。注意:首先要保證使用的GPIO的時鐘開啟
函數(shù)定義 void gpio_init(uint32_t gpio_periph,uint32_t mode,uint32_t speed,uint32_t pin)
參數(shù) gpio_periph:GPIO端口x(x = A,B,C,D,E,F,G)
mode:GPIO引腳模式
speed:GPIO輸出最大速度最大
pin:GPIO引腳x(x=0..15)
返回

mode: IO模式,在GD32標準固件庫中底瓣,共有四種輸入模式谢揪,四種輸出模式,詳細列表如下:

含義 官方解釋
GPIO_MODE_AIN 模擬輸入 analog input mode
GPIO_MODE_IN_FLOATING 浮空輸入 floating input mode
GPIO_MODE_IPD 下拉輸入 pull-down input mode
GPIO_MODE_IPU 上拉輸入 pull-up input mode
GPIO_MODE_OUT_OD 開漏輸出 GPIO output with open-drain
GPIO_MODE_OUT_PP 推挽輸出 GPIO output with push-pull
GPIO_MODE_OUT_OD 復用開漏輸出 AFIO output with open-drain
GPIO_MODE_OUT_PP 復用推挽輸出 AFIO output with push-pull

speed: IO輸出速度最大值捐凭,詳細列表如下:

含義 官方解釋
GPIO_OSPEED_10MHZ 輸出速度最大為10MHz output max speed 10MHz
GPIO_OSPEED_2MHZ 輸出速度最大為2MHz output max speed 2MHz
GPIO_OSPEED_50MHZ 輸出速度最大為50MHz output max speed 50MHz

2.2.2 gpio_bit_set

功能 將一個GPIO引腳拉高
函數(shù)定義 void gpio_bit_set(uint32_t gpio_periph, uint32_t pin)
參數(shù) gpio_periph:GPIO端口x(x = A,B,C,D,E,F,G)
pin:GPIO引腳x(x=0..15)
返回

2.2.3 gpio_bit_reset

功能 將一個GPIO引腳拉低
函數(shù)定義 void gpio_bit_reset(uint32_t gpio_periph, uint32_t pin)
參數(shù) gpio_periph:GPIO端口x(x = A,B,C,D,E,F,G)
pin:GPIO引腳x(x=0..15)
返回

2.2.4 gpio_bit_write

功能 將特定值寫入引腳
函數(shù)定義 void gpio_bit_write(uint32_t gpio_periph, uint32_t pin, bit_status bit_value)
參數(shù) gpio_periph:GPIO端口x(x = A,B,C,D,E,F,G)
pin:GPIO引腳x(x=0..15)
bit_value:SET設置或RESET清除
返回

2.2.5 gpio_input_bit_get

功能 獲取引腳的輸入值
函數(shù)定義 FlagStatus gpio_input_bit_get(uint32_t gpio_periph,uint32_t pin)
參數(shù) gpio_periph:GPIO端口x(x = A,B,C,D,E,F,G)
pin:GPIO引腳x(x=0..15)
返回 SET高電平或RESET低電平

2.2.6 gpio_pin_remap_config

功能 配置GPIO引腳重映射
函數(shù)定義 void gpio_pin_remap_config(uint32_t remap, ControlStatus newvalue)
參數(shù) remap:選擇重映射
newvalue:是否使能拨扶,ENABLE使能或DISABLE除能
返回

remap: 重映射,詳細列表如下:

含義
GPIO_SPI0_REMAP SPI0重映射
GPIO_I2C0_REMAP I2C0重映射
GPIO_USART0_REMAP USART0重映射
GPIO_USART1_REMAP USART1重映射
GPIO_USART2_PARTIAL_REMAP USART2部分重映射
GPIO_USART2_FULL_REMAP USART2全部重映射
GPIO_TIMER0_PARTIAL_REMAP TIMER0部分重映射
GPIO_TIMER0_FULL_REMAP TIMER0全部重映射
GPIO_TIMER1_PARTIAL_REMAP0 TIMER1部分重映射
GPIO_TIMER1_PARTIAL_REMAP1 TIMER1部分重映射
GPIO_TIMER1_FULL_REMAP TIMER1全部重映射
GPIO_TIMER2_PARTIAL_REMAP TIMER2部分重映射
GPIO_TIMER2_FULL_REMAP TIMER2全部重映射
GPIO_TIMER3_REMAP TIMER3重映射
GPIO_PD01_REMAP PD01重映射
GPIO_CAN_PARTIAL_REMAP CAN部分重映射(僅適用于GD32F10X_MD茁肠,GD32F10X_HD和GD32F10X_XD)
GPIO_CAN_FULL_REMAP CAN全部重映射(僅適用于GD32F10X_MD患民,GD32F10X_HD和GD32F10X_XD)
GPIO_SPI2_REMAP SPI2重映射(僅適用于GD32F10X_CL)
GPIO_TIMER4CH3_IREMAP TIMER4 channel3內部重映射(僅適用于GD32F10X_CL和GD32F10X_HD)
GPIO_ADC0_ETRGINS_REMAP ADC0外部觸發(fā)注入轉換重映射(僅適用于GD32F10X_MD,GD32F10X_HD和GD32F10X_XD)
GPIO_ADC0_ETRGREG_REMAP ADC0外部觸發(fā)規(guī)則轉換重映射(僅適用于GD32F10X_MD官套,GD32F10X_HD和GD32F10X_XD)
GPIO_ADC1_ETRGINS_REMAP ADC1外部觸發(fā)注入轉換重映射(僅適用于GD32F10X_MD酒奶,GD32F10X_HD和GD32F10X_XD)
GPIO_ADC1_ETRGREG_REMAP ADC1外部觸發(fā)規(guī)則轉換重映射(僅適用于GD32F10X_MD蚁孔,GD32F10X_HD和GD32F10X_XD)
GPIO_SWJ_NONJTRST_REMAP 全部的SWJ(JTAG-DP + SW-DP),但是不包括NJTRST
GPIO_SWJ_SWDPENABLE_REMAP JTAG-DP除能惋嚎,SW-DP使能
GPIO_SWJ_DISABLE_REMAP JTAG-DP除能杠氢,SW-DP除能
GPIO_CAN0_PARTIAL_REMAP CAN0部分重映射(僅適用于GD32F10X_CL)
GPIO_CAN0_FULL_REMAP CAN0全部重映射(僅適用于GD32F10X_CL)
GPIO_ENET_REMAP ENET重映射(僅適用于GD32F10X_CL)
GPIO_CAN1_REMAP CAN0重映射(僅適用于GD32F10X_CL)
GPIO_TIMER1ITI1_REMAP TIMER1內部觸發(fā)1重映射(僅適用于GD32F10X_CL)
GPIO_PTP_PPS_REMAP 以太網(wǎng)PTP PPS重映射(僅適用于GD32F10X_CL)
GPIO_TIMER8_REMAP TIMER8重映射
GPIO_TIMER9_REMAP TIMER9重映射
GPIO_TIMER10_REMAP TIMER10重映射
GPIO_TIMER12_REMAP TIMER12重映射
GPIO_TIMER13_REMAP TIMER13重映射
GPIO_EXMC_NADV_REMAP EXMC_NADV 連接/斷開

三、GPIO輸出

3.1 引腳確定

我使用的是 光子MINI-GD32F103RCT6 開發(fā)板

有個 IO 口為 PB4 的 LED 燈



在復位期間或復位之后另伍,備用功能并未激活鼻百,所有GPIO端口都被配置成輸入浮空模式,這種輸入模式禁用上拉(PU)/下拉(PD)電阻摆尝。但是復位后温艇,串行線調試端口(JTAG/Serial-Wired Debug pins)為輸入PU/PD模式:
PA15:JTDI為上拉模式;
PA14:JTCK / SWCLK為下拉模式堕汞;
PA13:JTMS / SWDIO為上拉模式勺爱;
PB4:NJTRST為上拉模式;
PB3:JTDO為浮空模式讯检。

所以PB4要當GPIO需要重映射

//管腳復用時鐘使能
rcu_periph_clock_enable(RCU_AF);
//PB4管腳默認是NJTRST琐鲁,要當GPIO,需要重映射
gpio_pin_remap_config(GPIO_SWJ_NONJTRST_REMAP, ENABLE)

3.2 編程要點

  1. 使能 GPIO 端口時鐘
  2. 初始化 GPIO 目標引腳為推挽輸出
  3. 控制 GPIO 引腳輸出高人灼、低電平

3.3 外設寄存器方法

//GPIOB時鐘使能
rcu_periph_clock_enable(RCU_GPIOB);
//配置GPIO端口
gpio_init(GPIOB, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_4);

//引腳輸出低電平
GPIO_BC(GPIOB) = GPIO_PIN_4;
//引腳輸出高電平
GPIO_BOP(GPIOB) = GPIO_PIN_4;

3.4 外設庫函數(shù)方法

//GPIOB時鐘使能
rcu_periph_clock_enable(RCU_GPIOB);
//PB4配置成輸出
gpio_init(GPIOB, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_4);

//引腳輸出低電平
gpio_bit_reset(GPIOB, GPIO_PIN_4);
//引腳輸出高電平
gpio_bit_set(GPIOB, GPIO_PIN_4);
//引腳輸出低電平
gpio_bit_write(GPIOB, GPIO_PIN_4, RESET);
//引腳輸出高電平
gpio_bit_write(GPIOB, GPIO_PIN_4, SET);

四围段、GPIO輸入

4.1 引腳確定

我使用的是 光子MINI-GD32F103RCT6 開發(fā)板

有個 IO 口為 PA1 的按鍵



4.2 編程要點

  1. 使能 GPIO 端口時鐘
  2. 初始化 GPIO 目標引腳為輸入模式(由于硬件電路沒有外部上拉電阻,這里使用內部上拉輸入)
  3. 檢測按鍵的狀態(tài)

4.3 外設庫函數(shù)方法

//GPIOA時鐘使能
rcu_periph_clock_enable(RCU_GPIOA);
//PA1配置成上拉輸入
gpio_init(GPIOA, GPIO_MODE_IPU, GPIO_OSPEED_50MHZ, GPIO_PIN_1);

//讀取引腳電平
gpio_input_bit_get(GPIOA, GPIO_PIN_1);

五投放、輪詢讀取按下按鍵奈泪,LED燈閃爍

5.1 board_gpio.c

/*********************************************************************
 * INCLUDES
 */
#include "gd32f10x.h"

#include "board_gpio.h"

/*********************************************************************
 * PUBLIC FUNCTIONS
 */
/*=========================================================================*/
/*                                   輸入                                  */
/*=========================================================================*/
/**
 @brief 按鍵驅動初始化
 @param 無
 @return 無
*/
void Key_GPIO_Init(void)
{
    // GPIO時鐘使能
    rcu_periph_clock_enable(RCU_GPIOA);
    // 配置為內部上拉輸入模式
    gpio_init(KEY1_GPIO_PORT, GPIO_MODE_IPU, GPIO_OSPEED_50MHZ, KEY1_GPIO_PIN);
}

/**
 @brief 獲取按鍵狀態(tài)
 @param keyNum -[in] 按鍵編號
 @return 1 - 按下;0 - 松開
*/
uint8_t Key_GPIO_Read(uint8_t keyNum)
{
    uint8_t value = 0;

    if(KEY1 == keyNum)
    {
        value = gpio_input_bit_get(KEY1_GPIO_PORT, KEY1_GPIO_PIN);
    }
//    else if(KEY2 == keyNum)
//    {
//        value = gpio_input_bit_get(KEY2_GPIO_PORT, KEY2_GPIO_PIN);
//    }

    return value;
}

/*=========================================================================*/
/*                                   輸出                                  */
/*=========================================================================*/
/**
 @brief LED燈驅動初始化
 @param 無
 @return 無
*/
void LED_GPIO_Init(void)
{
    // PB4管腳默認是NJTRST灸芳,要當GPIO涝桅,需要重映射
    rcu_periph_clock_enable(RCU_AF);                                    // 管腳復用時鐘使能
    gpio_pin_remap_config(GPIO_SWJ_NONJTRST_REMAP, ENABLE);
    
    // GPIO時鐘使能
    rcu_periph_clock_enable(RCU_GPIOB);
    // 配置為推挽輸出模式
    gpio_init(LED1_GPIO_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, LED1_GPIO_PIN);

    LED_GPIO_Write(LED1, LED_OFF);
}

/**
 @brief 配置LED燈工作模式
 @param ledNum -[in] LED燈編號
 @param ledMode -[in] 工作模式
 @return 無
*/
void LED_GPIO_Write(uint8_t ledNum, uint8_t ledMode)
{
    if(LED1 == ledNum)
    {
        gpio_bit_write(LED1_GPIO_PORT, LED1_GPIO_PIN, ledMode);
    }
//    else if(LED2 == ledNum)
//    {
//        gpio_bit_write(LED2_GPIO_PORT, LED2_GPIO_PIN, ledMode);
//    }
}

/**
 @brief 獲取LED燈工作模式
 @param ledNum -[in] LED燈編號
 @return 工作模式
*/
uint8_t LED_GPIO_Read(uint8_t ledNum)
{
    uint8_t ledMode = 0;
    if(LED1 == ledNum)
    {
        ledMode = gpio_output_bit_get(LED1_GPIO_PORT, LED1_GPIO_PIN);
    }
//    else if(LED2 == ledNum)
//    {
//        ledMode = gpio_output_bit_get(LED2_GPIO_PORT, LED2_GPIO_PIN, &ledMode);
//    }
    return ledMode;
}

5.2 board_gpio.h

#ifndef _BOARD_GPIO_H_
#define _BOARD_GPIO_H_

/*********************************************************************
 * INCLUDES
 */
#include "gd32f10x_gpio.h"
 
/*********************************************************************
 * DEFINITIONS
 */
/*=========================================================================*/
/*                                   輸入                                  */
/*=========================================================================*/
#define KEY1_GPIO_PORT                  GPIOA
#define KEY1_GPIO_PIN                   GPIO_PIN_1
#define KEY_OFF                         0x01
#define KEY_ON                          0x00
#define KEY1                            1
#define KEY2                            2

/*=========================================================================*/
/*                                   輸出                                  */
/*=========================================================================*/
#define LED1_GPIO_PORT                  GPIOB
#define LED1_GPIO_PIN                   GPIO_PIN_4
#define LED_OFF                         0x01
#define LED_ON                          0x00
#define LED1                            1
#define LED2                            2

/*********************************************************************
 * API FUNCTIONS
 */
void Key_GPIO_Init(void);
uint8_t Key_GPIO_Read(uint8_t keyNum);

void LED_GPIO_Init(void);
void LED_GPIO_Write(uint8_t ledNum, uint8_t ledMode);
uint8_t LED_GPIO_Read(uint8_t ledNum);

#endif /* _BOARD_GPIO_H_ */

5.3 main.c

#include "gd32f10x.h"
#include "systick.h"

#include "board_gpio.h"

int main(void)
{
    systick_config();//系統(tǒng)主頻108MHZ,采用外部晶振,由兩個宏決定(__SYSTEM_CLOCK_108M_PLL_HXTAL與HXTAL_VALUE)
    
    Key_GPIO_Init();// 按鍵模塊初始化
    LED_GPIO_Init();// LED燈模塊初始化
    
    while(1)
    {
        if(KEY_ON == Key_GPIO_Read(KEY1))
        {
            delay_1ms(100);//等待100ms
            LED_GPIO_Write(LED1, LED_ON);
            delay_1ms(100);//等待100ms
            LED_GPIO_Write(LED1, LED_OFF);
        }
    }
}

5.4 工程代碼

百度網(wǎng)盤:https://pan.baidu.com/s/1_tjTeP_xVNC-KdVDLbN-Ww?pwd=0h8m 提取碼:0h8m


? 由 Leung 寫于 2022 年 4 月 12 日

? 參考:GD32F103基礎教程—GPIO輸出實驗(五)
    GD32實戰(zhàn)3__點亮LED燈

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市耗绿,隨后出現(xiàn)的幾起案子苹支,更是在濱河造成了極大的恐慌砾隅,老刑警劉巖误阻,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異晴埂,居然都是意外死亡究反,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進店門儒洛,熙熙樓的掌柜王于貴愁眉苦臉地迎上來精耐,“玉大人,你說我怎么就攤上這事琅锻∝酝#” “怎么了向胡?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長惊完。 經(jīng)常有香客問我僵芹,道長,這世上最難降的妖魔是什么小槐? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任拇派,我火速辦了婚禮,結果婚禮上凿跳,老公的妹妹穿的比我還像新娘件豌。我一直安慰自己,他們只是感情好控嗜,可當我...
    茶點故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布茧彤。 她就那樣靜靜地躺著,像睡著了一般疆栏。 火紅的嫁衣襯著肌膚如雪棘街。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天承边,我揣著相機與錄音遭殉,去河邊找鬼。 笑死博助,一個胖子當著我的面吹牛险污,可吹牛的內容都是我干的。 我是一名探鬼主播富岳,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼蛔糯,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了窖式?” 一聲冷哼從身側響起蚁飒,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎萝喘,沒想到半個月后淮逻,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡阁簸,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年爬早,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片启妹。...
    茶點故事閱讀 39,696評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡捞奕,死狀恐怖啄清,靈堂內的尸體忽然破棺而出曲横,到底是詐尸還是另有隱情,我是刑警寧澤车胡,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站照瘾,受9級特大地震影響吨拍,放射性物質發(fā)生泄漏。R本人自食惡果不足惜网杆,卻給世界環(huán)境...
    茶點故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一羹饰、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧碳却,春花似錦队秩、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至关噪,卻和暖如春鸟蟹,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背使兔。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工建钥, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人虐沥。 一個月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓熊经,卻偏偏與公主長得像,于是被迫代替她去往敵國和親欲险。 傳聞我的和親對象是個殘疾皇子镐依,可洞房花燭夜當晚...
    茶點故事閱讀 44,592評論 2 353

推薦閱讀更多精彩內容