STM32入门教程第二讲

article/2025/8/28 0:50:07

系列文章目录

STM32入门教程第二讲------介绍GPIO


目录

系列文章目录

前言

一、GPIO是什么?

1.简要介绍GPIO

2.GPIO基本结构

二.GPIO的模式介绍 (四种输入四种输出)

1.浮空输入_IN_FLOATING:

​编辑

2. 模拟输入_AIN ​编辑

3带上拉输入_IPU 

4 .带下拉输入_IPD

5.开漏输出_OUT_OD

6.推挽输出_OUT_PP

7.开漏复用输出_AF_OD

8. 推挽复用输出_AF_PP

 三、GPIO的使用步骤

           1.第一步,使用RCC开启GPIO时钟:

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

         3.第三步,使用输出和输入的函数控制GPIO口,以点LED为例:

  



前言

前一篇我们学习了怎么建立一个stm32的keil工程,下面我们来详细介绍GPIO


一、GPIO是什么?

1.简要介绍GPIO

 首先介绍一下GPIO,GPIO(General Input Output)是通用输入输出口,可配置为八种输入输出模式,引脚电平:0—3.3V,部分引脚容忍5V。

输出模式——可控制端口输出高低电平,用以驱动LED,控制蜂鸣器,模拟通信协议输出时序等;

输入模式——可读取端口的高低电平或电压,用于读取按键输入,外界模块电平信号输入,AOC电压采集,模拟通信协议接收数据等。

2.GPIO基本结构

二.GPIO的模式介绍 (四种输入四种输出)

1.浮空输入_IN_FLOATING:


 

当GPIO采用浮空输入模式时,STM32的引脚状态是不确定的,I/O端口的电平信号直接进入输入数据寄存器。此时STM32得到的电平状态完全取决于GPIO外部的电平状态,所以说在GPIO外部的引脚悬空(无信号输入情况下)时,读取该端口的电平状态是个不确定的值。 

通常用于IIC、USART。

2. 模拟输入_AIN 

这个很好理解,最常用的场合是ADC模拟输入,不像其他输入模式只有0和1,模拟输入模式可以读取到很细微变化的值,I/O端口的模拟信号(电压信号,而非电平信号)直接模拟输入到片上外设模块,比如ADC模块等。模拟信号一般:3.3v 5v 9v。 

3带上拉输入_IPU 

 

具有上升沿触发检测的外部中断模式 ,与前面介绍的浮空输入模式相比,仅仅是在数据通道上面,接入了一个上拉电阻,根据STM32的数据手册,这个上拉电阻阻值介于30K~50K 欧姆。同样,CPU可以随时在“输入数据寄存器”的另一端,通过内部的数据总线读出I/O 端口的电平变化的状态

4 .带下拉输入_IPD

 

 下拉输入模式下,I/O端口的电平信号直接进入输入数据寄存器。但是在I/O端口悬空(在无信号输入)的情况下,输入端的电平保持在低电平;并且在I/O端口输入为高电平的时候,输入端的电平也是高电平。

5.开漏输出_OUT_OD

 

开漏输出模式下(上拉电阻+N-MOS管),通过设置位设置/清除寄存器或者输出数据寄存器的值,途经N-MOS管,最终输出到I/O端口。

可以输出0和1,适用于电平不匹配场合,要得到高电平需要上拉电阻才行。

6.推挽输出_OUT_PP

 推挽输出模式下(P-MOS管+N-MOS管),通过设置位设置/清除寄存器或者输出数据寄存器的值,途经P-MOS管和N-MOS管,最终输出到I/O端口。

可以输出高低电平0和1,适用于双向IO使用。

7.开漏复用输出_AF_OD

开漏复用输出模式,与开漏输出模式很是类似。只是输出的高低电平的来源,不是让CPU直接写输出数据寄存器,取而代之利用片上外设模块的复用功能输出来决定的。 

8. 推挽复用输出_AF_PP

推挽复用输出模式,与推挽输出模式很是类似。只是输出的高低电平的来源,不是让CPU直接写输出数据寄存器,取而代之利用片上外设模块的复用功能输出来决定的。 

一句话区分开漏和推挽输出:

推挽输出高低电平都有驱动能力
开漏输出高电平无驱动能力,低电平有驱动能力

 三、GPIO的使用步骤

        1.第一步,使用RCC开启GPIO时钟:

        上代码:

	RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOC,ENABLE);开始RCC时钟

        详细步骤:在libraries中--stm32f10x_rcc.h中:

