STM32——GPIO篇

技术笔记!

1.  什么是GPIO?

        GPIO是通用输入输出端口(General-purpose input/output)的英文简写,是所有的微控制器必不可少的外设之一,可以由STM32直接驱动从而实现与外部设备通信、控制以及采集和捕获的功能。

        GPIO口可配置为多种输入输出模式,如输入浮空、输入上拉、输入下拉、模拟输入、开漏输出、开漏复用功能、推挽式输出以及推挽式复用功能等。

        STM32单片机的GPIO被分为很多组,每组最多有16个引脚,不同型号的 MCU 的GPIO个数是不同的。

        引脚电平:0V~3.3V,部分引脚可容忍5V(FT)。

2.  GPIO内部结构

3.  GPIO工作模式(重点)

4  GPIO寄存器(以STM32f103C8T6为例)

        1.  端口配置低寄存器 CRL

        通常最多拥有16个引脚,每个引脚需要4位来进行配置,需要64位,两字节,所以端口配置寄存器分为高位和低位。

        端口配置寄存器主要是配置端口的八种模式以及输出速度,如下图

        2.  端口配置高寄存器 CRH(作用和CRL一样)

        3.  端口输入数据寄存器 IDR

        将输入的值存入相应的引脚位置中。

        4.  端口输出数据寄存器 ODR

        将ODR寄存器对应的 引脚内的值输出到接收的值中。

        5.  端口位设置/清除寄存器 BSRR

           6.  端口位清除寄存器 BRR (不常用)

           7.  端口配置锁定寄存器 LCKR(不常用)

5  GPIO中的HAL库

        其中GPIO_TypeDef *GPIOx指的是GPIO中的组别,GPIO_Pin指的是需要操作的引脚。

        Init 函数对GPIO进行初始化,EXTI是中断函数,ReadPin是读相应的引脚,TogglePin是翻转引脚,WritePin是将值写入相应的引脚。

6.  点亮led灯实验

led.c

#include "led.h"
#include "sys.h"//初始化GPIO函数
void led_init(void)
{GPIO_InitTypeDef gpio_initstruct;//打开时钟__HAL_RCC_GPIOB_CLK_ENABLE();                           // 使能GPIOB时钟//调用GPIO初始化函数gpio_initstruct.Pin = GPIO_PIN_8;                       // LED1对应的引脚gpio_initstruct.Mode = GPIO_MODE_OUTPUT_PP;             // 推挽输出gpio_initstruct.Pull = GPIO_PULLUP;                     // 上拉gpio_initstruct.Speed = GPIO_SPEED_FREQ_HIGH;           // 高速HAL_GPIO_Init(GPIOB, &gpio_initstruct);//关闭LEDled1_off();
}//点亮LED1的函数
void led1_on(void)
{HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_RESET);   // 拉低LED1引脚,点亮LED1
}//熄灭LED1的函数
void led1_off(void)
{HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_SET);     // 拉高LED1引脚,熄灭LED1
}//翻转LED1状态的函数
void led1_toggle(void)
{HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_8);
}

main.c

#include "sys.h"
#include "delay.h"
#include "led.h"int main(void)
{HAL_Init();                         /* 初始化HAL库 */stm32_clock_init(RCC_PLL_MUL9);     /* 设置时钟, 72Mhz */led_init();                         /* 初始化LED灯 */
//    led1_on();                        /* 点亮LED1 */
//    led1_off();                       /* 熄灭LED1 */while(1){ led1_toggle();/*led1_on();delay_ms(500);led1_off();*/delay_ms(500);}
}

实验小结:

        本次实验主要是掌握gpio引脚的使用,通过使能GPIO时钟,进而控制通过原理图所查到的led相关引脚,使用GPIO初始化函数进行GPIO的初始化。初始化gpio之前得配置GPIO的初始化结构体,如对应的引脚,GPIO模式(输出、输入、复用等),上下拉以及速度等。通过HAL_GPIO_Write函数写入led引脚对应的寄存器中的值,改变电位,进而控制led灯的亮灭,并且使用了翻转函数HAL_GPIO_Toggle函数,翻转对应引脚的状态,起到led灯的状态翻转。

        主函数中首先初始化了HAL库(本次实验通过调用HAL库来实现),并且初始化了时钟,接着初始化led函数。

7.  按键实验

key.c

