加入星計(jì)劃,您可以享受以下權(quán)益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴(kuò)散
  • 作品版權(quán)保護(hù)
  • 300W+ 專業(yè)用戶
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長(zhǎng)期合作伙伴
立即加入
  • 正文
  • 相關(guān)推薦
  • 電子產(chǎn)業(yè)圖譜
申請(qǐng)入駐 產(chǎn)業(yè)圖譜

RVMCU課堂「11」: 手把手教你玩轉(zhuǎn)RVSTAR—GPIO使用篇

2021/04/20
330
閱讀需 12 分鐘
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

GPIO是通用輸入輸出接口(General Purpose Input Output)的簡(jiǎn)稱,是微控制器最基本也是最常用的外設(shè),本期內(nèi)容將介紹GPIO的基本原理,然后通過(guò)「點(diǎn)亮LED」與「按鍵控制LED」兩個(gè)小實(shí)驗(yàn)帶領(lǐng)大家了解GPIO基本輸出與輸入功能的使用方法。

系統(tǒng)環(huán)境

Windows 10-64bit

軟件平臺(tái)

NucleiStudio IDE 202102版

PlatformIO IDE

硬件需求

RV-STAR開(kāi)發(fā)板

GPIO基本原理

GPIO的全稱是通用輸入輸出接口(General Purpose Input/Output),是很多外設(shè)能夠正常工作的基礎(chǔ),MCU上除了一些特定功能的引腳(如電源引腳)外,其他的引腳基本都可以作為GPIO來(lái)使用。

GD32VF103的GPIO端口以“組”的形式工作,命名方式為Px(x=A, B, C, D, E···),每組配置有16個(gè)引腳。GPIO端口和其他的備用功能(AFs)共用引腳,在特定的封裝下獲得最大的靈活性。

每個(gè)GPIO引腳都可以通過(guò)軟件配置為輸出(推挽或開(kāi)漏)、輸入、外設(shè)備用功能或者模擬模式。每個(gè)GPIO引腳都可以配置為上拉、下拉或浮空。除模擬模式外,所有的GPIO引腳都具備大電流驅(qū)動(dòng)能力。

(標(biāo)準(zhǔn)GPIO端口的基本結(jié)構(gòu))

GPIO具有下列特征:

輸入/輸出方向控制

施密特觸發(fā)器輸入功能使能控制

每個(gè)引腳都具有弱上拉/下拉功能

推挽/開(kāi)漏輸出使能控制

置位/復(fù)位輸出使能

可編程觸發(fā)沿的外部中斷——使用EXTI配置寄存器

模擬輸入/輸出配置

備用功能輸入/輸出配置

端口鎖定配置

實(shí)驗(yàn)1:點(diǎn)亮LED

RVSTAR有一個(gè)板載的RGB LED,通過(guò)PA1、PA2、PA3三個(gè)引腳控制LED_G、LED_R、LED_B三個(gè)顏色,通過(guò)原理圖可以得知:要點(diǎn)亮LED需要通過(guò)GPIO引腳輸出一個(gè)低電平,當(dāng)然也可以通過(guò)輸出PWM控制三個(gè)顏色LED的亮度,進(jìn)而組合產(chǎn)生不同的顏色。

下面將通過(guò)實(shí)驗(yàn)點(diǎn)亮LED_G,并令其以2秒為間隔閃爍:

(RGB LED原理圖 - 1)

(RGB LED原理圖 - 2)

首先參照之前的教程,使用NucleiStudio IDE或PlatformIO IDE創(chuàng)建工程,在main.c文件內(nèi)編寫(xiě)代碼如下:

/* 實(shí)驗(yàn)1:點(diǎn)亮LED */
#include "nuclei_sdk_hal.h"

void led_config();
void led_on();
void led_off();

int main(void)
{
                         // 首先對(duì)外設(shè)進(jìn)行初始化操作
    led_config();

    while (1)
    {
        led_on();        // 點(diǎn)亮LED
        delay_1ms(2000); // 延時(shí)2秒

        led_off();       // 熄滅LED
        delay_1ms(2000); // 延時(shí)2秒
    } 
}

void led_config()
{
    // 使能GPIOA端口的外設(shè)時(shí)鐘
    rcu_periph_clock_enable(RCU_GPIOA);
    // 將PA1初始化為推挽輸出模式
    gpio_init(GPIOA, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_1);
}

void led_on()
{
    // 將輸出引腳置位為0,輸出低電平,燈亮
    gpio_bit_reset(GPIOA, GPIO_PIN_1);
}

void led_off()
{
    // 將輸出引腳置位為1,輸出高電平,燈熄
    gpio_bit_set(GPIOA, GPIO_PIN_1);
}

