datasheet

STM32学习笔记一一GPIO

2019-01-09来源: eefocus 关键字:STM32  GPIO

1. GPIO工作方式

STM32 每个 IO 口可以自由编程,但 IO 口寄存器必须要按 32 位字被访问。 本文主要是库函数实现的笔记。相关图片来自正点原子教程。


1.1 4种输入模式

输入浮空 输入上拉 输入下拉 模拟输入


a.输入浮空



CPU可以通过输入数据寄存器读出I/O口的高低电平,工作电路如图。


b.上拉下拉输入:添加了上拉、下拉电阻后,CPU再读电平



c.模拟输入



输入量为模拟量,不再是电平,输入的电压范围:0—3.3V


1.2 4种输出模式

开漏输出 开漏复用功能 推挽式输出 推挽式复用功能


a. 开漏输出



开漏输出:输出端相当于三极管的集电极. 要得到高电平状态需要上拉电阻才行。适合于做电流型的驱动,其吸收电流的能力相对强(一般 20ma 以内)。


开漏是用来连接不同电平的器件,匹配电平用的,因为开漏引脚不连接外部的上拉电阻时,只能输出低电平,如果需要同时具备输出高电平的功能,则需要接上拉电阻,很好的一个优点是通过改变上拉电源的电压,便可以改变传输电平。


b. 推挽输出



推挽输出:可以输出高,低电平,连接数字器件; 推挽结构一般是指两个三极管分别受两互补信号的控制,总是在一个三极管导通的时候另一个截止。高低电平由 IC 的电源决定。


推挽电路是两个参数相同的三极管或MOSFET,以推挽方式存在于电路中,各负责正负半周的波形放大任务,电路工作时,两只对称的功率开关管每次只有一个导通,所以导通损耗小、效率高。输出既可以向负载灌电流,也可以从负载抽取电流。推拉式输出级既提高电路的负载能力,又提高开关速度。


(2) 8 个模式定义


GPIO_Mode_AIN = 0x0, //模拟输入 

GPIO_Mode_IN_FLOATING = 0x04, //浮空输入 

GPIO_Mode_IPD = 0x28, //下拉输入 

GPIO_Mode_IPU = 0x48, //上拉输入 

GPIO_Mode_Out_OD = 0x14, //开漏输出 

GPIO_Mode_Out_PP = 0x10, //通用推挽输出 

GPIO_Mode_AF_OD = 0x1C, //复用开漏输出 

GPIO_Mode_AF_PP = 0x18 //复用推挽


STM32 的 IO 口位配置表如下



(3)IO口速度定义


GPIO_Speed_10MHz = 1, 

GPIO_Speed_2MHz, 

GPIO_Speed_50MHz


STM32 输出模式配置:




I/O口输出速度是指I/O口驱动电路的响应速度而不是输出信号的速度,输出信号的速度与程序有关(芯片内部在I/O口的输出部分安排了多个响应速度不同的输出驱动电路,用户可以根据自己的需要选择合适的驱动电路)。通过选择速度来选择不同的输出驱动模块,达到最佳的噪声控制和降低功耗的目的。高频的驱动电路,噪声也高,当不需要高的输出频率时,请选用低频驱动电路,这样非常有利于提高系统的EMI性能。当然如果要输出较高频率的信号,但却选用了较低频率的驱动模块,很可能会得到失真的输出信号。关键是GPIO的引脚速度跟应用匹配。


(4)IO配置


① 作为普通GPIO输入: 

根据需要配置该引脚为浮空输入、带弱上拉输入或带弱下拉输入,同时不要使能该引脚对应的所有复用功能模块。 


② 作为普通GPIO输出: 

根据需要配置该引脚为推挽输出或开漏输出,同时不要使能该引脚对应的所有复用功能模块。 


③ 作为普通模拟输入: 

配置该引脚为模拟输入模式,同时不要使能该引脚对应的所有复用功能模块。 


④ 作为内置外设的输入: 

根据需要配置该引脚为浮空输入、带弱上拉输入或带弱下拉输入,同时使能该引脚对应的某个复用功能模块。 


⑤ 作为内置外设的输出: 

根据需要配置该引脚为复用推挽输出或复用开漏输出,同时使能该引脚对应的所有复用功能模块。


(5)GPIO口初始化


①使能GPIO口的时钟 


②配置模式设置(8种模式) 

注:STM32的GPIO的时钟统一挂接在APB2上,具体的使能寄存器为RCC_APB2ENR。该寄存器的第2位到第8位分别控制GPIOx(x=A,B,C,D,E,F,G)端口的时钟使能。


Eg:RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOD, ENABLE); //使能PA,PD端口时钟


注:STM32 的很多 IO 口都是 5V 兼容的,可以从该芯片的数据手册管脚描述章节查到( I/O Level 标 FT 的就是 5V 电平兼容的)。


