ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

STM32学习(三)—— GPIO

STM32学习(三)—— GPIO 一、GPIO的概述1. GPIO的概念GPIO指的是通用的输入输出端口可以由用户通过软件配置的方式来进行控制GPIO引脚需要和外设连接在一起就可以实现和外设实现通信以及采集数据等功能。2. GPIO的定义指的是对芯片的某个引脚进行高低电平的输出以及可以去检测某个引脚的电平状态。一般电平采用都是TTL电平信号TTL电平信号规定5V等价于逻辑”1“ 0V等价于逻辑”0“。电平其实有一个电平范围2.4V就表示高电平0.4V就表示低电平。高电平2.4~5V 低电平0~0.7V电源引脚 VCC、VDD、VSS、VDDA、VSSA、VREF等属于电源引脚晶振引脚 PC14、PC15、PH0、PH1就属于晶振引脚也可以作为其他的功能实用复位引脚 NRST属于复位引脚BOOT引脚 BOOT0是专用引脚BOOT1就属于功能引脚设置芯片的自举模式GPIO引脚 芯片一共有144引脚但是GPIO引脚只有114个下载引脚 PA13、PA14、PB3、PB4等都属于下载引脚JTAG、SWD4. 引脚的命名规则一般是由P开头分为很多组以字母A~H来命名每个组由16个引脚组成引脚的编号为0~15所以如 PA0~PA15 PB0~PB15..........5. 引脚的功能需要注意芯片的引脚有很多功能一般默认的功能都是作为GPIO输入输出但是引脚也有其他的功能被称为”第二功能“只有再实用ADC通道和DAC需要把引脚设置模拟模式其他情况下把引脚当作别的功能实用需要把引脚设置为复用模式。需要注意引脚的功能必须通过查阅芯片的数据手册才可以进行配置如下图所示注意带FT标志的IO口可以容忍5V电压芯片的标准电压为3.3V二、GPIO的使用GPIO外设的使用一般在实际开发中都是使用函数库开发提高开发效率以GPIO外设为例讲解一下函数库开发的流程以点亮LED为例子1. 分析原理图找到外设连接的GPIO引脚LED0-----PF9一般硬件工程师在设计开发板的过程中先设计原理图实际上就说对硬件的抽象一般外设都需要通过导线连接在芯片的引脚上不简洁都会利用网络标号实现导线的连接网络编号其实就是一个电气连接点一般是以字母数字命名如果多个连接点都是用同样的网络编号就说明导线是连接在一起的。2. 分析原理图理解硬件控制的原理GPIO输出低电平灯亮GPIO输出高电平灯灭。3. 根据函数库的接口进行开发参考ST公司提供的函数库帮助手册相当于Linux的man手册可以看到函数库开发的时候外设的使用流程都是一样的接下来讲解一下细节●定义一个外设的结构体变量变量命名规则PPP_InitTypeDef PPP_InitStructure;每个外设都有对应的结构体结构体的定义一般都是存放在每个外设的头文件内比如GPIO外设的初始化结构体定义在stm32f4xx_gpio.h中●在配置外设结构体之前需要打开外设的时钟任何一个外设都是由时钟控制的时钟就相当于外设的开关因为底层寄存器一般内部结构中都包含D触发器而触发器需要触发信号而触发信号是由时钟提供的。STM32低功耗的根本原因就是在芯片复位之后所有的外设的时钟开关都是默认关闭需要用到哪个外设就打开哪个外设的时钟不需要的就关有利于降低功耗。可以看到函数库中提供了多个可以打开外设时钟的函数如下图所示思考想要打开GPIO外设的时钟应该用哪个函数可以参考STM32中文参考手册的2.3章节存储器映射可以看到内核的外设都会挂载在不同的总线下面AHB总线叫做高级高性能总线APB总线叫做高级外设总线APB1和APB2。每个总线的时钟频率都不同因为不同类型的外设需要的时钟频率不同所以为了降低STM32的功耗把不同性能的外设挂载在不同频率的总线下。函数库中提供的时钟使能的函数在stm32f4xx_rcc.h中声明在stm32f4xx_rcc.c定义函数原型void RCC_AHB1PeriphClockCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState)函数参数参数一RCC_AHB1Periph 指的是外设的时钟 如RCC_AHB1Periph_GPIOF参数二NewState 指的是打开或者关闭 如ENABLE or DISABLE返回值None需要注意在调用函数库的时候大家不需要关注函数内部的实现过程只需要掌握函数的传参和返回值即可●打开外设时钟后需要对外设的结构体成员进行赋值操作引脚、模式、速率、类型....GPIO外设的结构体成员有5个可以参考stm32f4xx_gpio.h1. 需要指定配置的引脚 GPIO_Pin 定义在GPIO_pins_define (调整 or 查找一个端口有16个引脚在操作端口的某个引脚的时候需要说清楚用哪个引脚这样才可以对寄存器的某些位进行操作详细解释如何通过操作寄存器的位来控制引脚输出高低电平ODR是输出数据寄存器Output Data Register它才是真正存储每个引脚最终输出状态0或1的地方。而BSR和BRR这两个寄存器并不直接存储状态它门至少用来修改ODR的“快捷工具”。你往BSR写1硬件就i会自动取把对应的ODR位改写成1往BRR写1硬件就会自动把ODR位该为0。2. 需要指定引脚的模式 GPIO_Mode 定义在GPIOMode_TypeDef 跳转 or 查找GPIO的引脚模式可以参考中文参考手册的7.3章节可以看到每个引脚内部都有保护二极管这也是STM32的安全机制但是需要注意STM32引脚不是万能的一般是作为控制使用而不是作为驱动使用。每个引脚内部都有上拉电阻和下拉电阻但是上拉电阻是一个弱上拉驱动能力较弱如果想要提供引脚一个确定的电平建议外接上拉电阻。建议大家在没有使用引脚的时候给引脚一个默认的电平状态可以消除引脚不定值的影响。GPIO提供了3种输入模式浮空输入、上拉输入、下拉输入参考GPIO内部结构示意图GPIO提供了4种输出模式上拉下拉推挽输出、上拉下拉开漏输出参考GPIO内部结构示意图PMOS管和NMOS管循环依次导通好处是可以提高电路的负载能力和切换速度并且可以降低功耗。推挽输出可以利用驱动器直接输出高电平和低电平开漏输出可以利用驱动器直接输出低电平但是不能直接输出高电平需要外接上拉电阻3. 设置引脚的输出速率 GPIO_Speed 定义在GPIOSpeed_TypeDef指的时IO驱动电路的输出能力其实就是在不失真的情况下能输出的最大速率引脚的输出速率影响GPIO的引脚的功耗和噪声一般大家可以根据实际需要来选择速率越高则功耗越高噪声越大如果对产品的实时性要求不高则选择一个低速的即可有利于降低EMI电磁干扰一般指的是影响引脚在切换高低电平的过程中上升沿和下降沿的陡度。如果自己不知道选哪个就选高的。4. 设置引脚的输出类型 GPIO_OType 定义在GPIOOType_TypeDef推挽输出可以利用驱动器直接输出高电平和低电平开漏输出可以利用驱动器直接输出低电平但是不能直接输出高电平需要外接上拉电阻5. 设置引脚的上下拉电阻 GPIO_PuPd 定义在GPIOPuPd_TypeDef一般都会在引脚未使用的情况给引脚一个默认的电平状态防止引脚出现电平不定高阻态的情况。●在对结构体成员赋值之后调用初始化函数把结构体成员的值写入到对应外设的寄存器函数原型void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)函数参数参数一GPIOx 指的是想要初始化的GPIO外设的端口 A~K 若GPIOF参数二GPIO_InitStruct 指的是配置好的GPIO结构体变量的地址 记得取地址 返回值 None●设置引脚输出高电平输出模式有效 调用GPIO_SetBits()函数原型void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)函数参数参数一GPIOx 想要输出高电平的引脚端口 如GPIOx A~K 如 GPIOF参数二GPIO_Pin 想要输出高电平的引脚位置 如GPIO_Pin_x where x can be(0...15)返回值None●设置引脚输出低电平输出模式有效 调用GPIO_ResetBits()函数原型void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)函数参数参数一GPIOx 想要输出低电平的引脚端口 如GPIOx A~K 如 GPIOF参数二GPIO_Pin 想要输出低电平的引脚位置 如GPIO_Pin_x where x can be(0...15)返回值None●获取引脚的电平状态输入模式有效 调用GPIO_ReadInputDataBit()函数原型uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)函数参数参数一GPIOx 想要读取的引脚端口 如GPIOx A~K 如 GPIOF参数二GPIO_Pin 想要读取的引脚位置 如GPIO_Pin_x where x can be(0...15)返回值返回读取到的引脚的电平状态 0或者1
返回列表