【stm32学习总结与浅谈】——GPIO
【 stm32学习总结与浅谈】 gpio篇
———————芯片基于stm32f103vet6————————
学习stm32已经一月有余,基本外设学过一遍了,然而回头看看遗忘的东西太多太多,打算再从头整理一遍。写在这里,在自己巩固的同时给后来者一些便利,一些启迪。
1.GPIO外设的介绍
GPIO是通用输入输出端口的缩写,就是被stm32单片机所控制的引脚(类似于51单片机的IO口)。GPIO在单片机中扮演了非常重要的角色,它可以做普通的控制端口,也可以用于其他的功能,比如通信,采样(这些即后面要用到的复用功能)。基本上所有的GPIO都像51单片机一样有输入输出功能,但是也有一些GPIO我们专用于某一功能而不作为输入输出IO口。(例如下载端口,电源端口,晶振接口等)。
2.GPIO的结构图
3.GPIO硬件分析
<1>保护二极管及上、下拉电阻
引脚的两个保护二级管可以防止引脚外部过高或过低的电压输入,当引脚电压高于VDD时,上方的二极管导通, 当引脚电压低于Vss时,下方的二极管导通,防止不正常电压引入芯片导致芯片烧毁。尽管有这样的保护,并不意味着STM32的引脚能直接外接大功率驱动器件,如直接驱动电机,强制驱动要么电机不转,要么导致芯片烧坏,必须要加大功率及隔离电路驱动。
<2> P-MOS 管和N-MOS管
GPIO引脚线路经过两个保护二极管后,向上流向“输入模式”结构,向下流向“输出模式”结构。先看输出模式部分,线路经过一一个 由P-MOS和N-MOS管组成的单元电路。这个结构使GPIO具有了“推挽输出”和“开漏输出”两种模式。
所谓的推挽输出模式,是根据这两个MOS管的工作方式来命名的。在该结构中输入高电平时,经过反向后,上方的P-MOS导通,下方的N-MOS关闭,对外输出高电平;而在该结构中输入低电平时,经过反向后,N-MOS管导通,P-MOS关闭,对外输出低电平。当引脚高低电平切换时,两个管子轮流导通,P管负责灌电流,N管负责拉电流,使其负载能力和开关速度都比普通的方式有很大的提高。推挽输出的低电平为0伏,高电平为3.3伏。而在开漏输出模式时,上方的 P-MOS管完全不工作。如果我们控制输出为0,低电平,则P-MOS管关闭,N-MOS 管导通,使输出接地,若控制输出为1 (它无法直接输出高电平)时,则P-MOS管和N-MOS管都关闭,所以引脚既不输出高电平,也不输出低电平,为高阻态。为正常使用时必须外部接上拉电阻。
推挽输出模式一般应用在输出电平为0和3.3伏而且需要高速切换开关状态的场合。在STM32的应用中,除了必须用开漏模式的场合,我们都习惯使用推挽输出模式。
开漏输出一般应用在IC、SMBUS 通讯等需要“线与”功能的总线电路中。除此之外,还用在电平不匹配的场合,如需要输出5伏的高电平,就可以在外部接一一个 上拉电阻,上拉电源为5伏,并且把GPIO设置为开漏模式,当输出高阻态时,由上拉电阻和电源向外输出5伏的电平。
<3>输出数据寄存器
前面提到的双MOS管结构电路的输入信号,是由GPIO“输出数据寄存GPIOx_ ODR”提供的,因此我们通过修改输出数据寄存器的值就可以修改GPIO引脚的输出电平。而“置位/复位寄存器GPIOx_ BSRR"可以通过修改输出数据寄存器的值从而影响电路的输出。
<4>复用功能输出
“复用功能输出”中的“复用”是指STM32的其它片上外设对GPIO引脚进行控制,此时GPIO引脚用作该外设功能的一部分,算是第二用途。从其它外设引出来的“复用功能输出信号”与GPIO本身的数据据寄存器都连接到双MOS管结构的输入中,通过图中的梯形结构作为开关切换选择。例如我们使用USART串口通讯时,需要用到某个GPIO引脚作为通讯发送引脚,这个时候就可以把该GPIO引脚配置成USART串口复用功能,由串口外设控制该引脚,发送数据。
<5>输入数据寄存器
看 GPIO结构框图的上半部分,GPIO引脚经过内部的上、下拉电阻,可以配置成上/下拉输入,然后再连接到施密特触发器,信号经过触发器后,模拟信号转化为0、1的数字信号。
<6>复用功能输入
与“复用功能输出”模式类似,在“复用功能输入模式”时,GPI0 引脚的信号传输到STM32其它片上外设,由该外设读取引脚状态。同样,如我们使用USART串口通讯时,需要用到某个GPIO引脚作为通讯接收引脚,这个时候就可以把该GPIO引脚配置成USART串口复用功能,使USART可以通过该通讯引脚的接收远端数据。
<7>模拟输入输出
当GPI0引脚用于ADC采集电压的输入通道时,用作“模拟输入”功能,此时信号是不经过施密特触发器的,因为经过施密特触发器后信号只有0、1两种状态,所以ADC外设要采集到原始的模拟信号,信号源输入必须在施密特触发器之前。类似地,当GPIO引脚用于DAC作为模拟电压输出通道时,此时作为“模拟输出”功能,DAC的模拟信号输出就不经过双MOS管结构,模拟信号直接输出到引脚。
4. GPIO工作模式
5. GPIO初始化结构体讲解
void GPIO_Config()
{
GPIO_InitTypeDef GPIO_InitStructure;//建立初始化结构体
RCC_APB2PeriphClockCmd (GPIO_PortSourceGPIOA,ENABLE); //打开GPIOA的时钟
GPIO_InitStructure.GPIO_Pin = GPIO_PinSource0;//选择要控制的引脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_pp;//选择输出模式
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//选择引脚输出速率
GPIO_Init(GPIOA,&GPIO_InitStructure);//初始化函数,把结构体参数写入函数
/*
GPIO_PortSourceGPIOA:GPIOX的某一组端口
GPIO_PinSource0:GPIOX的某个引脚
*/
}
完成这些,意味着gpio已经准备妥当可以供使用,这一步相当于准备工作。stm32操作外设第一步做的就是打开该外设的时钟。无论什么操作这一步必不可少。
6. GPIO主要输出与读取函数讲解
Stm32输出高电平函数
void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
Stm32输出低电平函数
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
Stm32单片机的整个IO进行复位操作
void GPIO_DeInit(GPIO_TypeDef* GPIOx)
GPIO初始化函数
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)
对GPIO端口某一位进行写操作
void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal);
对GPIO端口某一组进行写操作
void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);
对GPIO端口某一位输入IO口进行读操作
uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
对GPIO端口某一组输入IO口进行读操作
uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx)
读取GPIO端口某一位输出的状态
uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
读取GPIO端口某一组输出的状态
uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx)
注:记住这些函数即可,其余的日常基本上不会用到。
7. GPIO全部库函数
1.void GPIO_DeInit(GPIO_TypeDef* GPIOx);
2.void GPIO_AFIODeInit(void);
3.void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);
4.void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct);
5.uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
6.uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx);
7.uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
8.uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);
9.void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
10.void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
11.void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal);
12.void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);
13.void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
14.void GPIO_EventOutputConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);
15.void GPIO_EventOutputCmd(FunctionalState NewState);
16.void GPIO_PinRemapConfig(uint32_t GPIO_Remap, FunctionalState NewState);
17.void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);
18.void GPIO_ETH_MediaInterfaceConfig(uint32_t GPIO_ETH_MediaInterface);
本文地址:https://blog.csdn.net/yunshengbixiao/article/details/108549849
推荐阅读
-
Python中的with语句与上下文管理器学习总结
-
Oracle索引(B*tree与Bitmap)的学习总结
-
前端框架学习总结之Angular、React与Vue的比较详解
-
重新学习MySQL数据库6:浅谈MySQL的中事务与锁
-
浅谈html5与APP混合开发遇到的问题总结
-
荐 14天数据分析与机器学习实践之Day02——数据分析处理库Pandas应用总结
-
MyBatis学习总结(二)——MyBatis核心配置文件与输入输出映射
-
Linux Shell 常用命令与目录分区的学习总结
-
JavaScript学习总结(一) ECMAScript、BOM、DOM(核心、浏览器对象模型与文档对象模型)
-
“5G芯片、终端的创新发展与集成电路产业战略思考“学习总结