GPIO:

← 返回 MOC | ← 主页


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

从电路到编程模型

1775610221477

我们写代码就是往某个内存地址写了个数值,

然后这个值被硬件电路翻译成 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得知

施密特触发器:把模拟信号变成数字信号,没有中间态 可以设置弱上拉下拉

输出:

分为推挽和开漏

推挽:驱动能力强

1775612683091

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

1775613102824

复用功能:

让同一个物理引脚在不同时刻承担不同角色 1775613499804 当引脚设置为复用功能,引脚将交给对应的片上外设驱动 配置完成后,代码操作 UART 寄存器而不是 GPIO 寄存器

模拟模式

用于连接 ADC 和 DAC 施密特触发器被禁用,IDR不再更新(数字电路是干扰源,要关断) 信号 - 内部电路 -ADC