高低电平:GPIO引脚电平范围:0V~3.3V(部分引脚可容忍5V)数据0就是0V,代表低电平;数据1就是3.3V,代表高电平;
STM32是32位的单片机,所以内部寄存器也都是32位的(这里联想到32位机器操作64位数据,比如int64/double数据,需要2个寄存器保存一个数据,计算效率很低);
GPIO在输出模式下可控制端口输出高低电平,用以驱动LED、控制蜂鸣器、模拟通信协议输出时序等;
GPIO在输入模式下可读取端口的高低电平或电压,用于读取按键输入、外接模块电平信号输入、ADC电压采集、模拟通信协议接收数据等(最常见的读取按键);
STM32中,所有的GPIO都是挂载在APB2总线上的,命名规则以GPIOA、GPIOB等;每个GPIO外设有16个引脚,编号0~15,一般称为PA0~PA15或PB0~PB15;
这里GPIOA中有一个寄存器,对应的只有16个引脚,所以这个寄存器只有低16位对应的有端口,高16位是没有用到的;
驱动器是用来增加信号的驱动能力的,寄存器只负责存储数据,比如说要实现点灯能力的时候,还是需要驱动器增大驱动能力的;
左边三个寄存器,中间是驱动器,右边是某一个I/O的引脚;整体可以分为两个部分,上面是输入部分,下面是输出部分;
保护二极管是对输入电压进行限幅的,VDD-3.3V、VSS-0V,如果I/O引脚的输入电压大于3.3V,那么上方的保护二极管就会导通,输入电压产生的电流会直接流入VDD,不会流入内部电路;如果输入电压小于0V,下方的二极管就会导通,电流会从VSS流向I/O引脚,防止内部电流汲取电流,保护电路;
上拉电阻和下拉电阻开关,这个是可以通过程序配置的:上面导通、下面断开就是上拉输入,上面断开、下面导通就是下拉输入模式,两个都断开就是浮空输入模式;
上拉和下拉是为了给输入提供一个默认的电平,如果输入引脚什么都不接,那么就不知道这个时候是算高电平还是低电平,就处于了浮空状态,受到一点扰动就会变化;上拉输入:默认高电平的输入方式,下拉输入:默认低电平的输入方式;
施密特触发器:对输入电压进行转换,当输入的电压大于某个阈值时,输出会瞬间升为高电平,当输入电压小于某个阈值时,输出会瞬间降为低电平;只有在输入高于上限或者低于下限的时候,输出电平才会变化(输入信号可能会失真,波形不稳定)经过施密特触发器整型的波形就可以直接写入输入数据寄存器了,用程序读取寄存器某一个位的数据,就知道对应端口的输入电平了;
通过程序对输出数据寄存器写入数据,就能操控对应断开的高低电平;
有三种方式,一种是读取输出寄存器里的数据,通过位运算的方式改变某一位的值,改变对应端口的高低电平,这效率比较低,对于IO操作不太合适;第二种方式就是使用位设置/清楚寄存器,在位设置寄存器的某一位写1,其他位写0,内部电路就会自动将输出寄存器中对应位置1,其他写0的位保持原数据不变;如果想清0某一位,就对改位写0,其他位写1;第三种方式。。。
推挽输出模式下输出控制根据输出寄存器中的数据,控制P-MOS/N-MOS的断开,输出高电平或者低电平,这种模式下输出由STM32强控制;
开漏输出模式下P-MOS完全断开,只有N-MOS能控制,数据位为1时,N-MOS断开,输出为高阻模式,是高电平,数据位为0是,N-MOS接通,接入VSS低电平,输出为低电平;这种模式下只有低电平有驱动能力,高电平是没有驱动能力的(I2C用的就是开漏输出模式,多机通信的情况下,可以避免各个设备之间的干扰);
关闭输出模式下只有输入,没有输出;
通过程序配置,可以设置GPIO为以下8种模式(配置上面的一些硬件电路)
输入模式下,输出驱动器是断开的,端口只能输入不能输出;
模拟输入时,GPIO是无效的,引脚直接接入内部ADC,输出是断开的,输入的施密特触发器是关闭状态,从引脚直接接入ADC
输出都是用输出寄存器中的数据控制的;输出模式下,输入模块是有效的,一个端口可以有多个输入,但是只能有一个输出
开漏下高电平时是高阻态,没有电流,也没有驱动能力;
控制输出模块直接接入片上外设,和内部数据寄存器是断开的,由片上外设控制