STM32——GPIO篇

news2024/11/24 0:55:44

技术笔记!

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);
    //关闭LED
    led1_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.coloradmin.cn/o/1640090.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

java中的字符串(String)常量池理解

下面创建String对象的方式一样吗? 上述程序创建对象类似,为什么s1和s2引用对象一样,但是s3和s4不一样呢? 在java程序中,许多基本类型的字面常量会经常用到,例如2,3.11,“hyy”等。为了提升程序…

算法学习系列(五十四):单源最短路的综合应用

目录 引言一、新年好二、通信线路三、道路与航线四、最优贸易 引言 关于这个单源最短路的综合应用,其实最短路问题最简单的就是模板了,这是一个基础,然后会与各种算法结合到一块,就是不再考察单个知识点了,而是各种知…

【RBAC鉴权】node-casbin基础教程

一、RBAC概述 RBAC鉴权,完整的英文描述是:Role-Based Access Control,中文意思是:基于角色(Role)的访问控制。这是一种广泛应用于计算机系统和网络安全领域的访问控制模型。 简单来说,就是通过…

a-table 控制列的展示和隐藏

一、业务场景: 最近在使用 Antd-vue 组件库的时候,a-table需要根据不同角色的权限显示和隐藏 columns的列 为了避免大家走弯路,为大家整理了一下,粘走可以直接用的那种 二、具体实现步骤: 1.在需要显示与隐藏的列增加一…

Android Studio实现简单的自定义钟表

项目目录 一、项目概述二、开发环境三、详细设计3.1、尺寸设置3.2、绘制表盘和指针3.3、动态效果 四、运行演示五、总结展望六、源码获取 一、项目概述 在安卓开发中,当系统自带的View已经无法满足项目需求时,就要自定义View。在Android中是没有与钟表有…

深度学习之基于Matlab BP神经网络烟叶成熟度分类

欢迎大家点赞、收藏、关注、评论啦 ,由于篇幅有限,只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 一、项目背景 烟叶的成熟度是评估烟叶品质的重要指标之一,它直接影响着烟叶的口感、香气和理化特性。传…

jupyter notebook切换conda虚拟环境

首先,切换到某个虚拟环境,本人切换到了d2l环境: (d2l) C:\Users\10129>pip install ipykernel然后,如代码所示安装ipykernel包 最后,按下述代码执行: (d2l) C:\Users\10129>python -m ipykernel i…

软件工程全过程性文档(软件全套文档整理)

软件项目相关全套精华资料包获取方式①:进主页。 获取方式②:本文末个人名片直接获取。 在软件开发的全过程中,文档是记录项目进展、决策、设计和测试结果的重要工具。以下是一个简要的软件全过程性文档梳理清单: 需求分析阶段…

Ex1-C6油气化工防爆轮式巡检机器人

Ex1系列防爆轮式巡检机器人整机采用防爆设计,防爆等级为Exd II CT4 Gb。机器人通过无轨3D形态导航技术,结合360度防爆云台和无线防爆充电桩,实现整套防爆标准,可广泛应用于石油、燃气、化工、冶金等II类爆炸环境中,代替…

【Qt QML】QLibrary加载共享库中的类

QLibrary是一个用于加载动态链接库(或称为共享库)的类。它提供了一种独立于平台的方式来访问库中的功能。 在QLibrary中,可以通过构造函数或setFileName()方法设置要加载的库文件名。当加载库文件时,QLibrary会搜索所有平台特定的…

VmWare 虚拟机没有网络解决办法

由于最近需要,装了个VM虚拟机,但是突然发现本机有网络,虚拟机却没有网络,更换了虚拟机的网络设置,都尝试过了 都不管用, 最后尝试了这种方法完美解决 还原网络默认设置 首先还原虚拟网络编辑器设置 启动V…

Re69:读论文 LaMDA: Language Models for Dialog Applications

诸神缄默不语-个人CSDN博文目录 诸神缄默不语的论文阅读笔记和分类 论文名称:LaMDA: Language Models for Dialog Applications ArXiv网址:https://arxiv.org/abs/2201.08239 本文介绍谷歌提出的对话大模型LaMDA,主要关注对各项指标&#x…

使用 MediaMTX 和 FFmpeg 推拉 RTSP 流媒体

实时流传输协议 RTSP(Real-Time Streaming Protocol)是 TCP/IP 协议体系中的一个应用层协议,由哥伦比亚大学、网景和 RealNetworks 公司提交的 IETF RFC 标准。该协议定义了一对多应用程序如何有效地通过 IP 网络传送多媒体数据。RTSP 在体系…

idea常用知识点随记

idea常用知识点随记 1. 打开idea隐藏的commit窗口2. idea中拉取Git分支代码3. idea提示代码报错,项目编译没有报错4. idea中实体类自动生成序列号5. idea隐藏当前分支未commit代码6. idea拉取新建分支的方法 1. 打开idea隐藏的commit窗口 idea左上角File→Settings…

Linux的软件包管理器-yum

文章目录 软件包的概念yum源的配置的原因yum的使用查看软件包安装软件卸载软件 软件包的概念 软件包(SoftWare Package)是指具有特定的功能,用来完成特定任务的一个程序或一组程序。可分为应用软件包和系统软件包两大类 在Linux系统中,下载安装软件的方式…

设计模式: 模板模式

目录 一,模板模式 二,特点 三,组成部分 四,实现步骤 五,案例 一,模板模式 模板模式(Template Pattern)是一种行为型设计模式,它在超类中定义了一个算法的骨架&#…

React Native支持Tailwind CSS 语法

React Native支持Tailwind CSS 语法 一、前沿背景 回想下我们平时按照官方的规范进行书写样式是什么样&#xff1f; 是像下面这样&#xff1a; const MyComponent () > {return (<View><Text style{{ fontSize: 20 }}>开发者演示专用</Text></View…

每日一题(力扣213):打家劫舍2--dp+分治

与打家劫舍1不同的是它最后一个和第一个会相邻&#xff0c;事实上&#xff0c;从结果思考&#xff0c;最后只会有三种&#xff1a;1 第一家不被抢 最后一家被抢 2 第一家被抢 最后一家不被抢 3 第一和最后一家都不被抢 。那么&#xff0c;根据打家劫舍1中的算法 我们能算出在i…

【linux】进程间通信(匿名管道)

对于本篇文章我们采取三段论&#xff1a;是什么 为什么 怎么办。 目录 进程间为什么要通信&#xff1f;进程间如何通信&#xff1f;进程间怎么通信&#xff1f;匿名管道&#xff1a;匿名管道原理&#xff1a;代码示例&#xff1a;匿名管道的情况与特征&#xff1a; 进程间为什…

Debian 12 tomcat 9 catalina 日志信息 中文显示乱码

目录 问题现象 解决办法&#xff1a; 1、设定Debian locale 2、设定catalina.sh utf8字符集 问题现象 Debian 12 linux操作系统中&#xff0c;tomcat 9 catalina 启动日志输出 中文乱码 解决办法&#xff1a; 1、设定Debian locale 先确保系统本身就支持中文的 Debian …