前一篇文章是第一次學會如何使用 GPIO 來控制 LED 的亮與滅:STM32筆記(15):使用 GPIO 控制紅綠燈 ,本篇將繼續使用 GPIO ,就由讀取 GPIO 的狀態來判斷按鍵是否被按下? 同時瞭解一下函式的用法。
讀取 IO 輸入引腳的值。
- 引數 GPIOx:對應的 GPIO,範圍是 GPIOA ~ GPIOG。
- 引數 GPIO_Pin:引腳編號,可以是GPIO_Pin_0 ~ GPIO_Pin_15 及 GPIO_Pin_All。
返回值:傳回一個 unit8_t 輸出管腳的值,僅有兩種狀態 Bit_SET(高電位),Bit_RESET(低電位)
✈ GPIO_ReadInputData(GPIO_TypeDef* GPIOx)
讀取 IO 輸入的資料,該函式用於讀取一個 GPIOx 分組的所有資料。
- 引數 GPIOx:對應的 GPIO,範圍是 GPIOA ~ GPIOG。
返回值:一個 GPIOx 的所有資料(輸入狀態),也就是一組 16 位元的值。
✈ GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx , uint16_t GPIO_Pin)
讀取 IO 輸出引腳的值。
- 引數 GPIOx:對應的 GPIO,範圍是 GPIOA ~ GPIOG。
- 引數 GPIO_Pin:引腳編號,可以是GPIO_Pin_0 ~ GPIO_Pin_15 及 GPIO_Pin_All。
返回值:傳回一個 unit8_t 輸出管腳的值,僅有兩種狀態 Bit_SET(高電位),Bit_RESET(低電位)
✈ GPIO_ReadOutputData(GPIO_TypeDef* GPIOx)
讀取 IO 輸出的資料,該函式用於讀取一個 GPIOx 分組的所有資料。
- 引數 GPIOx:對應的 GPIO,範圍是 GPIOA ~ GPIOG。
返回值:一個 GPIOx 的所有資料(輸出狀態),也就是一組 16 位元的值。
[常用的GPIO函式(續)]
✈ GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx , uint16_t GPIO_Pin)讀取 IO 輸入引腳的值。
- 引數 GPIOx:對應的 GPIO,範圍是 GPIOA ~ GPIOG。
- 引數 GPIO_Pin:引腳編號,可以是GPIO_Pin_0 ~ GPIO_Pin_15 及 GPIO_Pin_All。
返回值:傳回一個 unit8_t 輸出管腳的值,僅有兩種狀態 Bit_SET(高電位),Bit_RESET(低電位)
✈ GPIO_ReadInputData(GPIO_TypeDef* GPIOx)
讀取 IO 輸入的資料,該函式用於讀取一個 GPIOx 分組的所有資料。
- 引數 GPIOx:對應的 GPIO,範圍是 GPIOA ~ GPIOG。
返回值:一個 GPIOx 的所有資料(輸入狀態),也就是一組 16 位元的值。
✈ GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx , uint16_t GPIO_Pin)
讀取 IO 輸出引腳的值。
- 引數 GPIOx:對應的 GPIO,範圍是 GPIOA ~ GPIOG。
- 引數 GPIO_Pin:引腳編號,可以是GPIO_Pin_0 ~ GPIO_Pin_15 及 GPIO_Pin_All。
返回值:傳回一個 unit8_t 輸出管腳的值,僅有兩種狀態 Bit_SET(高電位),Bit_RESET(低電位)
✈ GPIO_ReadOutputData(GPIO_TypeDef* GPIOx)
讀取 IO 輸出的資料,該函式用於讀取一個 GPIOx 分組的所有資料。
- 引數 GPIOx:對應的 GPIO,範圍是 GPIOA ~ GPIOG。
返回值:一個 GPIOx 的所有資料(輸出狀態),也就是一組 16 位元的值。
[材料]
- STM32F103C8T6 主板 x 1
- OLED SSD1306 顯示器 x1
- 麵包板 x1
- LED x 1 個
- 按鍵 x 1 個
- STLINK V2 模擬下載器 x 1
- 連接線 x N 條
[接線與電路圖]
LED 正極(長腳)接到 3.3v,另一腳接在 STM32F103 的 PA0,按鍵的一個接腳接在 GND,另一腳接在 PB14。STM32F103x 連接 SSD1306 方式如下:STM32F103x | SSD1306 OLED | 按鍵 |
---|---|---|
3.3v | VDD | - |
GND | GND | 其中一個 Pin |
B8 | SCK/SCL | - |
B9 | SDA | - |
B14 | - | 另一個 Pin |
[程式]
主程式一開始先對 OLED 進行初始化,再設定一個引腳 GPIO 連接 LED 燈,進入迴圈循環時,執行定義在 Button.c 檔案中的 Button_Press() ,如果按下,傳回 KeyNum 值,然後判斷 KeyNum 來決定是否讓 LED 燈亮或滅。主程式 main.c 如下:#include "stm32f10x.h" #include "stm32f10x_rcc.h" #include "stm32f10x_gpio.h" #include "delay.h" #include "sys.h" #include "oled.h" #include "bmp.h" #include "button.h" uint8_t KeyNum; int main (void) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //開啟GPIOA的外設時鐘 GPIO_InitTypeDef GPIO_InitStruct; // 定義一個GPIO_InitTypeDef類型的結構體 GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0; //選擇要控制的GPIOA引腳 GPIO_InitStruct.GPIO_Speed = GPIO_Speed_2MHz; //設置引腳速率為2MHz GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; //設置引腳為通用推輓輸出模式 GPIO_Init(GPIOA, &GPIO_InitStruct); //調用庫函數,初始化GPIOA5引腳 // 將引腳設為高電位 GPIO_SetBits(GPIOA, GPIO_Pin_0); delay_init(); //延時函數初始化 OLED_Init(); //初始化OLED Button_Init2(); OLED_Clear(0); //清除螢幕 OLED_ShowString(2, 2, "Status:",16); while (1) { KeyNum = Button_Press(); if (KeyNum == 1) { GPIO_ResetBits(GPIOA, GPIO_Pin_0); // 點亮 LED OLED_ShowString(60, 2, "On ",16); } else { GPIO_SetBits(GPIOA, GPIO_Pin_0); // 熄滅 LED OLED_ShowString(60, 2, "Off",16); } } }Button.c 有兩個主要函式:
- Button_Init2(void)是初始化按鍵 GPIO。
- Button_Press(void)是讀取 GPIO 的狀態,判斷按鍵是否被按下?
#include "stm32f10x.h" // Device header #include "delay.h" void Button_Init2(void) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); } uint8_t Button_Press(void) { extern uint8_t KeyNum; // KeyNum 定義為全域變數 if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14) == 0) { delay_ms(20); while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14) == 0); //迴圈等到按鍵被按下 delay_ms(20); KeyNum = !KeyNum; } return KeyNum; }button.h 的內容如下:
#ifndef __BUTTON_H #define __BUTTON_H void Button_Init2(void); uint8_t Button_Press(void); #endif完整的程式請參考 Github:3. Push button control led using GPIO
張貼留言