STM32——GPIO输出(点亮第一个LED灯)

代码示例:

#include "stm32f10x.h"                  // Device headerint main()
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//开启时钟GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);GPIO_SetBits(GPIOA,GPIO_Pin_0);GPIO_WriteBit(GPIOA,GPIO_Pin_0,Bit_RESET);while(1){}
}   

使用的外设:

在要用STM32单片机实现某一个功能之前我们需要除了完成基础步骤之外,要知道需要用的什么外设,然后查看该外设都有哪些库函数,这是在采用库函数的开发模式下。

一.RCC:
在STM32单片机中,RCC(Reset and Clock Control)即复位和时钟控制器,是一个非常重要的模块,负责单片机的复位以及时钟的配置。
RCC模块的主要作用包括:
1.复位控制: STM32F10xxx系列支持多种复位形式,如系统复位、电源复位和备份区域复位。这些复位操作可以通过NRST引脚上的低电平(外部复位)、窗口看门狗计数终止(WWDG复位)、独立看门狗计数终止(IWDG复位)、软件复位(SW复位)或低功耗管理复位等方式触发。系统复位将复位除时钟控制器的RCC_CSR寄存器中的复位标志位和备份区域中的寄存器以外的所有寄存器至其复位状态。
2.时钟配置: 2.时钟配置:RCC模块提供了对时钟源的配置、时钟分频、复位控制等功能。它可以配置主时钟源、系统时钟、AHB总线时钟和APB总线时钟等。通过RCC模块,可以将各种时钟源分配给不同的系统和外设,以满足它们对时钟频率和精度的需求。
3.外设时钟使能:在使用外设模块之前,需要启用相应的外设时钟。RCC模块提供了一系列函数。
如:
RCC_APB2PeriphClockCmd RCC_APB1PeriphClockCmd ,用于启用或禁用外设时钟。这些函数可以确保在需要时向特定外设提供时钟信号,从而使其能够正常工作。
总的来说:RCC模块在STM32单片机中起着至关重要的作用,它负责整个系统的复位和时钟管理,确保系统能够稳定、可靠地运行。

第一步:使用RCC开启GPIO的时钟

首先:
可以在Library中找到rcc.h文件,该文件里面有它能够使用的所有库函数,而我们常用的一般就三个:
1.RCC AHB外设时钟控制
2.RCC APB2外设时钟控制
3.RCC APB1外设时钟控制

在这里插入图片描述

  • 右键可以打开该函数:
    注释部分讲述了该函数的功能。同时里面包含的外设就是你能够通过RCC进行使能的

    在这里插入图片描述

为什么第一步要开启时钟:

  • STM32的时钟系统对于整个微控制器的工作至关重要。时钟系统为STM32提供统一的节拍,就像人的心跳一样,驱动着微控制器内部各个部分按照预定的时序执行相应的指令。具体来说,时钟系统的作用主要体现在以下几个方面:

1. 同步工作:时钟信号为STM32的各个电路模块提供了一个统一的时间基准,使得它们能够按照预定的时序进行工作。例如,CPU核心在时钟的驱动下完成指令执行和状态变换,外设部件(如GPIO端口)在时钟的驱动下完成数据的发送和接收等操作。

2. 控制速度:时钟信号的频率决定了STM32的工作速度。通过调整时钟信号的频率,可以控制STM32的执行效率和功耗。在需要高性能的场景下,可以提高时钟频率以加快执行速度;在需要低功耗的场景下,可以降低时钟频率以降低功耗。

3. 省电设计:STM32的时钟系统采用了时钟门控技术,可以根据需要开启或关闭某个电路模块的时钟。当某个电路模块不需要工作时,关闭其时钟可以节省功耗。这种设计使得STM32在保持高性能的同时,也具有良好的节能性能。

  • 在STM32中,GPIO(通用输入/输出)端口是连接外部设备和微控制器的桥梁。要想使用GPIO端口进行数据的输入和输出,必须先通过RCC(Reset and Clock Control,复位与时钟控制)模块开启其时钟。这是因为GPIO端口的寄存器是由D触发器构成的,而触发器需要时钟信号才能改写其值。只有开启了GPIO的时钟,微控制器才能通过操作寄存器来控制GPIO端口的输入输出状态。因此,在使用GPIO之前,第一步就是使用RCC开启其时钟。