(6)GPIO配置寄存器


a.STM32 的 CRL 控制着每组 IO 端口( A~G)的低 8 位的模式。每个 IO 端口的位占用 CRL 的 4 个位,高两位为 CNF,低两位为 MODE。GPIO口配置是通过配置寄存器来进行的,每个GPIO 端口有:


两个32位配置寄存器(GPIOx_CRL,GPIOx_CRH)分别控制每个端口的高八位和低八位。如果IO口是0-7号的话,则写CRL寄存器;如果IO口是8-15号的话,则写CRH寄存器。CRL 和 CRH 控制着每个 IO 口的模式及输出速率。


配置表如下:



输出模式配置:



端口低配置寄存器 CRL 的描述:


该寄存器的复位值为 0X4444 4444,复位值其实就是配置端口为浮空 


输入模式。从上图还可以得出: STM32 的 CRL 控制着每组 IO 端口( A~G)的低 8 位的模式。每个 IO 端口的位占用 CRL 的 4 个位,高两位为 CNF,低两位为 MODE。


几个常用的配置,比如 0X0 表示模拟输入模式( ADC 用)、 0X3 表示推挽输出模式(做输出口用,50M 速率)、 0X8 表示上/下拉输入模式(做输入口用)、 0XB 表示复用输出(使用 IO 口的第二功能, 50M 速率)。


CRH 的作用和 CRL 完全一样,只是 CRL 控制的是低 8 位输出口,而 CRH 控制的是高 8位输出口。


b.两个32位数据寄存器(GPIOx_IDR,GPIOx_ODR)一个是只读作输入数据寄存器,一个是只写作输出寄存器。


端口输入数据寄存器 IDR 各位描述:



要想知道某个 IO 口的状态, 你只要读这个寄存器,再看某个位的状态就可以了。


ODR 是一个端口输出数据寄存器,也只用了低 16 位。该寄存器为可读写,从该寄存器读出来的数据可以用于判断当前 IO 口的输出状态。而向该寄存器写数据,则可以控制某个 IO 口的输出电平。



一个32位置位/复位寄存器(GPIOx_BSRR)。 

一个16位复位寄存器(GPIOx_BRR)。 

一个32位锁定寄存器(GPIOx_LCKR)。 

常用的IO端口寄存器只有四个:CRH,CRL,IDR,ODR。


数据手册中列出的每个I/O端口的特定硬件特征。 GPIO端口的每个位可以由软件分别配置成多种模式。每个I/O端口位可以自由编程,然而I/O端口寄存器必须按32位字被访问(不允许半字或字节访问)。 另外,STM32的每个端口使用前都要将其时钟使能,STM32的GPIO的时钟统一挂接在APB2上,具体的使能寄存器为RCC_APB2ENR,该寄存器的第2位到第8位分别控制GPIOx(x=A,B,C,D,E,F,G)端口的时钟使能,当外设时钟没有启用时,程序不能读出外设寄存器的数值。


(7)GPIO库函数简要解释:


函数名 具体功能

GPIO_DeInit 重新初始化外围设备GPIOx相关寄存器到它的默认复位值

GPIO_AFIODeInit 初始化交错功能(remap, event control和 EXTI 配置) 寄存器

GPIO_Init 根据GPIO_初始化结构指定的元素初始化外围设备GPIOx

GPIO_StructInit 填充GPIO_初始化结构(GPIO_InitStruct)内的元素为复位值

GPIO_ReadInputDataBit 读指定端口引脚输入数据

GPIO_ReadInputData 读指定端口输入数据

GPIO_ReadOtputDataBit 读 指定端口引脚输出数据

GPIO_ReadOtputData 读指定端口输出数据

GPIO_SetBits 置1指定的端口引脚

GPIO_ResetBits 清0指定的端口引脚

GPIO_WriteBit 设置或清除选择的数据端口引脚

GPIO_Write 写指定数据到GPIOx端口寄存器

GPIO_ANAPinConfig 允许或禁止 GPIO 4 模拟输入模式

GPIO_PinLockConfig 锁定GPIO引脚寄存器

GPIO_EventOutputConfig 选择GPIO引脚作为事件输出

GPIO_EventOutputCmd 允许或禁止事件输出

GPIO_PinRemapConfig 改变指定引脚的映射

GPIO_EXTILineConfig 设置外部中断

GPIO_ETH_MediaInterfaceConfig 配置以太网接口

(8)实例学习


①GPIO输出——LED实现:关键部分是实现GPIO的初始化工作,具体实现如下:


#define LED PAout(12) //输出,使用的是位带操作来实现操作某个 IO 口的 1 个位


void led_init(void)

