当前位置: 首页 > news >正文

GPIO端口的使用

目录

一. 前言

二. APB2外设时钟使能寄存器

三. GPIO端口的描述

四. GPIO端口使用案例


一. 前言

        基于库函数的开发方式就是使用ST官方提供的封装好的函数。而如果没有添加库函数,那就是基于寄存器的开发方式,这种方式一般不是很推荐。因为由于ST对寄存器封装的比较好,所以使用库函数的方法,既能满足对寄存器的配置,对开发人员也比较友好,有利于提高开发效率。

并且提一下,我们所讲的都是以STM32F10单片机系列作为案例来讲的。

今天我们所讲的GPIO都是APB2的外设,所谓APB2也就是桥接1。

二. APB2外设时钟使能寄存器

        因为我们GPIO都是APB2的外设,并且要想使用我们的STM32单片机,就都得先开时钟,这是为了降低能耗。这在我关于深入了解STM32单片机博客中也有提到的。

APB2外设复位寄存器也就是RCC_APB2ENR。我们通过查询手册就可以得到如下信息:

举个例子,当我们想开启GPIOC端口的时候,我们就可以这样设置:

RCC_APB2ENR=0x00000010;

这样就开启了GPIOC的时钟使能。因为我们这里总共有32位,用16进制表示就有8个数字,而GPIOC的位置在倒数第二个数,并且它的值为1。学会查看并使用STM32手册对于我们来说是非常重要的,我们都需要具备这种能力。

由于我们的GPIO口用不到APB1外设时钟使能寄存器,这里我就不介绍了,想了解的小伙伴可以去查询下STM32F10xxx参考手册。

三. GPIO端口的描述

        每个GPIO端口都有两个32位配置寄存器(GPIOx_CRL,GPIOx_CRH),两个32位数据寄存器(GPIOx_IDR,GPIOx_ODR),一个32位置位/复位寄存器(GPIOx_BSRR),一个16位复位寄存器(GPIOx_BRR)和一个32位锁定寄存器(GPIOx_LCKR)。

关于以上函数的使用说明,我们都可以使用手册来查询,如下所示:

我们只需要在上面书签查找处输入我们想要查询的内容,就可以得到相关使用说明了。大家慢慢培养这个习惯,就会使用芯片参考手册了。

 这里还需要讲下GPIO端口的八种输入输出模式,在输出模式下可控制端口输出高低电平,用以驱动LED,控制蜂鸣器,模拟通信协议输出时序等。在输入模式下则可读取端口的高低电平或电压,用于读取按键输入,外接模块电平信号输入,ADC电压采集,模拟通信协议接受数据等。

八种输入输出模式如下所示:

  1. 浮空输入:可读取引脚电平,若引脚悬空,则电平不确定。
  2. 上拉输入:可读取引脚电平,内部连接上拉电阻,悬空时默认高电平。
  3. 下拉输入:可读取引脚电平,内部连接下拉电阻,悬空时默认低电平。
  4. 模拟输入:GPIO无效,引脚直接接入内部ADC。
  5. 开漏输出:可输出引脚电平,高电平为高阻态,低电平接VSS
  6. 推挽输出:可输出引脚电平,高电平接VDD,低电平接VSS
  7. 复用开漏输出:由片上外设控制,高电平为高阻态,低电平接VSS
  8. 复用推挽输出:由片上外设控制,高电平接VDD,低电平接VSS

 值得注意的是,一个端口只能有一个输出,但可以有多个输入,也就是说为输入模式时,输出模式无效。

提到GPIO的描述,就不得不提及GPIO的位结构了,关于GPIO详细的位结构,感兴趣的小伙伴可自行在网上查找,很容易找到的。这里我主要讲下几个难以让人理解的。在GPIO位结构中,接了两个保护二极管,这个是对输入电压进行限幅的。

其中施密特触发器的作用就是对输入电压进行整形的,它的执行逻辑是,如果输入电压大于某一阈值,输出就会瞬间升为高电平。反之则相反。并且对于施密特触发器来说,只有高于上限或者低于下限,输出才会变化。

其中的MOS管就是一种电子开关,我们的信号来控制开关的导通和关闭,开关负责将IO口接到VDD或者VSS。

四. GPIO端口使用案例

        为了方便大家理解,我们这里举两个使用GPIO端口的示例。分别是LED流水灯和蜂鸣器的使用。

这里简单介绍下这两种东西,LED就是一种发光二极管,正向通电点亮,反向通电不亮。

蜂鸣器有两种,一种是有源蜂鸣器,另外一种则就是无源蜂鸣器。其中有源蜂鸣器就是内部自带振荡源,将正负极接上直流电压即可持续发声,频率固定。无源蜂鸣器则是内部不带振荡源,需要控制器提供振荡脉冲才可发声,调整提供振荡脉冲的频率,可发出不同频率的声音。

由于要使用到GPIO口,并且使用的是库函数的开发方式,所以就不得不提下关于GPIO口的几个常用库函数了。这里简要介绍下,给大家留个印象,如果想深入了解,可以查询手册。

首先是GPIO_DeInit()函数,是用来复位GPIO外设的。

GPIO_ResetBits()函数和GPIO_SetBits()函数是用来设置端口状态和初值的。

GPIO_WriteBit()和GPIO_Write()两个函数作用跟上面两个函数差不多。在使用时,可点击鼠标右键来查看函数参数该如何设置。

看到这里,不知道大家有没有注意到GPIO_ResetBits()等函数后面都有一个s,代表可以同时设置多个端口的状态。