调用RCC的APB2外设时钟控制函数:

  • 本次点灯用的是PA0口,所以对GPIOA的时钟进行使能,打开APB2外设时钟控制函数,在注释里能够看到支持的外设,选择GPIOA放到第一个参数,第二个参数就是使能ENABLE。
    在这里插入图片描述
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);

第二步:使用GPIO_Init函数初始化GPIO

首先:
打开GPIO的.H头文件,就可以看到GPIO_Init函数,这个函数用结构体参数来初始化GPIO口,函数会读取结构体成员然后把外设的参数配置好,这种Init函数在所有外设函数中基本都有。

为什么要用GPIO_Init函数对GPIO口进行初始化:

  • 在STM32中,使用GPIO_Init函数初始化GPIO是点亮LED灯的关键步骤,原因主要有以下几点:

1.配置GPIO引脚属性:GPIO_Init函数用于配置GPIO引脚的各种属性,如输出模式、上拉/下拉电阻、引脚速度等。对于LED灯来说,通常需要将GPIO引脚配置为输出模式,以便能够控制LED灯的亮灭。

2.确保通信正常:通过GPIO_Init函数的正确配置,可以确保STM32微控制器与LED灯之间的通信正常进行。这包括设置正确的引脚速度、避免冲突和干扰等。

3.简化编程:STM32的HAL(硬件抽象层)库中包含了GPIO_Init函数,使得开发者可以更方便地配置GPIO引脚。通过直接使用这个函数,可以避免直接操作寄存器,从而简化编程过程。

4.适应不同需求:GPIO_Init函数允许开发者根据具体需求配置GPIO引脚。例如,对于不同的LED灯或不同的应用场景,可能需要设置不同的引脚速度或上拉/下拉电阻。通过GPIO_Init函数,可以轻松实现这些配置。

因此,在使用STM32点亮LED灯时,需要使用GPIO_Init函数来初始化GPIO引脚,以确保LED灯能够正常工作。同时,还需要注意在程序中正确设置GPIO引脚的状态(高电平或低电平),以控制LED灯的亮灭。

结构体参数的赋值步骤:

2.GPIO_Init函数第二个参数是一个结构体,GPIO_InitTypeDef是一个结构体类型,它是这个结构体的名字,将它赋值下来一会在主函数中创建一个该结构体的变量,然后给这个结构体的变量的成员赋值,再将这个结构体变量的地址作为参数传给GPIO_Init函数。

//这样就创建了一个GPIO_InitTypeDef类型的变量,GPIO_InitTypeDef是一个已经定义好的结构体。GPIO_InitStructure则是一个用GPIO_InitTypeDe定义的结构体变量。
GPIO_InitTypeDef GPIO_InitStructure;

第一步:

  • 创建好一个结构体变量,然后通过点操作符先选择一个成员,右键选择去到该成员的定义处,不要画蓝选中,直接鼠标指到该变量右键就好。我们先看GPIO_Mode,配置好GPIO的工作模式。
GPIO_InitStructure.GPIO_Mode

