欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

【stm32学习总结与浅谈】——GPIO

程序员文章站 2022-07-03 09:09:50
stm32学习总结与浅谈学习stm32已经一月有余,基本外设学过一遍了,然而回头看看遗,忘的东西太多太多,打算再从头整理一遍,写在这里。在自己巩固的同时给后来者一些便利,一些启迪。GPIO外设我们对Markdown编辑器进行了一些功能拓展与语法支持,除了标准的Markdown编辑器功能,我们增加了如下几点新功能,帮助你用它写博客:全新的界面设计 ,将会带来全新的写作体验;在创作中心设置你喜爱的代码高亮样式,Markdown 将代码片显示选择的高亮样式 进行展示;增加了 图片拖拽 功能,你可以将...

【 stm32学习总结与浅谈】  gpio篇
———————芯片基于stm32f103vet6————————

学习stm32已经一月有余,基本外设学过一遍了,然而回头看看遗忘的东西太多太多,打算再从头整理一遍。写在这里,在自己巩固的同时给后来者一些便利,一些启迪。

1.GPIO外设的介绍
  GPIO是通用输入输出端口的缩写,就是被stm32单片机所控制的引脚(类似于51单片机的IO口)。GPIO在单片机中扮演了非常重要的角色,它可以做普通的控制端口,也可以用于其他的功能,比如通信,采样(这些即后面要用到的复用功能)。基本上所有的GPIO都像51单片机一样有输入输出功能,但是也有一些GPIO我们专用于某一功能而不作为输入输出IO口。(例如下载端口,电源端口,晶振接口等)。

2.GPIO的结构图
【stm32学习总结与浅谈】——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工作模式

【stm32学习总结与浅谈】——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