然后將工程文件進(jìn)行編譯和上傳,將可以觀察到板載的綠色LED以2秒為間隔進(jìn)行閃爍。運(yùn)行結(jié)果如下:

實(shí)驗(yàn)2:按鍵控制LED

實(shí)驗(yàn)1我們使用了GPIO的輸出功能點(diǎn)亮了LED,實(shí)驗(yàn)2將帶領(lǐng)大家使用GPIO的輸入功能:用RVSTAR的板載按鍵控制LED的亮和滅,在使用它之前我們需要了解一點(diǎn)按鍵消抖的知識(shí)。

(按鍵的原理圖)

RVSTAR有一個(gè)板載的按鍵,連接到了MCU的PA1引腳上,按鍵沒(méi)按下時(shí),PA1引腳通過(guò)一個(gè)下拉電阻接地,處于低電平狀態(tài),按鍵按下時(shí)PA1引腳被拉高到3.3V,處于高電平狀態(tài)。由于按鍵是機(jī)械結(jié)構(gòu),在按下和彈起的瞬間會(huì)產(chǎn)生抖動(dòng),即引腳上的電平狀態(tài)不會(huì)被立刻拉高或拉低到穩(wěn)定狀態(tài),因此為了能夠準(zhǔn)確檢測(cè)用戶的按鍵操作,往往需要通過(guò)一定的方法進(jìn)行消抖處理:

常用的按鍵消抖方法有硬件消抖和軟件消抖:硬件消抖是通過(guò)在按鍵兩端增加電容的方式實(shí)現(xiàn)的,成本較高;而軟件消抖是在第一次檢測(cè)到電平變化后延時(shí)一定時(shí)間后再次檢測(cè)電平狀態(tài),如果檢測(cè)到仍處于按下時(shí)的電平狀態(tài),那么說(shuō)明用戶進(jìn)行了完整的按鍵操作,這個(gè)延時(shí)時(shí)間跟具體的硬件有關(guān),經(jīng)測(cè)試,在RVSTAR的按鍵上大約需要是設(shè)置100毫秒的延時(shí)比較合適。

使用NucleiStudio IDE或PlatformIO IDE創(chuàng)建工程,在main.c文件內(nèi)編寫(xiě)代碼如下:

/* 實(shí)驗(yàn)2:按鍵控制LED */
#include "nuclei_sdk_hal.h"

void led_config();
void led_on();
void led_off();

void key_config();
bit_status key_get_status();

bit_status led_status = 0; // 用來(lái)記錄led的當(dāng)前狀態(tài)

int main(void)
{
    led_config();
    key_config();
    led_off();

    while (1)
    {
             // 第一次檢測(cè)按鍵按下
        if(key_get_status() == SET)
        { 
            // 軟件延時(shí)100ms用以消除抖動(dòng)
            delay_1ms(100);
            // 再次檢測(cè)按鍵是否按下
            if(key_get_status() == SET)
            {
                switch (led_status)
                {
                case 0:
                    led_on(); 
                    break;
                case 1:
                    led_off();
                    break;
                default:
                    break;
                }
                led_status = !led_status; // 每次按鍵操作后切換led的狀態(tài)
            }
        }
    } 
}

void led_config()
{
    // 打開(kāi)GPIOA端口的外設(shè)時(shí)鐘
    rcu_periph_clock_enable(RCU_GPIOA);
    // 將PA1初始化為推挽輸出模式
    gpio_init(GPIOA, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_1);
}

void led_on()
{
    // 將輸出引腳置位為0,輸出低電平,燈亮
    gpio_bit_reset(GPIOA, GPIO_PIN_1);
}

void led_off()
{
    // 將輸出引腳置位為1,輸出高電平,燈熄
    gpio_bit_set(GPIOA, GPIO_PIN_1);
}

void key_config()
{
    rcu_periph_clock_enable(RCU_GPIOA); // 開(kāi)啟外設(shè)時(shí)鐘
    rcu_periph_clock_enable(RCU_AF); // 開(kāi)啟復(fù)用時(shí)鐘
    gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_0); // 將PA0初始化為浮空輸入模式
}

bit_status key_get_status()
{
    // 獲得輸入引腳的狀態(tài),其中bit_status是一個(gè)固件庫(kù)定義的枚舉類型
    return gpio_input_bit_get(GPIOA, GPIO_PIN_0);
}

然后將工程文件進(jìn)行編譯和上傳,將可以觀察到:上電后LED不亮,每次按下按鍵后LED的狀態(tài)會(huì)發(fā)生切換。

運(yùn)行結(jié)果如下:

相關(guān)推薦

電子產(chǎn)業(yè)圖譜

中國(guó)大陸首家專業(yè)RISC-V處理器內(nèi)核IP和解決方案公司,助力構(gòu)建RISC-V創(chuàng)新生態(tài),公司網(wǎng)址:https://www.nucleisys.com