在这里插入图片描述
第二步:
跳转之后如下图,注意旁边的注释。
在这里插入图片描述
*1.注释 /*!< … / 是一种特殊的多行注释,在Doxygen(一个流行的文档生成工具)中用于生成文档。它通常用于为代码添加额外的描述信息,这些信息可以被Doxygen等工具提取并转换为人类可读的文档。

2.@ref GPIOMode_TypeDef 是一个Doxygen标记,用于创建一个到GPIOMode_TypeDef定义的引用。这意味着,当你查看生成的文档时,你可以通过这个引用直接跳转到GPIOMode_TypeDef的定义部分。

第三步:

  • 那么选中注释中的GPIOMode_TyepeDef,然后CTRL + F可以查找到关于GPIO八种工作模式的选择。
    在这里插入图片描述
  • 跳转到该处就能看到一个枚举类型GPIOMode_TyepeDef,可以看到其中的枚举常量(枚举成员)指定的整数值就是不同的输入输出模式。我们点灯用的是推挽输出,所以赋值Out_PP这一项。这个Out_PP是一个枚举常量,而GPIO_Mode是一个枚举类型GPIOMode_TypeDef的变量。**
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

在这里插入图片描述

其他的GPIO_Pin和GPIO_Speed也是同样的步骤

枚举类型:

  • 枚举类型(Enumeration Type)是一种用户定义的数据类型,允许你为整数值指定一组具名的标识符(也称为枚举成员或枚举常量)。在编程中,枚举类型用于表示固定数量的常量值,这些常量值通常与某种上下文或数据类型相关联。

代码块(1):

typedef enum
{ 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
}GPIOMode_TypeDef;
  • 代码(1)中展示的就是一个枚举类型,其中花括号{}内部的称为枚举成员,花括号结尾的GPIOMode_TypeDef是这个枚举类型的名字。

代码块(2):

typedef struct
{uint16_t GPIO_Pin;             /*!< Specifies the GPIO pins to be configured.This parameter can be any value of @ref GPIO_pins_define */GPIOSpeed_TypeDef GPIO_Speed;  /*!< Specifies the speed for the selected pins.This parameter can be a value of @ref GPIOSpeed_TypeDef */GPIOMode_TypeDef GPIO_Mode;    /*!< Specifies the operating mode for the selected pins.This parameter can be a value of @ref GPIOMode_TypeDef */
}GPIO_InitTypeDef;
  • 在上面这块代码中一共用GPIOSpeed_TypeDef定义了两个枚举变量,分别是GPIO_Speed和GPIO_Mode,于是我们就能够用枚举常量(枚举成员)给这两个变量进行赋值。

注意:

  • 在C语言中,如果枚举成员没有显式地指定整数值,那么它们的值将从0开始递增。在这个例子中,MONDAY 的值为0,TUESDAY 的值为1,依此类推。但是,你也可以显式地为枚举成员指定整数值,就像代码块(2)中已经为每个输出模式的名字指定了整数值。
  • 调用GPIO_Init函数:

//这样就创建了一个GPIO_InitTypeDef类型的变量,GPIO_InitTypeDef是一个已经定义好的结构体。GPIO_InitStructure则是一个用GPIO_InitTypeDe定义的结构体变量。
GPIO_InitTypeDef GPIO_InitStructure;
//接下来对该结构体变量的内部成员进行赋值,然后传给GPIO_Init函数,该函数会读取这些成员变量的值,然后对外设进行配置。
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
//记得这里传的是该结构体变量的地址
GPIO_Init(GPIOA,&GPIO_InitStructure);

当这段代码执行完,这个GPIOA就自动化被配置为推挽输出、50Mhz的速度了。
1.第一个参数是GPIOA,注释中有写该函数的参数和返回值。

GPIO_Init(GPIOA,...)

第三步:使用输出或者输入函数控制GPIO口

在这里插入图片描述
图上是所有GPIO输入或者输出函数,可以直接右键跳转到定义处,根据注释自己使用。
在这里插入图片描述
注释在函数定义的上面,包含简介、参数、返回值。

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

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

相关文章

租赁商城小程序源码部署/售后更新/搭建上线维护

基于ThinkPHPFastAdminUniApp开发的租赁商城小程序&#xff0c;提供用户物品租赁服务的应用程序&#xff0c;方便客户搭建各种类型的租赁场景服务。通过小程序端多角色进行平台管理&#xff0c;用户租赁商品缴纳租金及押金&#xff0c;员工端可操作商品出库和归还&#xff0c;订…

文件夹名批量重命名:一键实现中文到意大利语的高效翻译!文件管理更高效!

