GPIO:
全称 (General Purpose Input/Output),通用输入输出 GPIO是单片机与外部世界交互最基础、最直接的通道。在后面学习的串口通信,SPI总线,IIC总线,PWM控制电机,它们的物理信号都从GPIO引脚输出输入
从电路到编程模型

我们写代码就是往某个内存地址写了个数值,
然后这个值被硬件电路翻译成 MOS的导通/关断
一个蓝色小药丸 有48个引脚:VDD、VSS、VBAT、NRST、BOOT0、余GPIO GPIO分组:A~E,每组16个引脚,16正好是一个16位寄存器的宽度
引脚分组
把GPIO组映射到它在内存中的基地址
enum class GpioPort : uintptr_t { // enum class: 强枚举, uintptr_t: 平台指针宽度一致
A = GPIOA_BASE, // 0x40010800 ) 相差1KB
B = GPIOB_BASE, // 0x40010C00 )
C = GPIOC_BASE, // 0x40011000
D = GPIOD_BASE // 0x40011400
E = GPIOE_BASE, // 0x40011800
};
这些基地址之间间隔是 0x400 (1024字节),中间包含了7个寄存器
引脚和寄存器的关系
GPIOC : 0x40011000
CRL
32位寄存器,高 Pin7 ⇐- 低 Pin0 每4位中 低2位叫MODE:设置输入或输出速度(压摆率 (Slew Rate)电平响应快慢,上升下降沿是否陡峭) 高2位叫CNF:设置上拉?/推挽开漏?
CRH
与上同
IDR
输入数据寄存器,低16位有效记录电平状态
ODR
输出寄存器,操作非原子,直接控制电平 ↑ 不想被中断,所以设计了 BSRR 和 BRR
BSRR
低16位:往某位写1,对应ODR设为1,0无影响 高16位:往某位写1,对应ODR清零,0无影响 (原子操作)
BRR
低16位 写1清除 ODR对应位 (旧固件使用,现已冗余)
LCKR
锁定寄存器配置,对应位 CRL / CRH 无法修改 初始化后锁定,防止程序跑飞意外修改GPIO导致意外损坏 需按照特定的写入序列执行(防止跑飞的时候LCKR也被修改了)
GPIO的四种工作模式:
分别为输入、输出、复用功能、模拟模式,CRL,CRH设置
输入:
外部告诉单片机 外部信号电压 -⇒ 施密特触发器(Schmitt Trigger)进行整形-⇒输入数据寄存器IDR-⇒程序读取IDR得知
施密特触发器:把模拟信号变成数字信号,没有中间态 可以设置弱上拉下拉
输出:
分为推挽和开漏
推挽:驱动能力强

开漏:只可拉低,不可拉高,拉高要上拉电阻,IIC会用

复用功能:
让同一个物理引脚在不同时刻承担不同角色
当引脚设置为复用功能,引脚将交给对应的片上外设驱动
配置完成后,代码操作 UART 寄存器而不是 GPIO 寄存器
模拟模式
用于连接 ADC 和 DAC 施密特触发器被禁用,IDR不再更新(数字电路是干扰源,要关断) 信号 -⇒ 内部电路 -⇒ADC