{

    GPIO_InitTypeDef GPIO_InitStructure;


    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//使能PA端口


    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;//PA.8端口设置

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//IO口的速度为50MHZ


    GPIO_Init(GPIOA,&GPIO_InitStructure);//初始化PA

    GPIO_SetBits(GPIOA,GPIO_Pin_12);//PA.8输出高

}


在使用PA15引脚的时候,按照正常的 IO 初始化,并且停止使用JTAG,依然不能点亮LED,因为PA15默认JTAG的一个脚,现在要变成普通IO就要使能复用时钟。


RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO,ENABLE);//使能PA端口

GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE); //关闭JTAG口,使PB3,PB4,PA15这几个IO作为普通IO使用


注:操作 IO 口输出高低电平的三种方法

位操作就是可以单独的对一个比特位读和写,这个在51单片机中非常常见。51单片机中通过关键字sbit来实现位定义,STM32F103中没有这样的关键字,而是通过访问位带别名区来实现。


    a.通过位带操作 PA12 输出高低电平从而控制 LED 的方法如下:

    #define LED PAout(15) //输出

    LED=1; //通过位带操作控制 LED 的引脚 PA12 输出高电平

    LED=0; //通过位带操作控制 LED 的引脚 PA12 输出低电平


    b.使用固件库操作和寄存器操作:

来实现 IO

[1] [2]

关键字:STM32  GPIO

编辑:什么鱼 引用地址:http://www.eeworld.com.cn/mcu/2019/ic-news010942863.html
本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:STM32学习笔记一一外部中断
下一篇:STM32学习笔记一一USART

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

STM32:STM32库函数配置

stm32 固件库V3.0以上的版本,main等源文件中不再直接包含stm32f10x_conf.h,而是stm32f10x.h,stm32f10x.h则定义了启动设置,以及所有寄存器宏定义,此文件中需要注意的有:使用V3.0以上版本固件库的方法如下:1.选择device(配置函数STM32F10x.h,具体配置方法如下)在STM32F10x.h中有如下代码:#if !defined (STM32F10X_LD) && !defined (STM32F10X_LD_VL) && !defined (STM32F10X_MD) && !defined
发表于 2019-01-17
STM32:STM32库函数配置

STM32:STM32学习记录1:MDK基本数据类型及代码优化

大概一年前开始接触STM32,当时就被它的库函数开发所吸引,但是迫于各种压力放弃了学习,一直在使用所谓稳定的单片机来开发(忍不住要吐槽),现在终于有时间了,开始自己的兴趣之旅喽!!现在网上有各种大牛的经验文档使我受益匪浅,也感谢室友的无私帮助!!!大概看了一下大牛的经验文档,好像没有一个提到MDK的基本数据类型的,自己找找看在MDK的帮助里面有。打开MDK-----help----uVision help----RealView Compiler Reference Guide----C and C++ implementation details----C and C++ implementation
发表于 2019-01-17
STM32:STM32学习记录1:MDK基本数据类型及代码优化

STM32:STM32学习记录5: 外部中断

配置流程:1:系统时钟初始化,包括系统时钟和要开放的IO口或者功能的时钟配置。2:IO口初始化,包括引脚,速率,输入输出模式等。3:NVIC 中断向量配置 ,中断向量基地址和优先级的配置。4:EXTI 中断/事件控制器,使能或失能外部线路,使能的模式(事件请求和中断请求),边沿触发模式,状态等。说明:1:主函数写在main.c中,中断函数写在stm32f10x_it.c 中,找到相应的中断函数(一般都是空白),加入自己的中断代码即可。2:中断函数名在startup_stm32f10x_xx.s中查阅3:清除 EXT13 线路的挂起位  注意此处一定要清除!!!!!!!!在EXTI_PR寄存器中3:NVIC一般配
发表于 2019-01-17

STM32学习记录——printf函数重定位

功能: 重定位printf函数,使printf作为串口打印输出函数。代替usart_send_string()函数步骤: usart.c中包含USART初始化函数 1、USART初始化(使能时钟、使能GPIO、GPIO和USART初始化) 2、打开USART 3、在usart.c中加入如下代码#ifdef __GNUC__     /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf      
发表于 2019-01-17

STM32USART串口调节与printf重定义

首先,printf重定义后可以直接使用printf函数从串口发送数据在usart.c中添加代码:#ifdef __GNUC__  /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf     set to 'Yes') calls __io_putchar() */  #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)#else  #define PUTCHAR_PROTOTYPE int f
发表于 2019-01-17

STM32中使用标准库重定义printf()函数

//重定义函数1PUTCHAR_PROTOTYPE{ /* Place your implementation of fputc here */ /* e.g. write a character to the USART */  USART_SendData(USART1, (uint8_t) ch);   /* 循环等待直到发送结束*/  while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)  {}   return ch;}//重定义函数2 int fputc
发表于 2019-01-17

小广播

何立民专栏

单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2018 EEWORLD.com.cn, Inc. All rights reserved