文件夹管理成为了我们日常工作和生活中的重要一环。当文件夹名称繁杂且多样&#xff0c;尤其是涉及到不同语言时&#xff0c;如何快速、准确地批量重命名&#xff0c;成为了许多人的迫切需求。今天&#xff0c;我们就来聊聊如何轻松实现文件夹名从中文到意大利语的批量翻译&…

基于FPGA的视频矩阵切换方案

一、单个显示设备的系统方案&#xff1a;会议室只有1个显示设备 会议室的信号源有很多&#xff0c;但是显示设备只有1个&#xff0c;这个时候最佳方案是使用切换器。 &#xff08;1&#xff09;切换器&#xff08;控制方式&#xff1a;遥控器、软件、机箱面板、中控&#xff…

版本控制工具之Git的基础使用教程

Git Git是一个分布式版本控制系统&#xff0c;由Linux之父Linus Torvalds 开发。它既可以用来管理和追踪计算机文件的变化&#xff0c;也是开发者协作编写代码的工具。 本文将介绍 Git 的基础原理、用法、操作等内容。 一、基础概念 1.1 版本控制系统 版本控制系统&#x…

Python-----容器的介绍以及操作

1.列表和元组 1.列表是什么, 元组是什么&#xff1a; 编程中, 经常需要使用变量, 来保存/表示数据. 如果代码中需要表示的数据个数比较少, 我们直接创建多个变量即可. 但是有的时候, 代码中需要表示的数据特别多, 甚至也不知道要表示多少个数据. 这个时候, 就需要用到列表 列表…

论文解读--High-resolution Automotive Radar Point Cloud Imaging and Processing

高分辨汽车雷达点云成像和处理 摘要 汽车雷达具有体积小、硬件成本低、全天候工作、高分辨率等公认的优点&#xff0c;是高级驾驶辅助系统(ADAS)必不可少的一类重要传感器。然而&#xff0c;低角度分辨率和低成像性能的限制很难满足下一阶段ADAS的需要。新兴的4D成像雷达采用多…

SSC369G 双4K高性价比AI IPC方案

一、方案描述 SSC369G 双4K高性价比AI IPC方案采用主芯片SSC369G&#xff0c;内核为CA55四核最高主频为1.5Ghz处理器。SOC内置集成一个64位的四核RISC处理器&#xff0c;先进的图像信号处理器&#xff08;ISP&#xff09;&#xff0c;高性能的H.265/H.264/MJPEG视频编解码器&a…

每日OJ题_记忆化搜索⑤_力扣329. 矩阵中的最长递增路径

目录 力扣329. 矩阵中的最长递增路径 解析代码1_爆搜递归&#xff08;超时&#xff09; 解析代码2_记忆化搜索 力扣329. 矩阵中的最长递增路径 329. 矩阵中的最长递增路径 难度 困难 给定一个 m x n 整数矩阵 matrix &#xff0c;找出其中 最长递增路径 的长度。 对于每…

Linux下多线程相关概念

thread 1.什么是线程1.1 线程优缺点1.2 线程异常1.3 线程用途 2. 进程和线程区别3. 线程控制3.1 POSIX线程库3.2 pthread_create()3.3 线程ID3.4 线程ID地址空间布局pthread_self() 3.5 线程终止pthread_exit函数pthread_cancle函数 3.6 线程等待3.7 分离线程__thread修饰全局变…

Spring Boot | Spring Boot 消息管理 ( 消息中间件 ) 、RabbitMQ“消息中间件“

目录: 一、"消息服务" 概述 :1.1 为什么要使用 "消息服务" ( 消息中间件 ) &#xff1f;① 异步处理② 应用解耦③ 流量削峰④ 分布式事务管理 1.2 常用 "消息中间件" 介绍 :ActiveMQ ( 广泛应用于中小型企业 )RabbitMQ ( 没有特别要求的场景下…

如何利用SSL证书让IP实现HTTPS安全访问

