Skip to content

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

發佈

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

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

// 基本輸出
#include "stm32f10x.h"
 
void Delay(__IO u32 nCount);
 
int main(void)
{
   RCC->APB2ENR |= 0x00000004; // 啟用GPIOA時鐘
   GPIOA->CRL = 0x00200000;    // 設定PA5為推挽輸出,最高輸出頻率為2MHz
   while(1)
   {
     GPIOA->ODR = 0X0020;      // PA5 = 1
     Delay(6400000);           // Delay
     GPIOA->ODR = 0X0000;      // PA5 = 0
     Delay(6400000);           // Delay
   }
}
 
void Delay(__IO u32 nCount)
{
   for (; nCount != 0; nCount--);
}
▲ 基本輸出-中間的綠色LED會不斷閃爍。
▲ 基本輸出-中間的綠色LED會不斷閃爍。
// 基本輸出
#include "stm32f10x.h"
 
int main(void)
{
   RCC->APB2ENR |= 0X00000044;  // 啟用GPIOA、GPIOE時鐘
   GPIOA->CRL = 0x00200000;     // 設定PA5為推挽輸出,最高輸出頻率為2MHz
   GPIOC->CRH = 0x00400000;     // 設定PC13為浮空輸入
 
   while(1)
   {
     if(GPIOC->IDR & 0x2000)    // if PC13 = 1
       GPIOA->ODR = 0X0020;     // PA5 = 1
     else
       GPIOA->ODR = 0X0000;     // PA5 = 0
   }
}
▲ 基本輸入-按下按鈕後中間的綠色LED熄滅,否則亮起。
▲ 基本輸入-按下按鈕後中間的綠色LED熄滅,否則亮起。

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

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

// 基本輸入-使用各種函數來達成
#include "stm32f10x.h"
 
int main(void)
{
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);    // 啟用GPIOA時鐘
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);    // 啟用GPIOC時鐘
 
    // 宣告一個GPIO_InitTypeDef類型的結構GPIO_InitStructure
    GPIO_InitTypeDef GPIO_InitStructure;
 
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;             // 使用Pin_5
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;      // 設定為推挽式輸出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;      // 設定最高輸出頻率為2MHz
    GPIO_Init(GPIOA, &GPIO_InitStructure); // 選為GPIO Port-A,傳入以上設定
 
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;            // 使用Pin_13
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; // 設定為浮空輸入
    GPIO_Init(GPIOC, &GPIO_InitStructure); // 選為GPIO Port-C,傳入以上設定
 
    while (1)
    {
        if(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_13) == 1) // if PC13 = 1
            GPIO_SetBits(GPIOA,GPIO_Pin_5);           // PA5 = 1
        else
            GPIO_ResetBits(GPIOA,GPIO_Pin_5);         // PA5 = 0
    }
}

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


RCC_APB2PeriphClockCmd


GPIO_Init


GPIO_ReadInputDataBit


GPIO_SetBits


GPIO_ResetBits


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運算)一次選取多個功能。例如:

// 啟用Port-A、C時鐘
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |
                       RCC_APB2Periph_GPIOC ,
                       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選擇全部

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

GPIO_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推挽复用輸出

把Seagate Personal Cloud改裝成USB外接硬碟
[STM32學習記錄-2] 基本輸入與輸出教學-GPIO相關暫存器簡介

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