![image]()
編碼器與 STM32F103 引腳連接
| 編碼器引腳 |
STM32F103 引腳 |
說明 |
| VCC |
3.3V |
供電 |
| GND |
GND |
地 |
| CLK(A) |
PA0 |
EXTI0,中斷輸入,上拉 |
| DT(B) |
PA2 |
普通輸入,上拉(不需要中斷) |
| SW(按鍵) |
PA3 |
EXTI3,中斷輸入,上拉 |
OLED 與 STM32F103 引腳連接
| OLED 引腳 |
STM32F103 引腳 |
說明 |
| VCC |
3.3V |
電源 |
| GND |
GND |
地 |
| SCL |
PB8 |
軟件 I2C SCL |
| SDA |
PB9 |
軟件 I2C SDA |
CubeMX 配置要點
- PA0:GPIO_Input + EXTI0,觸發 Rising/Falling(雙沿),Pull-up。
- PA2:GPIO_Input,Pull-up。
- PA3:GPIO_Input + EXTI3,觸發 Falling(按鍵接地),Pull-up。
- 使能 EXTI0/EXTI3 中斷(NVIC 里勾選)。
- OLED 用 I2C1(PB8/PB9)。
encoder.h
#include "encoder.h"
volatile int32_t encoder_count = 0;
volatile uint8_t encoder_button_clicked = 0;
#define ENC_A_Port GPIOA
#define ENC_A_Pin GPIO_PIN_0 // CLK
#define ENC_B_Port GPIOA
#define ENC_B_Pin GPIO_PIN_2 // DT
#define ENC_SW_Port GPIOA
#define ENC_SW_Pin GPIO_PIN_3 // SW
// 若方向反了,改為 1
#define ENC_REVERSE 0
void Encoder_Init(void) { /* 空實現:GPIO/EXTI 由 CubeMX 生成 */ }
/* HAL 的 EXTI 回調:任一外部中斷都會進來 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if (GPIO_Pin == ENC_A_Pin) // A 相邊沿到來,讀 B 相判斷方向
{
GPIO_PinState b = HAL_GPIO_ReadPin(ENC_B_Port, ENC_B_Pin);
#if ENC_REVERSE
if (b == GPIO_PIN_SET) encoder_count--;
else encoder_count++;
#else
if (b == GPIO_PIN_SET) encoder_count++;
else encoder_count--;
#endif
}
else if (GPIO_Pin == ENC_SW_Pin) // 按鍵:簡單消抖
{
static uint32_t last = 0;
uint32_t now = HAL_GetTick();
if (now - last > 20) { // 20ms 去抖
if (HAL_GPIO_ReadPin(ENC_SW_Port, ENC_SW_Pin) == GPIO_PIN_RESET) {
encoder_button_clicked = 1; // 單擊標志
}
}
last = now;
}
}
main.c
#include "encoder.h"
#include "oled.h"
#include <stdio.h>
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_I2C1_Init(); // 你已有
OLED_Init();
OLED_Clear();
Encoder_Init(); // 可選
char line[16];
int32_t last = 0;
while (1)
{
if (encoder_count != last) {
last = encoder_count;
sprintf(line, "Cnt:%-6ld", (long)last);
OLED_ShowString(2, 1, " ");
OLED_ShowString(2, 1, line);
}
if (encoder_button_clicked) {
encoder_button_clicked = 0;
OLED_ShowString(3, 1, "Button!");
HAL_Delay(150);
OLED_ShowString(3, 1, " ");
}
HAL_Delay(5);
}
}