第三章第三节 GPIO 输入
1. 按键介绍
① 假设没按下高电平,按下低电平。
② 按键抖动:由于按键内部使用的是机械式弹簧片来进行通断的,所以在按下和松手的瞬间会伴随有一连串的抖动。如图所示,按下按键后,从高电平变为低电平,之后又有瞬间恢复到高电平。
2. 传感器模块介绍
① 传感器元件的电阻会随着外界模拟量的变化而变化,通过与定值电阻分压即可得到模拟电压输出,再通过电压比较器进行二值化即可得到数字电压输出。
② 电路图分析
这是一个基于 LM393 电压比较器实现的二值化电路,主要用于将输入的模拟信号(A0)转换为数字信号(高电平或低电平,D0),并带有电源指示和输出状态指示功能。
核心芯片:LM393(U1)
(1) 这是一个双路电压比较器芯片(虽然图中只画了一路),它内部有两个独立的比较器。
(2) 比较器的基本功能:比较 IN+(同相输入端)和 IN-(反向输入端)的电压:
- 当 IN+ > IN- 时,输出端 OUT 为 高电平(接近 VCC)
- 当 IN+ < IN- 时,输出端 OUT 为 低电平(接近 GND)
(3) 关键特性:LM393 的输出是 “开漏” 结构。这意味者它的输出内部相当于一个连接到地的开关(当输出低时闭合),但当输出时,内部是断开的(高阻态)。因此,要输出真正的高电平,必须在输出端和 VCC 之间连接一个 “上拉电阻”。图中 R5(10k)就是这个作用。
- 当比较器判定 IN+ > IN- 时,这个晶体管完全截止(关断),输出端与地之间是高阻态(开路)。此时,输出端本身无法主动输出高电平(VCC)。
- R5 一端连接到 VCC,另一端连接到 LM393 的输出端 N1/D0。当 LM393 内部输出晶体管关断(高阻态)时,R5 为 N1/D0 点提供了一个到 VCC 的电路路径。此时,几乎没有电流流过 R5,N1/D0 点的电压被上拉到接近 VCC 的电压。
(4) 判断是否是上拉电阻的方法:
- 电阻一端固定连接电源(VCC、VDD、VBAT等)
- 电阻另一端连接信号线 / 芯片引脚
3. 硬件电路
①为何必须使用上拉模式?(一般用上面两种方法)
(1) 当按键未按下时:
- PA0 引脚悬空(无外部电路驱动)
- 若无上拉电阻 → 引脚电压不确定
(2) 启用内部上拉后:
- 悬空时被自动拉高到 3.3V(高电平)
- 按键按下时直接接地(低电平)
必须牢记:“悬空引脚必须拉,有源驱动不用拉”
4. C 语言数据类型
① STM32 中的 int 是 32 位,而 51 的 int 只有 16 位
② STM32 中的 int 和 long 都是 32 位!这与 PC 编程不同(Linux/Windows中 long 都是 64 位)
5. C语言结构体
① 一般使用 typedef 创建类型别名(在 STM32 HAL库中,所有外设寄存器都使用 typedef 定义结构体)
typedef struct { char x; int y; float z;
} StructName_t; // 定义类型别名StructName_t a; // 声明该类型的变量
组成部分 | 说明 |
typedef | 关键字,表示要定义类型别名 |
struct { ... } | 定义匿名结构体类型 |
StructName_t | 类型别名(_t 是类型命名惯例) |
StructName_t s; | 使用新类型声明变量 |
② 示例:
// 定义LCD显示配置
typedef struct {uint8_t backlight; // 背光亮度 0-100uint16_t text_color; // 文字颜色 RGB565uint16_t bg_color; // 背景颜色 RGB565uint8_t font_size; // 字体大小uint8_t rotation; // 屏幕旋转 0-3
} LCD_Config_t;// 使用
LCD_Config_t display_cfg = {.backlight = 80,.text_color = 0xFFFF, // 白色.bg_color = 0x001F, // 蓝色.font_size = 16,.rotation = 0
};void update_display() {LCD_SetBacklight(display_cfg.backlight);LCD_SetColors(display_cfg.text_color, display_cfg.bg_color);LCD_SetFontSize(display_cfg.font_size);LCD_SetRotation(display_cfg.rotation);
}