在互联网日益发展的今天&#xff0c;数据安全与隐私保护成为了用户和企业共同关注的焦点。HTTPS&#xff08;超文本传输安全协议&#xff09;作为一种广泛采用的安全通信协议&#xff0c;通过加密数据传输&#xff0c;为网站访问提供了安全保障。然而&#xff0c;要实现HTTPS访…

uniapp百度地图聚合

// loadBMap.js ak 百度key export default function loadBMap(ak) {return new Promise((resolve, reject) > {//聚合API依赖基础库,因此先加载基础库再加载聚合APIasyncLoadBaiduJs(ak).then(() > {// 调用加载第三方组件js公共方法加载其他资源库// 加载聚合API// Ma…

Oracle数据库如何插入平方(²)立方(³)字符

第一步&#xff1a;创建数据表&#xff0c;字段一定要是NVARCHAR2类型的 第二步&#xff0c;插入数据用 unistr(1\00b3) 形式的写法 00b3 代表m&#xff0c;00b2代表㎡ SELECT * FROM TESTABC; UPDATE TESTABC set NAME1unistr(1\00b3); UPDATE TESTABC set NAME2unistr(2\00b2…

【LLM多模态】MiniGPT4模型结构和训练流程

note 图生文应用场景&#xff1a;比如电商领域根据产品图像生成产品描述、娱乐领域中根据电影海报生成电影介绍等MiniGPT-4将预训练的大语言模型和视觉编码器参数同时冻结&#xff0c;只需要单独训练线性投影层&#xff0c;使视觉特征和语言模型对齐。MiniGPT4的视觉编码器&am…

centos 8.5 Node v20.12.2 npm 安装及环境配置 配置淘宝最新镜像地址

1下载&#xff1a;Node.js — Download Node.js 2文件上传到服务器 rootlocalhost software]# tar xvf node-v20.12.2-linux-x64.tar.xz [rootlocalhost software]# mv node-v20.12.2-linux-x64/ /usr/local/node [rootlocalhost software]# vim /etc/profile export PA…

VSCode:设置搜索时的排除目录

VSCode搜索时默认会搜索目录下所有文件 $ tree . ├── a.c ├── m.c └── x └── b.c //a.c #include <stdio.h> #include <string.h>int main() {char s[] "hello\n";fprintf(stdout, s, strlen(s));return 0; } //m.c #include <stdio…

【LSTM】LSTM网络及参数学习笔记

图1 LSTM模型结构可视化 [6]. 图2 LSTM cell结构说明 图3 LSTM cell和num_units说明 [4]. 图4 LSTM的网络结构 1. LSTM 是对一个LSTM层的抽象&#xff0c;可以看成是由多个LSTM cell组成&#xff0c;是包含时间步的一个网络 2. LSTM cell 图2是LSTM在时间步上的结构&#xf…

【硬件开发】原型设计对于成功产品开发重要性及常见阶段

电子产品的设计与开发始于原型制作阶段。这些原型虽可能与最终产品极为相似&#xff0c;但总带有实验性质&#xff0c;因为电子原型的制作过程包括对新概念、新思想及新解决方案的测试。虽然存在出错的风险&#xff0c;跳过这一阶段可能会导致不必要的开支。不擅长电子硬件设计…

2024年想要开一家抖音小店,需要多少钱?一篇详解!

大家好&#xff0c;我是电商糖果 随着抖音卖货的持续火爆&#xff0c;抖音小店也成了电商行业讨论度最大的项目之一。 不少朋友都想知道&#xff0c;如果今年开抖音小店大概需要多少钱。 糖果做小店的时间也比较长&#xff0c;也经营了多家小店。 对于开一家抖音小店需要多…

多规格产品应该如何设置呢?

今天一用户从供应商手中拿到产品价目表&#xff0c;但是设置起来蒙圈了&#xff0c;接下来我们就一起设置一下吧&#xff5e; 一、产品价格表 我们通过供应商手中拿到产品价目表是这个样子的&#xff1a; 我们可以看到此产品的销售客价根据不同地区导致的价格不同&#xff0…