IO端口位的基本结构
在STM32有特定功能的内存单元,即"寄存器"。寄存器是程序与硬件电路通信的桥梁。寄存器按照每32位二进制0/1数据为一组。存储着芯片特定电路的相关信息。我们就是通过程序对寄存器中的数据进行修改,可以改变某个电路的开关或者读写。控制单片机就是在控制寄存器
例如把PA7设置为高电平时,调用
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_7,GPIO_PIN_SEt)
函数实际上就是对BSRR寄存器的第七个bit位设置成1.
-
- void HAL_GPIO_WritePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState)
- {
- /* Check the parameters */
- assert_param(IS_GPIO_PIN(GPIO_Pin));
- assert_param(IS_GPIO_PIN_ACTION(PinState));
-
- if (PinState != GPIO_PIN_RESET)
- {
- GPIOx->BSRR = GPIO_Pin;
- }
- else
- {
- GPIOx->BSRR = (uint32_t)GPIO_Pin << 16u;
- }
- }
在输出驱动器中,有两个被输出控制模块控制的两个MOS(金氧半场效晶体管),分别时P_MOS和N-MOS。这两个可以简化为两个建议开关。 VDD提供3.3V的高电平,VSS提供0V的低电平。
假设I/O外连接一个工作电压为3.3V的小灯,小灯另一端接地。那么在推挽输出模式下,P_MOS和N-MOS协同工作.。
假设I/O外连接一个工作电压为5V的小灯,那么推挽输出怎样都无法使小灯亮起。在开楼模式下只有N-MOS工作,P-MOS一直处于断开状态。假设工作电压为5V的小灯在另外一端接入外部的5V的电势,VSS与5V形成电势差,那么小灯变可以亮起。开漏输出可以根据需求自行接入电压,更加灵活。
根据电路上显示,输出控制模块实际上有两个控制指令的来源。一个是我们使用HAL_GPIO_WritePin函数控制的输出寄存器。另一个来自于片上外设。比如串口模块,I²C模块等。由于同时控制将会使输出控制模块指令混乱。因此STM32将这两种输出模式由细分为
当电流从IO引脚接入时会经过一对上拉加拉电阻
电流继续往前走就会到达TTL肖特基(施密特)触发器。其作用是稳定电平。因为电流在实际应用中是会有波动的。如果在高低电平阈值附近上下波动,信号就会不断地变化造成不稳定。因此施密特触发器为了解决这个问题,分别设置了高电平阈值和低电平阈值。当处于低电平状态超过高电平阈值时就会变成高电平,当处于高电平时要低于低电平阈值时才会变成低电平。
最后电流通过施密特触发器便会进入到输入数据寄存器。等待我们用HAL_GPIO_ReadPin函数进行读取。
在读出数据这条"主线"电路中有两个分支,分别是模拟输入和复用功能输入。模拟输入分支在到施密特触发器前就叉出去了,没有经过高低电平的调整。因此模拟输入接入的是电压的具体数值。复用功能输入在片上外设上使用,其他功能和普通输入模式一样,拿到的都是调整后的高低电平。