输入:I/O引脚进入接两个保护二极管,一个接VDD(高于从这个引脚出), 一个接VSS(低于GND从这个引脚进)使输入电压在VDD-VSS之间;进入连接了一个上拉电阻和下拉电阻,控制上拉输入和下拉输入,两个阻值较大,弱拉
施密特触发器:使输入电压高于上限或者低于下限时输出高或者低,在中间状态时不变,避免因为信号波动造成的输出抖动现象
最后写入输入数据寄存器,以及复用功能输入(数字量在其后面,连接到其他需要读取端口的外设上,例如串口等),模拟输入不经过施密特触发器直接接出(模拟量)
输出:数字部分可以由输出数据寄存器(同时控制16个端口且只能整体读写,单独控制某一个端口不影响其他端口用位设置/清除寄存器)或者片上外设控制(复用功能输出),两种控制方式通过数据选择器连接到输出控制部分,之后接到两个MOS管可以设置
推挽:P/N-MOS均有效,数据寄存器为1 时,上管导通下管断开,输出直接接到VDD,输出为高,数据寄存器为0 时,上管断开下管导通,输出直接接到VSS,输出为低;这样直接接到高低电平,有较强的驱动能力,也称为强推挽输出,这种模式下,STM32对IO口有绝对控制权,高低电平由32说了算
开漏:P-MOS无效,只有N-MOS在工作,数据寄存器为1 时,下管断开,输出断开,为高阻模式,数据寄存器为0 时,下管导通,输出直接接到VSS,输出为低;高电平无驱动能力;可以作为通信协议的驱动方式(IIC),开漏模式还可以做输出5V的电平信号(在IO口外接一个上拉电阻到5V的电源:寄存器为0输出VSS,寄存器为1,输出5V)
关闭:两个MOS管均无效,输出关闭,端口信号由外部控制)
浮空输入:端口要接上一个连续的驱动源,不能出现悬空的状态
输入模式下,输出无效;输出模式下,输入有效;一个端口只能有一个输出,但可以有多个输入
复用输出:引脚电平由片上外设控制,输入部分,片上外设也可以读取引脚电平,普通输入有效,可以接收电平信号
除了模拟输入模式会关闭数字输入功能,其他模式中,输入都是有效的
调试方式:显示屏调试,单步运行,断点调试,点灯调试,注释调试,对照法
GPIO输出实例:流水灯
void LED_Init(void)
{
RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 |
GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7 ;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_Write(GPIOC, ~0x0000);
}
void LED_FlowColors(void)
{
GPIO_Write(GPIOC, ~0x0001);
Delay_ms(500);
GPIO_Write(GPIOC, ~0x0002);
Delay_ms(500);
GPIO_Write(GPIOC, ~0x0004);
Delay_ms(500);
GPIO_Write(GPIOC, ~0x0008);
Delay_ms(500);
GPIO_Write(GPIOC, ~0x0010);
Delay_ms(500);
GPIO_Write(GPIOC, ~0x0020);
Delay_ms(500);
GPIO_Write(GPIOC, ~0x0040);
Delay_ms(500);
GPIO_Write(GPIOC, ~0x0080);
Delay_ms(500);
}
GPIO输入实例:按键检测
#define Key_GPIO GPIOB
#define Key1_PIN GPIO_Pin_10
#define Key2_PIN GPIO_Pin_11
void Key_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Pin = Key1_PIN | Key2_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(Key_GPIO, &GPIO_InitStructure);
}
uint8_t Key_GetNum(void)
{
uint8_t KeyNum = 0;
if(GPIO_ReadInputDataBit(Key_GPIO, Key1_PIN) == 0)
{
Delay_ms(20);
while(GPIO_ReadInputDataBit(Key_GPIO, Key1_PIN) == 0);
KeyNum = 1;
}
if(GPIO_ReadInputDataBit(Key_GPIO, Key2_PIN))
{
Delay_ms(20);
while(GPIO_ReadInputDataBit(Key_GPIO, Key1_PIN) == 0);
KeyNum = 2;
}
return KeyNum;
}