做网站su软件,吉安律师网站建设,wordpress图片上加文字,动态手机网站怎么做的前段时间由于其他原因#xff0c;专栏暂停更新了较长一段时间#xff0c;现在恢复更新#xff0c;争取继续为大家创造有价值的内容#xff0c;期待大家的订阅关注#xff0c;欢迎互相学习交流。 在STM32速成笔记系列专栏中其实已经对GPIO的一些必要知识进行了介绍#xf… 前段时间由于其他原因专栏暂停更新了较长一段时间现在恢复更新争取继续为大家创造有价值的内容期待大家的订阅关注欢迎互相学习交流。 在STM32速成笔记系列专栏中其实已经对GPIO的一些必要知识进行了介绍但是如果我们想要深入了解GPIO的一些寄存器知识和各种输入输出模式还需要继续深入学习本文就让我们一起来深入学习GPIO的相关内容。 PS笔者能力有限文章如有错漏之处还请各位不吝赐教感谢大家的支持 文章目录 一、GPIO简介二、GPIO寄存器2.1 端口配置寄存器低/高2.2 端口输出寄存器2.3 端口设置/清除寄存器2.4 端口清除寄存器 三、硬件分析3.1 推挽输出3.2 开漏输出 四、程序分析 一、GPIO简介 每个GPI/O端口有两个32位配置寄存器(GPIOX CRLGPIOx CRH)两个32位数据寄存器(GPIOX IDR和GPIOx ODR)一个32位置位1复位寄存器(GPIOx BSRR)一个16位复位寄存器(GPIOx BRR)和一个32位锁定寄存器(GPIOx LCKR)。根据数据手册中列出的每个!/O端口的特定硬件特征GPIO端口的每个位可以由软件分别配置成多种模式。 每个I/O端口位可以自由编程然而I/O端口寄存器必须按32位字被访问(不允许半字或字节访问)。GPIOX BSRR和GPIOX BRR寄存器允许对任何GPIO寄存器的读/更改的独立访问:这样在读和更改访问之间产生IRQ时不会发生危险。 上面一段文字是STM32中文参考手册中对于GPIO功能的描述这有一个关键就是I/O寄存器必须按照32位来操作我们在看一些程序工程时可能会看到如下的宏定义
// SDA方向
#define MPU_SDA_IN() {GPIOB-CRL0X0FFFFFFF;GPIOB-CRL|(u32)828;}
#define MPU_SDA_OUT() {GPIOB-CRL0X0FFFFFFF;GPIOB-CRL|(u32)328;}这里也是严格按照32位来操作了GPIO关于上面两句具体是什么作用是怎么实现的我们下面随着学习的深入会一步一步来分析。
我们知道I/O有多种输入输出模式在STM32中文参考手册的GPIO功能描述部分给出了各种模式的配置方法 复位期间和刚复位后复用功能未开启I/O端口被配置成浮空输入模式复位后JTAG引脚会被配置成对应的输入输出模式。 在使用时需要注意们尽量不要使用这些引脚具体是哪些引脚以及如果必须使用这几个引脚改怎么办在STM32速成笔记专栏中有介绍这里就不再赘述了。 当作为输出配置时写到输出数据寄存器上的值(GPIOx_ODR)输出到相应的I/O引脚输入数据寄存器(GPIOx_IDR)在每个APB2时钟周期捕捉I/O引脚上的数据。
二、GPIO寄存器
我们这里介绍几个关键的GPIO寄存器
2.1 端口配置寄存器低/高
每一个GPIOx都有16个引脚0~15每一个GPIO引脚的输入输出配置需要4bit一个寄存器是32bit所以想要能配置16个引脚的输入输出模式需要两个GPIO配置寄存器所以在STM32参考手册中有高低之分低控制0到7高控制8到15我们只附一个GPIO配置寄存器低的图高的是类似的。 我们看到这里介绍的时候只给出了“上拉/下拉式输入模式”并没有说明怎么配置是上拉输入怎么配置是下拉输入这时我们可以结合上面的表格17来参考。 另外笔者在看的时候注意到“输入模式”后面写着“复位后的状态”导致笔者以为如果想从输出模式配置成输入模式需要复位操作后来明白这里的意思应该是引脚复位后的默认状态应该是浮空输入模式。 2.2 端口输出寄存器
结合GPIO配置寄存器和上面的表格加入我们想要配置一个GPIO的某各引脚为上拉输入模式我们需要配置它的CNFy[1:0]为10配置它的MODEy[1:0]为00还需要再配置ODR寄存器来确定是上拉输入模式而不是下拉我们来看一下端口数据输出寄存器GPIOx_ODR寄存器的描述。 2.3 端口设置/清除寄存器
我们想要配置成上拉输入模式需要将GPIOx_ODR对应位设置成1从上面对于ODR寄存器描述来看我们可以借助GPIOx_BSRR寄存器来单独操作ODR寄存器的值STM32参考手册中对于段端口位设置/清除寄存器GPIOx_BSRR的描述如下。 根据寄存器描述我们只需要将对应端口的BS位设置成1即可完成上拉输入模式的配置。
2.4 端口清除寄存器
除了可以通过上面的GPIOx_BSRR来清除对应的ODR位之外还提供了一个端口清楚寄存器GPIOx_BRR来单独清除和上面的GPIOx_BSRR的清除方法是一样的这里就不再做赘述了。 此外还有一个端口配置锁定寄存器(GPIOx_LCKR)这里也不做介绍了。 三、硬件分析
下面我们来简单分析一下端口配置成不同模式时的硬件电路从而更深的理解他们的区别这里之分析推挽式输出与开漏输出。在STM32中文参考手册中给出了输出的配置图并且针对推挽式输出和开漏输出给出了一些描述 开漏模式输出寄存器上的’0’激活N-MOS而输出寄存器上的’1’将端口置于高阻状态(PMOS从不被激活)。推挽模式输出寄存器上的’0’激活N-MOS而输出寄存器上的’1’将激活P-MOS。
如果只是从表面上来理解的话推挽式输出是具有实际输出能力的也就是说推挽式输出的高电平可以真正的驱动负载而开漏输出无法输出真正的高电平也就是说开漏输出的高电平是无法驱动负载的。 针对其中的细节电路已经有很多博主作了介绍由于笔者对于硬件不擅长所以就不露怯了指从表面上来分析一下推挽输出与开漏输出的区别。 我们单独把上图的输出驱动器部分摘出来看一下 3.1 推挽输出
我们先分析一下推挽式输出
当P-MOS打开N-MOS关闭时输出高电平电流会流出去这就叫“推” 当P-MOS关闭N-MMOS打开时输出低电平电流会流进来这就叫“挽”
3.2 开漏输出
下面我们再来看一下开漏输出端口配置为开漏输出时P-MOS一直处于关闭状态当N-MOS打开时输出高电平当N-MOS关闭时处于一个高阻态/浮空。我们既然已经有了推挽输出而且开漏输出还需要一个上拉电阻才能输出高电平那为什么还需要开漏输出呢下面我们就介绍一下开漏输出的用处。
首先第一个根据STM32中文参考手册中的描述在开漏模式时对输入数据寄存器的读访问可得到I/O状态也就是说如果我们把引脚初始化为开漏输出模式我们需要读取引脚输入时就不需要再把引脚配置成输入模式了。但是在推挽式模式时对输出数据寄存器的读访问得到最后一次写的值所以如果引脚配置的是推挽输出那么需要读取引脚数据时需要重新初始化成输入模式。开漏输出的这个特点对于在进行IIC通信或者其他共用数据线的总线通信中十分友好不需要重新初始化SDA引脚为输入模式也可以读取引脚数据。
第二个开漏输出可以用来匹配电平比如我们有一个单片机的引脚输出是5V但是我们的目标器件电压是3.3V此时我们可以初始化引脚为开漏输出外部接一个3.3V上拉电阻这样的话当我们的GPIO处于高阻态时输出端就会被上拉电阻拉到3.3V同理反过来也是一样的也就是说STM32的引脚配置成开漏输出外部接一个5V上拉电阻就能实现5V输出STM官方社区也给出了这个说明但是笔者没有尝试过所以大家请谨慎尝试。
第三呢就是可以支持几个设备同时挂接到同一条线上比如我们使用IIC通信有多个主设备时如果我们设置成推挽输出可能会导致主设备之间产生短路。
最后就是开漏输出能够实现线与操作什么是线与线与简单理解就是当一根总线上的设备输出全部为高电平时总线处于高电平状态一旦有一个设备的输出是低电平总线处于低电平状态。比如在IIC总线的仲裁机制就是通过线与逻辑实现的我们知道当主机要开启IIC通信时需要先发送一个起始信号也就是在SCL为高时将SDA拉高再拉低但是当IIC总线上有多个主设备时就需要有一个仲裁机制来判断谁先占用总线谁后占用总线。当主设备将SDA拉高后需要检查SDA的电平如果此时SDA电平为高说明主设备可以占用总线如果此时SDA电平为低说明总线已经被其他设备占用。
四、程序分析
最后我们说回来最开始介绍的两行代码
// SDA方向
#define MPU_SDA_IN() {GPIOB-CRL0X0FFFFFFF;GPIOB-CRL|(u32)828;}
#define MPU_SDA_OUT() {GPIOB-CRL0X0FFFFFFF;GPIOB-CRL|(u32)328;}对照上面的表格与寄存器我们可以知道第一行是将SDA配置成了下拉输入模式第二行是将SDA配置成了通用推挽输出模式对应的引脚是PB7。
我们从这个配置来说可以推测他在初始化IIC引脚是配置的是推挽输出模式所以需要不断地切换SDA引脚的输入输出状态不是很友好而且当总线上需要有多个主设备时会造成短路所以建议后续IIC引脚还是初始化成开漏输出模式。 笔者测试了一下使用STM32F103C8T6将引脚初始化为开漏输出模式后将引脚电平拉高用万用表测试引脚输出电平发现是低电平也就是说如果想在初始化时初始化为开漏输出必须要保证引脚外面要接一个上拉电阻否则无法正常进行IIC通信所以说在使用软件模拟IIC时如果没有多主机的需求还是建议初始化成推挽输出模式。