下面我们来看下LED流水灯实现代码:

#include "stm32f10x.h"                  // Device header
#include "delay.h"
int main(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Pin=GPIO_Pin_All;GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);while(1){ //LED流水灯闪烁代码GPIO_Write(GPIOA,~0x0001);	//0000 0000 0000 0001Delay_ms(100);GPIO_Write(GPIOA,~0x0002);  //0000 0000 0000 0010Delay_ms(100);GPIO_Write(GPIOA,~0x0004);	//0000 0000 0000 0100Delay_ms(100);GPIO_Write(GPIOA,~0x0008);	//0000 0000 0000 1000Delay_ms(100);GPIO_Write(GPIOA,~0x0010);	//0000 0000 0001 0000Delay_ms(100);GPIO_Write(GPIOA,~0x0021);	//0000 0000 0010 0000Delay_ms(100);GPIO_Write(GPIOA,~0x0041);	//0000 0000 0100 0000Delay_ms(100);GPIO_Write(GPIOA,~0x0081);	//0000 0000 1000 0000Delay_ms(100);}}

下面我们再来看下实际效果:

 

下面我们再来看下关于蜂鸣器的相关源代码:

#include "stm32f10x.h"                  // Device header
#include "delay.h"
int main(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Pin=GPIO_Pin_12;GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz;GPIO_Init(GPIOB,&GPIO_InitStructure);while(1){ GPIO_ResetBits(GPIOB,GPIO_Pin_12);Delay_ms(100);GPIO_SetBits(GPIOB,GPIO_Pin_12);Delay_ms(100);GPIO_ResetBits(GPIOB,GPIO_Pin_12);Delay_ms(100);GPIO_SetBits(GPIOB,GPIO_Pin_12);Delay_ms(700);}
}

 

至于关于STM32F10参考手册,我已经放在了百度网盘中,如下:

 链接:https://pan.baidu.com/s/1zrtAtLYEEnBNZ1QsuvvdNQ 
提取码:3wjv

 

        

        

相关文章:

  • 牛客周赛 Round 61(思维、组合数)
  • 关于三维布尔运算的思考(2)
  • 深入理解 WebSocket:实时通信的利器
  • 如何使用 DomCrawler 进行复杂的网页数据抓取?
  • InnoDB架构
  • Mavn解决依赖不重新下载,主动下载依赖
  • 什么?你想通过网络安全月入千万?看看AI的回答(包含注释版)
  • 自动化学习3:日志记录及测试报告的生成--自动化框架搭建
  • Django 数据库配置以及字段设置详解
  • 深入理解 Nuxt.js 中的 app:created 钩子
  • 打造备份一体机,群晖科技平台化战略再进阶
  • 网络安全科普之网络钓鱼,零基础入门到精通,收藏这一篇就够了
  • 栅极控制技术是什么?(MOSFET、IGBT)
  • 如何使用Kimi编写商品管理设计文档:包含流程图和用例图
  • OIDC6-OIDC 授权流程类型
  • 【mysql】环境安装、服务启动、密码设置
  • 2017届校招提前批面试回顾
  • cookie和session
  • CSS3 变换
  • JavaScript 是如何工作的:WebRTC 和对等网络的机制!
  • java中的hashCode
  • SOFAMosn配置模型
  • Spark in action on Kubernetes - Playground搭建与架构浅析
  • VUE es6技巧写法(持续更新中~~~)
  • 读懂package.json -- 依赖管理
  • 工作中总结前端开发流程--vue项目
  • 如何优雅的使用vue+Dcloud(Hbuild)开发混合app
  • 如何优雅地使用 Sublime Text
  • 用简单代码看卷积组块发展
  • ​人工智能之父图灵诞辰纪念日,一起来看最受读者欢迎的AI技术好书
  • (145)光线追踪距离场柔和阴影
  • (二十六)Java 数据结构
  • (南京观海微电子)——I3C协议介绍
  • (七)MySQL是如何将LRU链表的使用性能优化到极致的?
  • (三)Pytorch快速搭建卷积神经网络模型实现手写数字识别(代码+详细注解)
  • (算法)求1到1亿间的质数或素数
  • (一)pytest自动化测试框架之生成测试报告(mac系统)
  • (自适应手机端)响应式服装服饰外贸企业网站模板
  • .MSSQLSERVER 导入导出 命令集--堪称经典,值得借鉴!
  • .Net 6.0 处理跨域的方式
  • .Net 8.0 新的变化
  • .net core Swagger 过滤部分Api
  • .net core 连接数据库,通过数据库生成Modell
  • .NET Core使用NPOI导出复杂,美观的Excel详解
  • .NET Framework 3.5中序列化成JSON数据及JSON数据的反序列化,以及jQuery的调用JSON
  • .NET/C# 编译期间能确定的相同字符串,在运行期间是相同的实例
  • .NET/C# 使用反射注册事件
  • .NetCore Flurl.Http 升级到4.0后 https 无法建立SSL连接
  • .net中的Queue和Stack
  • @Transactional事务注解内含乾坤?
  • [<MySQL优化总结>]
  • [AI资讯·0612] AI测试高考物理题,最高准确率100%,OpenAI与苹果合作,将ChatGPT融入系统中,大模型在物理领域应用潜力显现
  • [Android]将私钥(.pk8)和公钥证书(.pem/.crt)合并成一个PKCS#12格式的密钥库文件
  • [C++] cout、wcout无法正常输出中文字符问题的深入调查(1):各种编译器测试
  • [C++进阶篇]STL中vector的使用