| 層級 |
方式 |
示例 |
難度 |
適合人群 |
| 高級 |
HAL 庫(CubeMX 默認(rèn)) |
HAL_GPIO_WritePin() |
? |
新手入門 |
| 中級 |
LL 庫(Low Layer) |
LL_GPIO_SetOutputPin() |
?? |
進(jìn)階者 |
| 底層 |
直接寄存器 |
GPIOA->ODR = (1 << 5); |
??? |
高級用戶 |
| 名稱 |
含義 |
| GPIOA |
代表 GPIOA 端口 |
| ODR |
Output Data Register,輸出數(shù)據(jù)寄存器 |
| 1 << 5 |
把第 5 位(PA5)置 1 |
| ` |
= ` |
HAL_Init();
SystemClock_Config(); // 已由 CubeMX 自動生成 72MHz 配置
MX_GPIO_Init();
while (1)
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET); // 設(shè)置高電平
HAL_Delay(500);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET); // 設(shè)置低電平
HAL_Delay(500);
}
GPIO 初始化MX_GPIO_Init()
系統(tǒng)時鐘SystemClock_Config()
CubeMX 中配置外部時鐘 + GPIO 步驟
![image]()
| 項目 |
當(dāng)前設(shè)置值 |
含義 & 作用 |
| GPIO output level |
High |
初始化時的默認(rèn)輸出電平,上電時默認(rèn)輸出高電平(VDD) |
| GPIO mode |
Output Push Pull |
輸出推挽模式(標(biāo)準(zhǔn)輸出) |
| GPIO Pull-up/Pull-down |
Pull-up |
內(nèi)部上拉電阻,使引腳在懸空時為高電平(對輸出口其實不起作用) |
| Maximum output speed |
Medium |
GPIO 切換速度為中等(約 10 MHz) |
| User Label |
LED |
給這個引腳設(shè)置標(biāo)簽(可讀性提升) |
官方定義說明(STM32 HAL 中):
#define GPIO_PIN_0 ((uint16_t)0x0001) // 1 << 0
#define GPIO_PIN_1 ((uint16_t)0x0002) // 1 << 1
...
#define GPIO_PIN_15 ((uint16_t)0x8000) // 1 << 15
注意這些宏是 uint16_t 類型,所以最多只能表達(dá) 16 位(即 PIN_0~15)。
GPIOA->ODR |= (1 << pin) 置高,或 GPIOA->ODR &= ~(1 << pin) 置低
| 31 … 16 |
15 … 0 |
| 復(fù)位位 Reset Bits |
設(shè)置位 Set Bits |
低 16 位(0~15 bit):將對應(yīng)引腳 置高電平(寫 1 有效)
高 16 位(16~31 bit):將對應(yīng)引腳 置低電平(寫 1 有效)
| 操作 |
寫入值 |
說明 |
| 設(shè)置 PA5 為高電平 |
GPIOA->BSRR = (1<<5) |
低 16 位 Bit5 寫 1 |
| 設(shè)置 PA5 為低電平 |
GPIOA->BSRR = (1<<21) |
高 16 位 Bit5 寫 1(5+16) |
GPIOx->BSRR = GPIO_PIN_0; // 置 GPIOx 的第 0 引腳為高電平
GPIOx->BSRR = (uint32_t)GPIO_Pin << 16u;
ODR 修改需要 讀 → 改 → 寫,中斷過程中可能打斷寫入操作。
BSRR 寫入是 一次完成、原子操作,不會影響其他引腳,適合高實時場景(如中斷、RTOS)
while (1)
{
GPIOA->BSRR = (1 << 5); // PA5 = 高
HAL_Delay(500); // 延時 500ms
GPIOA->BSRR = (1 << (5 + 16)); // PA5 = 低
HAL_Delay(500); // 延時 500ms
}
for i in range(16):
led_high = 1 << i
led_low = 1 << (i + 16)
print(f"GPIO_PIN_{i:>2}: SET=0x{led_high:08X} RESET=0x{led_low:08X}")
Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_gpio.h
| 宏定義名 |
說明 |
GPIO_MODE_INPUT |
輸入模式(默認(rèn)懸浮) |
GPIO_MODE_OUTPUT_PP |
推挽輸出(能主動拉高+拉低) |
GPIO_MODE_OUTPUT_OD |
開漏輸出(只能拉低) |
GPIO_MODE_AF_PP |
推挽復(fù)用功能(如 UART TX) |
GPIO_MODE_AF_OD |
開漏復(fù)用功能(如 I2C) |
GPIO_MODE_ANALOG |
模擬模式(ADC) |
GPIO_MODE_IT_RISING |
上升沿中斷輸入 |
GPIO_MODE_IT_FALLING |
下降沿中斷輸入 |
GPIO_MODE_IT_RISING_FALLING |
雙邊沿中斷輸入 |
MX_GPIO_Init() 函數(shù)
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOA_CLK_ENABLE(); //使能 GPIOA 時鐘
GPIO_InitStruct.Pin = GPIO_PIN_5;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; //推挽輸出模式
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); //初始化 PA5
開漏模式:LED 長腳(正極)連 GPIO 短腳(負(fù)極)連電阻 → GND
GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD; // 開漏輸出模式
GPIO_InitStruct.Pull = GPIO_PULLUP; // 內(nèi)部上拉電阻啟用
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
![image]()
時鐘選項
| 選項 |
含義 |
用于哪些功能 |
是否必須 |
| HSE (High Speed Clock) |
高速外部時鐘,通常為外接 8MHz 晶振 |
主系統(tǒng)時鐘(SYSCLK)、串口、USB、定時器等較精準(zhǔn)時鐘 |
? 推薦開啟(大部分板子通常帶 8MHz 晶振) |
| LSE (Low Speed Clock) |
低速外部時鐘,常為 32.768KHz 晶體 |
用于 RTC 實時時鐘、低功耗定時、日歷功能等 |
? 通常不需要(除非你用到 RTC) |
光敏電阻模塊引腳
| 引腳名 |
功能 |
| A0 |
模擬輸出(可選) |
| GND |
地線 |
| D0 |
數(shù)字輸出(高/低電平) |
| VCC |
電源(一般 3.3V 或 5V) |
有源蜂鳴器模塊引腳
| 蜂鳴器引腳 |
說明 |
連接到 STM32 小板 |
| VCC |
電源(3.3V 或 5V) |
3.3V 或 5V(建議用 5V) |
| GND |
地 |
GND |
| I/O |
控制引腳(低電平觸發(fā)) |
比如 PA0(GPIO 輸出) |
有源蜂鳴器模塊接線(低電平觸發(fā)型)
| 蜂鳴器模塊引腳 |
說明 |
接 STM32 小板 |
| VCC |
電源 |
5V(或 3.3V) |
| GND |
地 |
GND |
| I/O |
控制輸入 |
PA0(輸出) |
光敏電阻模塊接線(數(shù)字輸出 DO)
| 光敏模塊引腳 |
說明 |
接 STM32 小板 |
| VCC |
電源(建議 5V) |
5V |
| GND |
地 |
GND |
| D0 |
數(shù)字信號輸出(高/低) |
PA1(輸入) |
| A0 |
模擬輸出(可忽略) |
不接或接 ADC |
#include "main.h"
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
while (1)
{
// 如果檢測到低電平,說明環(huán)境變暗
if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1) == GPIO_PIN_RESET)
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET); // 蜂鳴器響
}
else
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET); // 蜂鳴器關(guān)閉
}
HAL_Delay(100); // 稍作延時
}
}
繼電器吸合:
#define RELAY_ON() HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET) // 低電平吸合
#define RELAY_OFF() HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET) // 高電平斷開
RELAY_ON(); // 吸合
HAL_Delay(1000);
RELAY_OFF(); // 斷開
HAL_Delay(1000);