找到如下库函数的定义: 

是关于GPIO的时钟开启库函数定义,选用哪一个取决于自己的项目需求 

以APB2为例,转到函数定义:

直接上代码:

/*** @brief  Enables or disables the High Speed APB (APB2) peripheral clock.* @param  RCC_APB2Periph: specifies the APB2 peripheral to gates its clock.*   This parameter can be any combination of the following values:*     @arg RCC_APB2Periph_AFIO, RCC_APB2Periph_GPIOA, RCC_APB2Periph_GPIOB,*          RCC_APB2Periph_GPIOC, RCC_APB2Periph_GPIOD, RCC_APB2Periph_GPIOE,*          RCC_APB2Periph_GPIOF, RCC_APB2Periph_GPIOG, RCC_APB2Periph_ADC1,*          RCC_APB2Periph_ADC2, RCC_APB2Periph_TIM1, RCC_APB2Periph_SPI1,*          RCC_APB2Periph_TIM8, RCC_APB2Periph_USART1, RCC_APB2Periph_ADC3,*          RCC_APB2Periph_TIM15, RCC_APB2Periph_TIM16, RCC_APB2Periph_TIM17,*          RCC_APB2Periph_TIM9, RCC_APB2Periph_TIM10, RCC_APB2Periph_TIM11     * @param  NewState: new state of the specified peripheral clock.*   This parameter can be: ENABLE or DISABLE.* @retval None*/
void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState)
{/* Check the parameters */assert_param(IS_RCC_APB2_PERIPH(RCC_APB2Periph));assert_param(IS_FUNCTIONAL_STATE(NewState));if (NewState != DISABLE){RCC->APB2ENR |= RCC_APB2Periph;}else{RCC->APB2ENR &= ~RCC_APB2Periph;}
}

根据使用的I/O确定第一个函数参数,然后ENABLE为第二参数;

时钟启动成功。

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

上代码:

GPIO_Init(GPIOA,&GPIO_InitStructure);

详细步骤:转到GPIO_Init函数定义:

/*** @brief  Initializes the GPIOx peripheral according to the specified*         parameters in the GPIO_InitStruct.* @param  GPIOx: where x can be (A..G) to select the GPIO peripheral.* @param  GPIO_InitStruct: pointer to a GPIO_InitTypeDef structure that*         contains the configuration information for the specified GPIO peripheral.* @retval None*/
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)
{uint32_t currentmode = 0x00, currentpin = 0x00, pinpos = 0x00, pos = 0x00;uint32_t tmpreg = 0x00, pinmask = 0x00;/* Check the parameters */assert_param(IS_GPIO_ALL_PERIPH(GPIOx));assert_param(IS_GPIO_MODE(GPIO_InitStruct->GPIO_Mode));assert_param(IS_GPIO_PIN(GPIO_InitStruct->GPIO_Pin));  

根据使用的I/O确定第一个函数参数,以GPIOA为例,因此第一个参数为GPIOA,根据函数定义,第二个参数需要定义结构体;

上代码:

GPIO_InitTypeDef GPIO_InitStructure;
定义结构体,如果报错268,可以把该行放在RCC时钟上边,放在RCC下边的话需要在编译器魔术棒-C/C++改为C99
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;//推挽输出
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_13;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;

第一行声明结构体后,在下边引出结构体的三个内容 ,下边详细介绍方法:

首先第一个GPIO_ModeGPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;//推挽输出

转到GPIO_Mode定义: 

 GPIOMode_TypeDef GPIO_Mode;  /*!< Specifies the operating mode for the selected pins.This parameter can be a value of @ref GPIOMode_TypeDef*/

继续转到  GPIOMode_TypeDef:

是一个枚举 :

/** * @brief  Configuration Mode enumeration  */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;

根据项目需求选择,以推挽输出为例:选择  GPIO_Mode_Out_PP,因此,Mode搞定。

GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;//推挽输出

同理操作 :GPIO_Pin和GPIO_Speed;

需要注意的是,转GPIO_Pin定义时选择member,如下图:

 全部写好后,结构体定义完成
 

	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就写好了:

	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初始化完成

 3.第三步,使用输出和输入的函数控制GPIO口,以点LED为例:

先上代码:

	GPIO_SetBits(GPIOC,GPIO_Pin_13);//将PC13号口置为高电平		(灯灭)GPIO_ResetBits(GPIOC,GPIO_Pin_13);//将PC13号口置为低电平 (灯亮)

转到函数定义根据项目需求写参数即可,就不详细介绍了,下一期详细讲解控制LED的操作

至此,GPIO介绍完成。


  


http://chatgpt.dhexx.cn/article/Y6pMcgRt.shtml

相关文章

【STM32】串口通信基本原理(超基础、详细版)

STM32F1xx官方资料&#xff1a; 《STM32中文参考手册V10》-第25章通用同步异步收发器&#xff08;USART) 通信接口背景知识 设备之间通信的方式 一般情况下&#xff0c;设备之间的通信方式可以分成并行通信和串行通信两种。它们的区别是&#xff1a; 并、串行通信的区别 并行…

【STM32】HAL库 STM32CubeMX教程四---UART串口通信详解

前言&#xff1a; 今天我们学习STM32CubeMX串口的操作&#xff0c;以及HAL库串口的配置&#xff0c;我们会详细的讲解各个模块的使用和具体功能&#xff0c;并且基于HAL库实现Printf函数功能重定向&#xff0c;UART中断接收&#xff0c;本系列教程将HAL库与STM32CubeMX结合在…

横屏切换视频(iOS基于ZFPlayer 做的横屏上下滑动切换视频的需求)

思路&#xff1a;全屏到某一个视频时把这个视频的上一个和下一个视频一起传到全屏播放页&#xff0c;滑动时通过改变播放器的位置&#xff0c;切换视频&#xff08;说得不清楚&#xff0c;不多说上代码&#xff0c;不理解或者需要详细思路下方留言&#xff09; 1&#xff0c;手…

网络视频播放ZFPlayer

根据项目需要&#xff0c;公司app需要用到视频播放功能&#xff0c;推荐ZFPlayer&#xff0c;视频播放几乎有你想要的任何样式&#xff0c;该博客只是为了给自己留一个以后查找的资料&#xff0c; 改代码可以使用ZFPlayer github地址 https://github.com/renzifeng/ZFPlayer 转…

关于ZFplayer升级3.0以后

之前2.0 版本倍速会有画面缺失的效果,升级了3.0 产品加了个新需求,滑动的时候判断是否之前学过,学过就允许拖拽,没学过就不允许拖拽 最开始我的思路是在这里添加进度条是否允许点击,比如后来发现自己太天真,这样的后果是每次到了这个对应的进度都重新开始,于是路走死了,又想着…

ZFPlayer视频播放PC 安卓都可以正常 播放,iOS端只有声音没有画面(2)

排查方式: 原生的有些视频播放不了&#xff0c;ijk就可以了&#xff0c;我就遇到过[表情][表情]。。如果你是有的能播放&#xff0c;有的不能播放的话,搜用到这个zfplayer的地方,把原生换成ijk 针对本例子就是注释红线地方,打开后面的第3行 2 把有问题的链接下载下来上传到优酷…

iOS--视频播放器之ZFPlayer

2019独角兽企业重金招聘Python工程师标准>>> 还是直接上代码,详情如下: 一.ZFPlayer的导入。pod ZFPlayer,头文件 #import "ZFPlayer.h" 二.在cell中使用图片看得更清晰,代码可以直接复制 图片: .h文件 .m文件 代码: // // CellShowController.h // Te…

ios 按位运算---分解ZFPlayer

按位与&&#xff08;位运算时&#xff0c;相同为1&#xff0c;不同为0&#xff09; 按位或 |&#xff08;位运算时&#xff0c;有1为1&#xff0c;全0为0&#xff09; 按位异或 ^&#xff08;位运算时&#xff0c;相同为0&#xff0c;不同为1&#xff09; 按位取反~&#x…

ios 视频列表处理---分解ZFPlayer

1.视频播放器添加到containerView的机制与一个普通播放器页面的不同 普通视频播放页面可以直接添加一个播放器&#xff0c;按照正常逻辑播放、暂停、切换等操作&#xff0c;而视频列表的做法是 用户触发播放动作 当点击一个cell上的播放按钮时&#xff0c;首先判断当前是否有其…

iOS16灵动岛横屏视频播放适配(ZFPlayer)

项目场景&#xff1a; 手机为iphone14Pro 版本iOS16.0.3 Xcode版本14.2 视频播放第三方库ZFPlayer 问题描述 使用视频时&#xff0c;视频播放自动横屏控制层的返回按钮和暂停按钮都点不到&#xff0c;上图错误、下图正确&#xff08;控制按钮距离屏幕左右减小50、视频全屏不做…

ZFPlayer视频播放PC 安卓都可以正常 播放,iOS端只有声音没有画面

1.添加视频&#xff0c;选择MP4格式 2.设置输出配置&#xff0c;并选择输出文件夹&#xff0c;视频编码为AVC(H264)&#xff0c;屏幕大小调整为720*480 3&#xff0c;点击开始 视频会出现在指定文件夹。可配置自定义文件夹 用格式工厂帮忙转个格式可以得出能播放和不能播放的区…

ZFPlayer 源码解读

源码下载地址&#xff1a;https://github.com/renzifeng/ZFPlayer 之前自己实现过一个模仿百思不得姐的demo https://github.com/agelessman/FFmpegAndKxmovieDemo 由于有朋友推荐&#xff0c;看了下ZFPlayer&#xff0c;觉得功能和封装都写的很好&#xff0c;就把源码看了一遍…

iOS开发-ZFPlayer的简单使用 播放单个网络视频

iOS开发-ZFPlayer的简单使用 播放单个网络视频 前言开发准备代码注意 前言 关于ZFPlayer播放单个网络视频案例&#xff0c;它的网络列表视频案例在gitHub上面很多。 开发准备 podfile导入 pod ZFPlayer, ~> 3.3.3 #, ~> 3.2.17 # 视频播放 pod ZFPlayer/ControlView p…

关于ZFPlayer集成播放 rtmp 视频流的总结

最近公司项目需要能够播放 rtmp 格式的直播流地址的播放器,安卓那边是买了人家的三方库,EasyPlayer,但是不想再买一个 ios 的了所以需要自己去找免费的合适的播放器去集成,终于在 github 上找到一个合适的了,那就是 强大的IJKPlayer 播放器;但在集成的时候出现了一些问题,朋友推…

ZFPlayer 播放器调用addPlayerViewToSmallFloatView开小窗播放样式错误以及无法关闭处理

ZFPLayer 是一款强大开源的视频播放器&#xff0c;在结合列表播放滑动超出当前视频范围调用 addPlayerViewToSmallFloatView开启小窗播放(类似画中画&#xff0c;但没有其强大和友好的交互)布局错误并且右上角的关闭按钮也没法关闭&#xff0c;错乱参考图如下&#xff1a; 1、样…

ios html zfplayer,【iOS】ZFPlayer源码解读中

前言 本篇继ZFPlayer源码解读基础之上&#xff0c;主要解析说明控制层与播放器&#xff0c;因为在上篇文章至现在并未提及丝毫关于这两个类业务的实现。 首先说下这两个类各自的职责。 控制层&#xff1a;主要负责响应与用户之间的交互&#xff0c;如手势控制的播放&#xff0c…

ZFPlayer iOS16 系统横屏全屏问题处理

iOS16 以后 通过原始横屏的方法已经不好使了&#xff0c;需要在此基础上添加 setNeedsUpdateOfSupportedInterfaceOrientations 方法的调用&#xff0c;具体API 描述如下&#xff1a; 回到主题&#xff0c;在使用ZFPlayer 视频库全屏播放时iOS16系统下的处理参考如下&#xff…

iOS使用ZFPlayer 实现视频播放

文章目录 ZFPlayer 视频播放使用1 创建 ZFAVPlayerManager 对象2创建containerView, 也就是视频视图的父视图3 创建 controllView4 创建 ZFPlayerController播放视频判断视频的横竖 ZFPlayer 视频播放使用 1 创建 ZFAVPlayerManager 对象 ZFAVPlayerManager *manager [[ZFAVP…

配置分离式LANP源代码编译实例

一、php编译 配置apache-2.4.9以fpm方式的php-5.4.26&#xff08;php服务器IP为172.16.3.30&#xff09; 1、编译php #tar xf php-5.4.26.tar.bz2 #cd php-5.4.26 # ./configure --prefix/usr/local/php --with-mysql/usr/l…

Centos使用Docker搭建Lanp环境

前言 LAMP 指的Linux(操作系统)、ApacheHTTP服务器&#xff0c;MySQL(有时也指MariaDB&#xff0c;数据库软件) 和 PHP(有时也是指Perl或Python)的第一个字母&#xff0c;集成环境方便&#xff0c;一般用来建立web应用平台 Docker 是一个开源的应用容器引擎&#xff0c;在doc…