单片机型号STM32F407VET6。

概述

GPIO的分类:

  • 可接受5V输入的(FT),绝大多数引脚都是;

  • 只能接受3.3V输入的(TTa),只有PA4PA5,就是DAC输出的两个引脚;

  • 其他,包括BOOT0NRST这两个特殊功能的引脚。

GPIO不仅可以用作GPIO,每个GPIO都有复用功能(alternate function,AF)和附加功能(additional function),AF用GPIOx_AFR来配置,附加功能用外设中的寄存器。

一组GPIO为16个,从Px0Px15xAI,有些封装上有些引脚不存在。

GPIO的功能主要有4类:

  • 输出,推挽(push-pull,PP)或开漏(open-drain,OD),可选上拉(pull-up,PU)或下拉(pull-down,PD),4档速度;

  • AF,细节同上;

  • 输入,可选上拉或下拉;

  • 模拟,用于ADC和DAC。

HAL

HAL把外部中断也归到了GPIO中,这里暂且不涉及外部中断。

初始化这种事情我都交给STM32CubeMX来完成(STM32CubeIDE内置)。我已经初步领略到HAL的设计思想,以后专门开一篇写。

GPIO有以下函数:

  • HAL_GPIO_Init():初始化一组GPIO中的一个或多个;

  • HAL_GPIO_DeInit():把一组GPIO中的一个或多个还原为复位状态;

  • HAL_GPIO_ReadPin():读引脚电平,返回GPIO_PinState枚举类型,可能值为GPIO_PIN_RESET = 0GPIO_PIN_SET = 1

  • HAL_GPIO_WritePin():写引脚电平,是原子操作,允许中断发生;

  • HAL_GPIO_TogglePin():翻转引脚电平;

  • HAL_GPIO_LockPin():锁定引脚配置,在复位前不可修改,引脚电平还可以写。

#include "main.h"
#include <stdbool.h>
int main(void)
{
bool prev = true;
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
while (1)
{
if (HAL_GPIO_ReadPin(KEY0_GPIO_Port, KEY0_Pin) == GPIO_PIN_RESET)
HAL_GPIO_WritePin(LED0_GPIO_Port, LED0_Pin, GPIO_PIN_RESET);
else
HAL_GPIO_WritePin(LED0_GPIO_Port, LED0_Pin, GPIO_PIN_SET);
bool now = HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin) == GPIO_PIN_RESET;
if (!prev && now)
HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin);
prev = now;
HAL_Delay(1);
}
}

(STM32CubeMX生成的代码是两格缩进的,这让我非常不爽!)

LED0LED1分别连接到PA6PA7,低电平亮;KEY0KEY1分别连接到PE4PE3,上拉。程序的功能为:KEY0按下时LED0亮,松开熄灭;KEY1按下时切换LED1的亮暗状态。

寄存器

每一组GPIO都有10个寄存器:

  • GPIOx_MODER,32位,2位MODERy[1:0]一组(y015,下同),设置GPIO模式;

  • GPIOx_OTYPER,16位,1位OTy一组,设置GPIO输出类型;

  • GPIOx_OSPEEDR,32位OSPEEDRy[1:0],设置GPIO输出速度;

  • GPIOx_PUPDR,32位PUPDRy[1:0],设置上拉下拉;

  • GPIOx_IDR,16位IDRy,读取输入电平;

  • GPIOx_ODR,16位ODRy,设置输出电平;

  • GPIOx_BSRR,低16位BSy,写1GPIOx_ODR中对应位置1;高16位BRy,写1GPIOx_ODR中对应位清0;同时写1BSy优先;

  • GPIOx_LCKR:低16为LCKy,第16位LCKK,需要一个特定的写入过程(参考datasheet或HAL_GPIO_LockPin实现),可以锁定GPIOx_MODERGPIOx_OTYPERGPIOx_OSPEEDRGPIOx_PUPDRGPIOx_AFRLGPIOx_AFRH这6个控制寄存器中的对应位;

  • GPIOx_AFRLGPIOx_AFRH,4位AFRHy[3:0]为一组,设置复用输出。

GPIO的输出级有一个NMOS和一个PMOS:

  • 在推挽输出模式下,ODRx0,NMOS导通;ODRx1,PMOS导通;

  • 在开漏输出模式下,ODRx0,NMOS导通;ODRx1,高阻态;PMOS都不会导通。

开漏输出的应用有矩阵键盘和I²C等,需要上拉电阻,通常用内置的即可。

用寄存器重写上面的程序:

#include "main.h"
#include <stdbool.h> #define LED0_Bit 6
#define LED1_Bit 7
#define KEY0_Bit 4
#define KEY1_Bit 3 int main(void)
{
bool prev = true;
HAL_Init();
SystemClock_Config();
__HAL_RCC_GPIOA_CLK_ENABLE();
LED0_GPIO_Port->ODR |= 1 << LED0_Bit;
LED0_GPIO_Port->MODER |= 0b01 << (LED0_Bit * 2);
LED1_GPIO_Port->ODR |= 1 << LED1_Bit;
LED1_GPIO_Port->MODER |= 0b01 << (LED1_Bit * 2);
__HAL_RCC_GPIOE_CLK_ENABLE();
KEY0_GPIO_Port->PUPDR |= 0b01 << (KEY0_Bit * 2);
KEY1_GPIO_Port->PUPDR |= 0b01 << (KEY1_Bit * 2);
while (1)
{
if (!(KEY0_GPIO_Port->IDR & 1 << KEY0_Bit))
LED0_GPIO_Port->BSRR = 1 << (16 + LED0_Bit);
else
LED0_GPIO_Port->BSRR = 1 << LED0_Bit;
bool now = !(KEY1_GPIO_Port->IDR & 1 << KEY1_Bit);
if (!prev && now)
LED1_GPIO_Port->ODR ^= 1 << LED1_Bit;
prev = now;
HAL_Delay(1);
}
}

