前一篇文章是第一次學會如何使用 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

張貼留言