#include "key.h"//初始化GPIO函数
void key_init(void)
{GPIO_InitTypeDef gpio_initstruct;//打开时钟__HAL_RCC_GPIOA_CLK_ENABLE();                           // 使能GPIOB时钟//调用GPIO初始化函数gpio_initstruct.Pin = GPIO_PIN_0 | GPIO_PIN_1;                       // key1,key2对应的引脚gpio_initstruct.Mode =  GPIO_MODE_INPUT;             // 输入gpio_initstruct.Pull = GPIO_PULLUP;                     // 上拉,该模式的设置须和跟工作模式相反gpio_initstruct.Speed = GPIO_SPEED_FREQ_HIGH;           // 高速HAL_GPIO_Init(GPIOA, &gpio_initstruct);}
//按键扫描函数
uint8_t key_scan(void)
{//检测按键1是否被按下if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_RESET){//消抖delay_ms(10);//再次判断是否被按下if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_RESET){//如果确实是按下的状态,等待按键松开while(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_SET);//返回按键值return 1;}}//检测按键2是否被按下,使用了readPin函数if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1) == GPIO_PIN_RESET){//消抖delay_ms(10);//再次判断是否被按下if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1) == GPIO_PIN_RESET){//如果确实是按下的状态,等待按键松开while(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1) == GPIO_PIN_SET);//返回按键值return 2;}}//返回默认值return 0;
}

main.c

#include "sys.h"
#include "delay.h"
#include "led.h"
#include "key.h"int main(void)
{HAL_Init();                         /* 初始化HAL库 */stm32_clock_init(RCC_PLL_MUL9);     /* 设置时钟, 72Mhz */led_init();                         /* 初始化LED灯 */key_init();                         /* 初始化key*/uint8_t key_num = 0;while(1){ key_num = key_scan();           /* 扫面按键获取按键的值*/if(key_num == 1)                /* 检测按键1按下*/{led1_toggle();              /*翻转LED1*/}if(key_num == 2)                /* 检测按键2按下*/{led2_toggle();              /*翻转LED2*/}}
}

实验小结:

        按键实验是为了对GPIO有更加深层次的认识,在led的实验的基础上,通过多个引脚控制led灯的亮灭。实验步骤首先是对GPIO时钟使能,进而初始化GPIO,通过gpio结构体结构体对GPIO进行相关引脚的配置,当需要初始化多个引脚时可以使用  ’|‘ 或运算符,如 GPIO_PIN_0 | GPIO_PIN_1,模式设为输入模式,led中的是输入模式,上下拉设置为上拉模式(不工作的状态)。使用自定义的按键扫描函数检测按键的状态,通过两次HAL_GPIO_ReadPin读取引脚状态,第一次为了防止是误触并且使用延时函数进行消抖,通过轮询的读取引脚等待按键的松开,最后返回对应的按键。

        主函数初始化HAL库,时钟的初始化,通过自定义的按键扫描函数返回的值进而控制led灯的翻转。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/320842.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

骨传导耳机哪个品牌值得入手?精选五款高性能骨传导耳机,闭眼入都不踩雷!

随着健康生活的日益普及,运动健身逐渐成为人们生活中的重要组成部分。在这一背景下,骨传导耳机作为一种新型蓝牙耳机,凭借其不堵塞耳道、防水性能强等特性,受到了广大运动爱好者的喜爱。然而,骨传导耳机的热销也吸引了…

海外大带宽服务器的带宽大小是如何定义的?

海外大带宽服务器的带宽大小通常是由提供的数据传输速率来衡量的。Rak部落小编为您整理发布海外大带宽服务器的带宽大小是如何定义的? 带宽的大小决定了服务器能够处理的数据量和传输速度,这对于确保服务器性能至关重要。在详细定义中,带宽可以根据以下…

Flutter笔记:Widgets Easier组件库(9)使用弹窗

Flutter笔记 Widgets Easier组件库(9):使用弹窗 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite:http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress o…

每日OJ题_贪心算法三②_力扣553. 最优除法

目录 力扣553. 最优除法 解析代码 力扣553. 最优除法 553. 最优除法 难度 中等 给定一正整数数组 nums,nums 中的相邻整数将进行浮点除法。例如, [2,3,4] -> 2 / 3 / 4 。 例如,nums [2,3,4],我们将求表达式的值 "…

MySQL-笔记-08.数据库编程

目录 8.1 编程基础 8.1.1 基本语法 8.1.2 运算符与表达式 1. 标识符 2. 常量 (1) 字符串常量 (2)日期时间常量 (3)数值常量 (4)布尔值常量 (5)NULL…

暖心又实用!母亲节教会妈妈这4招才是最贴心的礼物

母亲节就要到了,这个特殊的日子,我们总是想要为妈妈送上最真挚的祝福和关怀。在这个数字化时代,一部智能手机就能成为我们表达爱意的桥梁。今天,就让我们一起来看看华为手机的四个功能,让妈妈的手机使用体验更加便捷、…

革新食品改良,解锁品质新高度——体验西奥机电TEX-01质构仪的卓越魅力

革新食品改良,解锁品质新高度——体验西奥机电TEX-01质构仪的卓越魅力 引领食品改良新潮流 在追求品质生活的今天,食品的口感和品质成为了消费者选择的重要标准。为了满足这一市场需求,食品企业正积极寻求新的改良方法,以提升产…

Study--Oracle-01-单实例部署Oracle11G-R2

Oracle版本发布介绍 Oracle 19c和12c和11g功能区别_数据库_oracle_支持 一、CentOS 7 环境准备 1、软件准备 操作系统:CentOS 7 数据库版本: Oracle11g R2 2、操作系统环境配置 关闭selinux ,编辑 /etc/selinux/config文件,设置SELINU…

栈的磁盘优化:降低存取成本的算法与实现

栈的磁盘优化:降低存取成本的算法与实现 问题背景简单实现方法的分析实现方法PUSH操作POP操作成本分析渐近分析 优化实现方法实现方法成本分析渐近分析 进一步优化:双页管理策略实现方法管理策略成本分析 伪代码示例C代码示例结论 问题背景 在具有有限快…

Photoshop中选区工具的应用

Photoshop中选区工具的应用 前言Photoshop中选区工具的基本操作创建选区的工具及方法选择、取消、隐藏选区选区的增加、减少选区的应用变换扩大选取与选取相似 Photoshop中采用快速选择工具来创建选区Photoshop中采用色彩范围命令来创建选区Photoshop中采用快速蒙版来创建选区P…

如何用Kimi,5秒1步生成流程图

引言 在当前快节奏的工作环境中,拥有快速、专业且高效的工具不可或缺。 Kimi不仅能在5秒内生成专业的流程图(kimi),还允许实时编辑和预览,大幅简化了传统流程图的制作过程。 这种迅速的生成能力和高度的可定制性使得…

docker资源限额

多数的应⽤场景要对Docker容器的运⾏内存进⾏限制,防⽌其使⽤过多的内存。 格式:-m或--memory 正常的内存大小 [rootadmin ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS …

音视频开发4 FFmpeg windows 环境搭建,QT 安装,动态库的搜索路径

FFmpeg 为了让所有平台的开发者都能够学习到音视频开发的通用技术,本教程主要讲解跨平台的音视频开发库FFmpeg。其实只要你掌握了FFmpeg,也可以很快上手其他音视频开发库,因为底层原理都是一样的,你最终操作的都是一样的数据&…

速卖通新卖家测评攻略:从入门到精通

在电商行业中,测评被广泛认为是提升产品转化率和销量的有效手段。对于速卖通的卖家而言,测评的必要性更是显而易见。测评,本质上与国内电商的补单行为相似,是一种通过增加销量来提升产品权重的方法。 特别是在竞争激烈的类目中&a…

【Stream 流】通过一个例子看遍所有Stream API使用场景

前言 上篇文章记录了方法引用,Lambda表达式等基础的知识点,这篇文章主要结合课设项目详细介绍Stream 流的API以及它的主要场景。 Stream API作用 在Java 8及其以后的版本中,Stream API为处理集合数据提供了强大而灵活的功能。有了Stream AP…

Flutter开发Dart中的队列(Queue)

文章目录 Dart中的队列(Queue)基本操作示例队列的类型队列的应用总结 Dart中的队列(Queue) 队列是一种抽象的数据结构,遵循“先进先出”(FIFO)的原则。这意味着最早添加的元素将首先被移除。队…

如何在速卖通(aliexpress)买东西?速卖通(aliexpress)买东西怎么付款?

如何在速卖通购物: 1、注册账户:首先访问速卖通官网或下载速卖通手机应用程序,并注册一个账户。如果您已经有一个账户,直接登录即可。 2、搜索商品:在搜索框中输入您想要购买的商品关键词,然后点击搜索。…

Ansible 自动化运维工具 - 了解和模块应用

目录 一. Ansible 的相关知识 1.1 Ansible 工具的简介 1.2 Ansible的四大组件 1.3 运维自动化工具 1.4 Ansible 和其它自动化运维工具对比 1.5 Ansible 的优缺点 二. Ansible 环境安装部署 2.1 管理端安装 ansible 2.2 配置主机清单 三. ansible 命令行模块 3.1 comm…

ue引擎游戏开发笔记(33)——武器与角色的匹配,将新武器装备到角色身上

1.需求分析: 武器能出现在世界中,完成了第一步,下一步需要角色和武器适配,即不论角色跑动,射击等,武器和角色都相匹配,将武器装备到角色身上。 2.操作实现: 1.首先先把角色原有的武…

HAL PWM 配置 占空比 频率 stm32 学习笔记

title: HALPWM配置占空比频率 tags: STM32ClionHal 1.STM32CubeMX学习笔记(13)——PWM输出(呼吸灯)使用 2.STM32标准库HAL库 | 高精度动态调节PWM输出频率占空比 看你cubemx 里面的配置时钟频率是多少 参照第二篇文章描述修改 下面俩个参数就行 uin…