只把GPIO相关的改成了寄存器操作,时钟之类的还是用的HAL。

STM32学习笔记——GPIO的更多相关文章

  1. STM32学习笔记——OLED屏

    STM32学习笔记--OLED屏 OLED屏的特点: 1.  模块有单色和双色可选,单色为纯蓝色,双色为黄蓝双色(本人选用双色): 2.  显示尺寸为0.96寸 3.  分辨率为128*64 4.   ...

  2. STM32学习笔记——点亮LED

    STM32学习笔记——点亮LED 本人学习STM32是直接通过操作stm32的寄存器,使用的开发板是野火ISO-V2版本: 先简单的介绍一下stm32的GPIO: stm32的GPIO有多种模式: 1 ...

  3. stm32学习笔记——外部中断的使用

    stm32学习笔记——外部中断的使用 基本概念 stm32中,每一个GPIO都可以触发一个外部中断,但是,GPIO的中断是以组为一个单位的,同组间的外部中断同一时间只能使用一个.比如说,PA0,PB0 ...

  4. STM32学习笔记(四)——串口控制LED(中断方式)

    目录: 一.时钟使能,包括GPIO的时钟和串口的时钟使能 二.设置引脚复用映射 三.GPIO的初始化配置,注意要设置为复用模式 四.串口参数初始化配置 五.中断分组和中断优先级配置 六.设置串口中断类 ...

  5. stm32学习笔记----双串口同时打开时的printf()问题

    stm32学习笔记----双串口同时打开时的printf()问题 最近因为要使用串口2外接PN532芯片实现通信,另一方面,要使用串口1来将一些提示信息输出到上位机,于是重定义了printf(),使其 ...

  6. STM32学习笔记-NVIC中断知识点

    STM32学习笔记-NVIC中断知识点总结 中断优先级设置步骤 1. 系统运行后先设置中断优先级分组 函数:void NVIC_PriorityGroupConfig(uint32_tNVIC_Pri ...

  7. stm32学习笔记之GPIO功能框图分析

    GPIO 是通用输入输出端口的简称,简单来说就是STM32 可控制的引脚,STM32 芯片的GPIO 引脚与外部设备连接起来,从而实现与外部通讯.控制以及数据采集的功能.STM32 芯片的GPIO被分 ...

  8. STM32学习笔记之一(初窥STM32)

    怎么做好学习笔记? 答:自我感知-->学习知识-->归纳总结-->自我升华(真正属于自己的知识是,抛开书本,运用时,你还能记得的思想) 自我感知--看到知识概念,先自我感觉那应该是个 ...

  9. STM32学习笔记(一)——点亮一个LED

    引言 最近报名了2017全国大学生电子设计竞赛,我们学校是第一次参加这个比赛,由于8/9月份就要比赛了,所以现在准备是比较晚的了,指导老师说只能做控制类的题目了,让我们学习一下STM32单片机,51到 ...

随机推荐

  1. Atlassian 系列软件安装(Crowd+JIRA+Confluence+Bitbucket+Bamboo)

    公司使用的软件开发和协作工具为 Atlassian 系列软件,近期需要从腾讯云迁移到阿里云环境,简单记录下安装和配置过程.(Atlassian 的文档非常详尽,过程中碰见的问题都可以找到解决办法.) ...

  2. threejs 鼠标移动控制模型旋转

    <!doctype html> <html> <head> <meta charset="utf-8"> <title> ...

  3. stand up meeting 11/19/2015

    队员 今日工作 工作耗时/h 明日计划 计划耗时/h 冯晓云 利用昨天编写的调用必应词典API的DLL,完成了UWP版本查词APP的试水,证实了DLL可调和在线查词的可行性:和其他部分的同学就接口数据 ...

  4. 总结vscode调试vue,nodejs的各种方法

    之前写项目一直都是console.log()来调试的,浪费了很多时间,现在整理一下用vscode对nuxt(vue)前后端进行调试的方法 前端的调试 chrome+launch 使用chrome调试, ...

  5. Java代码生成器加入postgresql数据库、HikariCP连接池、swagger2支持!

    目录 前言 PostgreSql VS MySql HikariCP VS Druid Swagger2 自定义参数配置一览 结语 前言   最近几天又抽时间给代码生成器增加了几个新功能(预计今晚发布 ...

  6. 安卓微信浏览器中window.location.href失效的问题

    最近接手一微信项目,测试功能时,发现跳转在android手机上不动了.iso系统可以正常跳转的.解决方法: window.location.href = url + '?v=' + (new Date ...

  7. Libra教程之:运行自定义move modules

    文章目录 简介 创建Move modules 启动本地网络 创建账号并送测试币 编译Move Module 发布编译好的Module 创建交易脚本 编译编译脚本 执行脚本 简介 因为Libra和Mov ...

  8. Spring5参考指南:AOP代理

    文章目录 AOP代理 AOP Proxies原理 AOP代理 通常来说Spring AOP有两种代理方式,一种默认的JDK代理,只能代理接口,一种是CGLIB代理,可以代理具体的类对象. Spring ...

  9. Tomcat7 启动慢的问题解决

    [问题] 由于上面标记部分,导致启动耗时将近160s,不能忍! [原因] 此于jvm环境配置有关,请打开jvm安装目录中jre/lib/security/java.security文件,找到secur ...

  10. CSS样式2

    1.css重用 <style> .cl{ ... } .c2{ ... } .c{ ... } </style> <div class='c c2'></di ...