目录
前言
如下图所示就是stm32的I/O端口位的基本结构:
这个框图实现了stm32单片机I/O口的8种工作方式,以此来完成它的通信,数据传输,端口驱动,外设扩展,可以说大部分的作业都离不开它。
一、GPIO功能及寄存器概述
每个GPI/O端口有两个32位配置寄存器(GPIOx_CRL,GPIOx_CRH),两个32位数据寄存器 (GPIOx_IDR和GPIOx_ODR),一个32位置位/复位寄存器(GPIOx_BSRR),一个16位复位寄存 器(GPIOx_BRR)和一个32位锁定寄存器(GPIOx_LCKR)。
每个I/O端口位可以自由编程,然而必须按照32位字访问I/O端口寄存器(不允许半字或字节访 问)。GPIOx_BSRR和GPIOx_BRR寄存器允许对任何GPIO寄存器进行读/更改的独立访问;这 样,在读和更改访问之间产生IRQ时不会发生危险。
二、GPIO的8种工作模式
根据数据手册中列出的每个I/O端口的特定硬件特征,GPIO端口的每个位可以由软件分别配置成 多种模式。
- 浮空输入
- 上拉输入
- 下拉输入
- 模拟输入
- 开漏输出
- 推挽输出
- 复用推挽
- 复用开漏
浮空输入
浮空输入的结构原理如下:
由上图可见,浮空输入模式的上拉下拉电阻都断开,所以电平信号直接进入输入数据寄存器,也就是说输入电平状态是不确定的,时刻由外部输入来决定。如果在该引脚悬空(在无信号输入)的情况下,读取该端口的电平是不确定的。所以一般读取外部电平信号时通常配置为浮空输入。
简要介绍下这个肖特基触发器(TTL):外界输入的电平信号是复杂多样的,但是单片机只能识别两种信号,0和1即高电平和低电平,肖特基触发器的作用就是把多样的信号通过阈值判断的方法归为高电平和低电平两类,然后传给输入数据寄存器。例如,如果阈值电压是1.15v,那么输入的电平信号中大于1.15v的都会判定为高电平,而小于1.15v的都会判定为低电平。
这里说一下前面的保护电路:
这个保护电路是针对所有输入模式的,包括浮空输入,上拉输入,下拉输入,模拟输入,它的工作原理也很简单,当输入的电压超过VDD+二极管的导通电压时,上面的保护二极管就会导通,在电压差的作用下电流会顺着二极管流走从而保护单片机。同理当输入的电压过低时,下面的保护二极管也会导通来平衡压差。
上拉输入
上拉输入的结构原理如下:
在上拉输入模式下,上拉电阻开关闭合,默认状态下I/O端口保持高电平,当输入低电平时,输入端的电压会被拉低,这样的作用是能识别端口的低电平,最典型的例子就是按键,一般按键都是低电平触发,I/O端口配置为上拉输入可以判断是否有低电平到来,从而判断按键是否按下。
下拉输入
下拉输入的结构原理如下:
下拉输入模式原理与上拉相同,工作方式刚好和上拉模式相反。下拉电阻开关闭合,默认状态下I/O端口保持低电平,可以识别高电平的到来。举例:一些外部中断是通过I/O口的高电平触发。
模拟输入
模拟输入的结构原理如下:
在模拟输入模式中,I/O端口的模拟信号(电压信号,而非电平信号)直接模拟输入到片上外设模块,比如ADC模块。所以模拟输入不会通过肖特基触发器。
推挽输出
推挽输出的结构原理如下:
推挽输出也叫强推输出,通过设置位设置/清除寄存器或者输出数据寄存器的值,控制P-MOS管和N-MOS管的导通来控制IO口输出高电平还是低电平。例如串口的输出一般都是推挽输出。
复用推挽输出
复用推挽输出的结构原理如下:
推挽复用输出模式,与推挽输出模式很是类似。只是输出的高低电平的来源,不是让CPU直接写输出数据寄存器,取而代之利用片上外设模块的复用功能输出来决定的。一些I/O会复用映射到片上外设的寄存器上,其依然拥有通用I/O的功能。
开漏输出
开漏输出的结构原理如下:
当配置为开漏输出模式时,P-MOS管将不起作用,设置输出的值为高电平时,N-MOS关闭,此时I/O端口的电平就不会由输出的高低电平决定,而是由I/O端口外部的上拉或者下拉决定。设置输出的值为低电平时,N-MOS管导通并输出低电平。所以开漏输出模式通常要在外部加上拉电阻。可以理解为开漏输出是一种强下拉的输出方式,典型的例子就是stm32软件I2C的时序模拟。
复用开漏输出
复用开漏输出的结构原理如下:
开漏复用输出模式,与开漏输出模式很是类似。只是输出的高低电平的来源,不是让CPU直接写输出数据寄存器,取而代之利用片上外设模块的复用功能输出来决定的。
三、代码(标准库)
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOx, ENABLE); //开启APB2外设时钟
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode =;//GPIO_Mode_IN_FLOATING 浮空输入 、GPIO_Mode_IPU 上拉输入、GPIO_Mode_IPD 下拉输入、GPIO_Mode_AIN 模拟输入、
//GPIO_Mode_Out_PP 推挽输出、GPIO_Mode_AF_PP 复用推挽输出、GPIO_Mode_Out_OD 开漏输出、GPIO_Mode_AF_OD 复用开漏输出
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_xx; //GPIO_Pin_0~15
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_xxMHz;//GPIO_Speed_10MHz、GPIO_Speed_2MHz、GPIO_Speed_50MHz
GPIO_Init(GPIOC, &GPIO_InitStructure);
总结
stm32 I/O的掌握对于理解微机控制,通信与驱动外设至关重要。
喜欢单片机的同学可以留下你的赞和关注,持续更新更多嵌入式技术文章ing~
(才疏学浅,不吝赐教)