【CH32】| 02——常用外设 | GPIO
系列文章目录
【CH32】| 00——开发环境搭建
【CH32】| 01——新建工程 | 下载 | 运行 |调试
【CH32】| 02——常用外设 | GPIO
失败了也挺可爱,成功了就超帅。 |
文章目录
- 前言
- 1. GPIO简介
- 2. IO口的内部结构框图
- 保护二极管
- 上下拉电阻
- 施密特触发器
- 两个MOS管
- 输出寄存器和输入寄存器
- 3. GPIO的几种模式
- 3.1 输入
- 模拟输入
- 浮空输入
- 上拉输入
- 下拉输入
- 3.2 输出
- 推挽输出
- 开漏输出
- 复用推挽/开漏输出
- 4. GPIO模式如何选择
- 5. 引脚的复用功能
- 6. 引脚产生的中断 | 外部中断
- 7. 引脚的锁定机制
- 8. GPIO相关寄存器
- 配置寄存器低位 GPIOx_CFGLR
- 端口输入寄存器 GPIOx_INDR
- 端口输出寄存器 GPIOx_OURDR
- 端口复位/置位寄存器 GPIOx_BSHR
- 端口复位寄存器 GPIOx_BCR
- 配置锁存寄存器 GPIOx_LCKR
- 9. 实践(代码篇)
- 9.1 点灯前
- 看查原理图 LED灯的电路 及控制引脚
- 9.2 寄存器操作——点灯
- 9.3 库函数操作——点灯
前言
白嫖了开发板那不得做些事情。现在好多刚入门单片机的都是从库函数入手的 大多教程也是库函数的 这样导致对一些底层怎么实现的不是很清楚。我在学习的时候 老师强烈要求寄存器 然后在学完stm32后 用一些其他单片机也是很容易上手的。所以我就通过带大家看寄存器以及库函数的底层实现深入了解各个外设。
1. GPIO简介
GPIO就是引脚,我们在使用引脚时根据作用 应配置了其模式再去使用。通过看它的参考手册(最好的资料) 了解到GPIO可以配置为很多模式。和stm32一模一样。毕竟抄的 这点可以理解 这样我们再用这个芯片可以无缝上手。当然它也有些自已的特点啦。
2. IO口的内部结构框图
先简单认识下它内部结构
保护二极管
IO进来之后遇到的第一个就是保护二极管。这两个二极管的作用就是 引脚外部电压过高/过低时 这两个二极管对其进行电压钳位 电压不会流通到后面 从而保护引脚
上下拉电阻
这组上拉下拉电阻的作用给IO口配置默认电平 拉高/拉低如果没有上拉/下拉操作 那么这个引脚是出于浮空状态的也就说会受外界因素干扰 。一般单片机复位后大多数IO口都是处于浮空状态的。通过上拉 给IO口一个高电平 ,下拉给IO低电平。让IO口有一个明确的状态。
施密特触发器
施密特触发器就是 电压高于某个值 输出变为高电平 低于某个值 输出变为低电平。
两个MOS管
输出模式下有两个Mos管
一个PMOS 一个NMOS 他两是让其具有推挽输出和开漏输出的关键。后面详细说。
输出寄存器和输入寄存器
我们操作单片机 也是通过操作相关寄存器实现相关功能的。寄存器就是我们和机器交互的桥梁 我们不需要管它之后时怎么操作的 只需要配置设置寄存器让他去执行就和。在这里我们通过配置GPIO 输出 和输入 寄存器 来配置IO口模式以及IO输出高低电平。
3. GPIO的几种模式
引脚 无非 输入、输出两大类
3.1 输入
IO配置为输入模式时 是没有复用功能的
模拟输入
模拟输入:一般 ADC采集时 配置为该模式,ADC即采集模拟信号所以 不会经过施密特触发器
浮空输入
浮空输入:在系统复位后 大多数引脚处于该状态 很容易受外部干扰 这种状态下引脚处于不确定状态 不是高电平也不是低电平 一般测得电压1.几V 还不停变化。
上拉输入
上拉输入:引脚电平拉为高电平(=VDD) 该模式可以确定引脚默认状态 处于高电平 逻辑1 。一般使用在需要检测外部 信号是 低电平有效的情况下 比如 按键检测(低电平有效、某些低电平有效的数字输出传感器)
注意:芯片内部上拉 电流能力很弱 在需要电流高的情况下 外接上拉。
下拉输入
下拉输入: 设置引脚默认电平为 低电平(VSS) 逻辑0 0V
一般用在检测高电平有效的情况下。
3.2 输出
推挽输出
PMOS管相当于NPN三极管 NMOS相当于PNP三极管 动图通过正弦波 模拟高低电平切换时电流的流向。
当输出控制 IN输出高电平时,PMOS管导通,NMOS截至 OUT输出高电平。这种情况我们也称为推(灌电流)。
当输出控制 IN输出低电平时,NMOS管导通,PMOS截至 OUT输出低电平。这种情况我们也称为挽(拉电流)。
推挽输出的优点
1、可以快速输出(切换)高低电平
2、驱动能力较强,一般IO口驱动电流可以达到20ma
缺点
不能线与(两个推挽输出IO不能接一起) 推挽时线与等于直接短接VCC和地 会烧了芯片。
推挽输出使用场景:
一般用在需要快速切断的状态 驱动LED 驱动一些数字芯片控制引脚
开漏输出
开漏输出只有一个NMOS管 在工作
当漏输出 通过上拉实现高电平输出能力 输出的高电平=VDD电压 驱动能力和上拉电阻有关。
开漏输出的特点:
可以线与(该模式多个引脚可以连载一起) 可以通过上拉电阻实现 电平转换 电平切换速度也和电阻相关
开漏输出一般用在一些总线信号线比如I2C、电机驱动器信号线等
复用推挽/开漏输出
IO除了本身功能 还可以复用其他功能( 好比我这个IO口 通过复用实现ADC输入引脚的功能等)。在这种复用情况下使用开漏/推挽。
4. GPIO模式如何选择
官方参考手册给出了推荐配置 P52页 我只截取了一部分
5. 引脚的复用功能
一个IO口除了作为普通引脚 用作输入输出外 还可以有其他功能 我们把这个赋予引脚其他功能的操作叫做复用(重映射) 一个IO口可以复用多个功能
引脚映射有 默认映射 部分 完全三种 不同的映射 让引脚实现不同的作用
可以看到 复用功能 可以通过 不同的重映射方式 选择好多引脚
其他重映射 P57
6. 引脚产生的中断 | 外部中断
所以IO口都可以配置为外部中断模式。就是将一个中断线 绑定到引脚上 中短线是由编号的 需要和 IO口的对应
比如我 PA1 PB1 PC1 三个端口 他们序号是 1 做外部中断时 是绑定到 中断线1 上的 EXTI1 PC2 即 绑定到EXTI2上的 必须对应。
7. 引脚的锁定机制
可以让IO口处于锁定状态。无法被修改。只有复位后才可修改。
如何锁定;通过给引脚写1或0完成 锁定时序。 比如:让这个引脚写1 写1 读1 读0 类似
8. GPIO相关寄存器
每个外设的寄存器都有一个基地址(起始地址) 。即这个外设寄存器有固定范围。一个外设有又好几个寄存器 这些是在基地址基础上偏移得到。
我们GPIO也是一样的 不同端口有不同的基地
它的地址在哪看 参考手册
如图该芯片 GPIO 不同端口的基地址
GPIO相关寄存器名称即地址如下
下面我们详细介绍相关寄存器
配置寄存器低位 GPIOx_CFGLR
为什么叫配置寄存器低位 因为我手里这个芯片CHV003 一个端口 只有8个引脚 如PA0-7 一个配置寄存器是32位4字节 负责8个IO 引脚更多的芯片 就有配置寄存器高位 (一个端口 16个IO口)
那么具体怎么写呢
eg: 配置PA1为推挽输出 速度为50MHZ
1、可以看到一个IO口由 MODE CNF 一共四位配置 MODE[1:0]这两位在低位
2、配置PA1 A端口引脚 是不是要通过配置A端口的配置寄存器
GPIOA_CFGLR
3、要配置为输出模式 速度50MHZ
MODE和CNF时配套的 可以看到 由8组 序号是从0-7它对应8个引脚0-7
我们是PA1 那么 要设置 CNF1 MODE1 这四位
输出模式 50MHZ MODE1[1:0] =0x3或3; 3 就是二进制11
推挽输出 CNF1[1:0]=0x00或0;二进制00
合在一起 二进制 0011 是不是就是十进制3;
4、将设置值给这个寄存器
GPIOA_CFGLR | = 3<<4; 因为我们是PA1 相当于第二个引脚 一个引脚用4位 所以<<4bit
端口输入寄存器 GPIOx_INDR
相当于 读 获取引脚电平
可以看到 只用到低8位 因为我们芯片一个端口8个IO 每1位对应我们1个IO的电平 IDR0位 对应 编号0的IO的电平
获取引脚电平 通过读引脚对应 该寄存器的位
eg:读 PC6 IO口的电平
if(GPIOC_INDR&(1<<6)==1) 如果GPIOC INDR寄存器第6位为1 则PC6为高电平 反则低电平
端口输出寄存器 GPIOx_OURDR
这个寄存器就是 让这个IO输出 高电平还是低电平 如果IO是输入模式 可以让其设置默认电平为高还是低
eg: 设置PD4 输出高电平
GPIOD_OUTDR|=1<<4; 第四位设置为1 即 PD4输出高电平
端口复位/置位寄存器 GPIOx_BSHR
复位/置位 复位等价于输出低 置位等价于 输出高
可以看到如果 BS BR同时设置了 BS起效即 输出高起效果
eg: PC1 复位(清除/输出低)
GPIOC_BSHR |=1<<17; 复位是设置 BR位
eg: PC1 置位(输出高)
GPIOC_BSHR |=1<<1; 置位是设置 BS位
端口复位寄存器 GPIOx_BCR
和BSHR比较来说 这个只有复位(清除的功能)
操作和上面是一样的
配置锁存寄存器 GPIOx_LCKR
锁定IO配置的
锁定IO 让其无法被改变 后面代码详细说明
复用相关的寄存器 后面用到时候再说 初步看了这些寄存器 我们开始实操
9. 实践(代码篇)
9.1 点灯前
看查原理图 LED灯的电路 及控制引脚
我这里选择通过 PC1控制LED1 所以用杜邦线吧PC1端口和LED1连接起来
9.2 寄存器操作——点灯
1、定义PC端口相关寄存器
通过看手册 我们知道PORT C端口的起始地址
0X400011000
定义C端口 寄存器的地址(基地址)
因为库里已经定义了 GPIOC_BASE这种名字 我这里 后面加个杠
定义C端口 相关寄存器的地址
或者看具体寄存器描述上 有在基地址基础上的偏移地址
操作寄存器 相当于操作地址 所以我们需要使用指针
2、使能时钟 在使用GPIOC 前需要开GPIOC的时钟 这样GPIOC才会有作用
无论使用什么外设 在使用前都需要开相应的时钟 该外设才会生效
寄存器地址定义方式一样的
3、配置IO口模式 配置PC1为推挽输出 50MHZ
4、控制IO口(输出高低电平)
5、全部代码
6、LED闪烁
9.3 库函数操作——点灯
通过上面我们已经对相关寄存器很清楚了 库把寄存器操作封装成了函数 这样方便我们快速使用不用 看手册 查寄存器。
1、我们先看看库是怎么实现的
它也定义了寄存器地址
可以看到它通过结构体定义了 相关寄存器 然后不同端口的定义 只是将 端口地址给到这个结构体 通过这样的方式 实现不同端口访问相应寄存器 这个操作有C基础肯定可以看到就不说拉
这样情况下 访问寄存器 GPIOC->CFGLR |=3<<4;
接下来我们看看 GPIO相关操作函数是如何实现的
先来看初始化函数
可以看到 底层还是操作寄存器的
大家有兴趣可以 看下其他都是怎么写的
2、点灯
如果第一次接触如何你找这些函数
就去对应 .h头文件看函数
相关文章:

【CH32】| 02——常用外设 | GPIO
系列文章目录 【CH32】| 00——开发环境搭建 【CH32】| 01——新建工程 | 下载 | 运行 |调试 【CH32】| 02——常用外设 | GPIO 失败了也挺可爱,成功了就超帅。 文章目录 前言1. GPIO简介2. IO口的内部结构框图保护二极管上下拉电阻施密特触发器两个MOS管输出寄存器…...

第四章 测试用例编
本科程目标 1.什么是测试用例 2.测试用例的重要性 3.测试用例的八大要素(重点) 4.测试用例的评审 一、什么叫软件测试用例 测试用例(TestCase)是为项目需求而编制的一组测试输入、执行条件以及预期结果,以便测试…...

解决dpdk reserve的内存返回的虚拟地址和iova地址一样的问题
1. 背景: 在ubuntu20.04上用dpdk API: rte_memzone_reserve_aligned("L1L2_PCIE_MEMORY", 1.5*1024*1024*1024, rte_socket_id(), RTE_MEMZONE_1GB|RTE_MEMZONE_IOVA_CONTIG, RTE_CACHE_LINE_SIZE); 分配1.5…...

JQuery实现小项目
博主简介:想进大厂的打工人博主主页:xyk:所属专栏: JavaEE初阶 目录 文章目录 一、JQuery是什么 二、JQuery项目 2.1 猜数字 2.2 表白墙 2.3 聚合搜索 2.4 计算器 一、JQuery是什么 jQuery是一个快速、简洁的JavaScript框架,是继Prototype之…...

【C++/嵌入式笔试面试八股】一、23.结构体指针 | 指针和引用 | 万能指针 | 野指针
结构体指针 28.将结构体作为参数向函数中传递 传递方式有两种: 值传递地址传递,利用操作符 -> 可以通过结构体指针访问结构体属性//学生结构体定义 struct student {//成员列表string name; //姓名int age; //年龄int score; //分数 };//值传递...

【C++初阶】类和对象(下)构造函数(初始化列表) + explicit关键字 +static成员
👦个人主页:Weraphael ✍🏻作者简介:目前学习C和算法 ✈️专栏:C航路 🐋 希望大家多多支持,咱一起进步!😁 如果文章对你有帮助的话 欢迎 评论💬 点赞…...

chatgpt赋能python:Python代码怎么用?一个10年编程经验工程师的实践总结
Python代码怎么用?一个10年编程经验工程师的实践总结 如果你正在学习Python或已经是一名Python开发者,你需要知道如何正确地使用Python代码以实现项目需求。在本文中,我将分享我的10年Python编程经验,并介绍一些关于如何使用Pyth…...

【Android定制】修改BUILD_AGO_GMS = no 和 BUILD_GMS=no属性
文章目录 概要名词解释细节小结 概要 在安卓底层源码中,有这样的两个属性,这两个第一眼看上去都像是带不带谷歌,BUILD_AGO_GMS no和BUILD_GMSno有什么区别?? 如果带了谷歌,那么这个设备就差不多是国外定…...

第十章:C语言的调试
很多小伙伴刚开始听到C语言的调试,这是个啥,表示很怀疑,敲代码不就是直接就是干嘛,结果很多小白们,一运行错误多的数都数不过来。就开始这改改,那删删,莫名奇妙就运行成功了。到最后都不知道到底…...

【20】SCI易中期刊推荐——计算机信息系统工程电子与电气(中科院3区)
💖💖>>>加勒比海带,QQ2479200884<<<💖💖 🍀🍀>>>【YOLO魔法搭配&论文投稿咨询】<<<🍀🍀 ✨✨>>>学习交流 | 温澜潮生 | 合作共赢 | 共同进步<<<✨✨ 📚📚>>>人工智能 | 计算机视觉…...

初识网络之UDP网络套接字
目录 一、UDP中的socket编程常用接口 1. socket的含义 2. sockaddr结构 3. socket编程中UDP协议常用接口介绍 3.1 创建socket文件描述符(TCP/UDP、客户端 服务器) 3.2 绑定端口号(TCP/UDP,服务器) 3.3 接收数据…...

数据中心末端配电的数字化方案及设备选型
普通PDU和智能PDU有什么区别? 机架安装配电盘或机架配电单元 (PDU) 是一种配备许多插座的设备,可将电力分配给位于数据中心机架或机柜内的服务器、存储设备和网络设备。领先的分析公司 IHS 将它们分为两大类: 1) 基本 PDU 提供可靠的配电。 2…...

k8s入门实战-Service
k8s入门实战-Service Service 和 Label Service 通过一组 Pod 路由通信。Service 是一种抽象,它允许 Pod 死亡并在 Kubernetes 中复制,而不会影响应用程序。在依赖的 Pod (如应用程序中的前端和后端组件)之间进行发现和路由是由Kubernetes Service 处理…...

Python量化交易:策略创建运行流程
学习目标 目标 知道策略的创建和运行知道策略的相关设置知道RQ的策略运行流程应用 无 1、体验创建策略、运行策略流程 1.1 创建策略 1.2 策略界面 2、 策略界面功能、运行介绍 2.1 一个完整的策略需要做的事情 选择策略的运行信息: 选择运行区间和初始资金选择回…...

企业该如何自主构建信息化管理系统?
实践证明,企业自己搭建的信息化系统灵活性更高,更能契合企业的需求。 我们可以借助零代码平台自主搭建,既提供了各个应用系统的标准化功能,又支持自定义搭建,可根据企业自身需求修改。 全球领先的信息技术研究和顾问公…...

linuxOPS基础_操作系统概述
计算机发展史 第一台计算机是1946 年2 月14 日诞生日,第一台名称ENIAC。体积一间屋子的大小,重量高达28t。 第一代:1946 – 1958 > 12 年 (电子管) 第二代:1958 – 1964 > 6 年 (晶体管…...

常用adb命令记录下
adb root 获取root 权限(以root权限运行ADB守护程序)adb remount 以读写方式重新挂载设备的文件系统adb reboot 重启设备adb devices 查看当前连接设备adb get-serialno 获取设备的序列号adb backup 备份设备的应用程序和数据adb bugreport 收集设备的当前状态信息以进行故障排…...

Etcdctl 命令v3
一、v3必须导出环境变量 export ETCDCTL_API3 二、查看版本 etcdctl version 三、写入键 1.基本 etcdctl put foo bar 2.绑定租约 etcdctl put foo bar --leasexxxx 四、获取键 1.基本 etcdctl get foo 2.按十六进制获取 etcdctl get foo --hex 3.只读取键值 et…...

第二十一章 开发Productions - ObjectScript Productions - 延迟发送
文章目录 第二十一章 开发Productions - ObjectScript Productions - 延迟发送延迟发送 生成事件日志条目在 ObjectScript 中生成事件日志条目 第二十一章 开发Productions - ObjectScript Productions - 延迟发送 延迟发送 除了同步(等待)和异步&…...

用vue-full-calendar实现酒店预定管理展示
文章目录 前言一、关于vue-full-calendar二、使用步骤1. 引入库2. 使用库3. 开始编码4. 实际效果图展示5. 点击弹窗展示6. 弹窗展示效果图 总结 前言 近些天有位做酒店业务朋友问到我,有没有前端比较好用的预定日历查看插件,实际上我也没有研究过&#…...

DirectX12环境配置(1)
开发环境:visual studio 2022 第一种配置DirectX12环境得方式。首先创建一个c得空项目,然后创建一个main.cpp文件。把下面这串代码放进去,先不用管这串代码什么意思,后面会逐行逐句得讲解,因为我们创建得是空项目&am…...

Go-异常处理(defer recover panic)
系列文章目录 提示:goi语言基础文章 GO-异常处理 文章目录 系列文章目录前言一、关键字含义defer /recover 实现异常捕获和处理应用场景deferrecoverpanic 二、实例实例讲解上述几种情况 总结 前言 提示:这里可以添加本文要记录的大概内容: …...

【完美解决】mysql启动不了:本地计算机上的MySQL服务启动后停止
本文基于mysql8.0,5.7也可以参考 navicat 突然莫名其妙连不上mysql 查看服务,也启动不了,手动启动出现错误: 本地计算机上的MySQL服务启动后停止。某些服务在未由其他服务或程序使用时将自动停止 20230525更新! 先…...

C++ Qt 项目设计:基于C++与Qt的跨平台定时关机/关屏应用开发
基于C与Qt框架的定时关机与关屏应用开发全攻略 (一) 项目概述 (Project Overview)1.1 项目需求解析 (Analyzing the Project Requirements)1.2 选择技术栈 (Choosing the Tech Stack)1.3 功能概览 (Function Overview) (二) 设计思路 (Design Thinking)2.1 系统架构设计 (Syste…...

Python新技术和趋势:如何应对Python生态的变化和发展趋势
第一章:引言 Python作为一门简洁、优雅且易于学习的编程语言,一直以来都备受开发者的喜爱。它拥有强大的生态系统和活跃的社区,使得Python在各个领域都有广泛的应用。然而,随着时间的推移,Python生态系统也在不断演变…...

Flutter 又一元老离职,感谢 Tim 这些年的付出
前天在 insiders 收到 Tim Sneath 的离职邮件时感觉很震惊,因为他绝对是 Flutter 团队的元老级人物,几乎每次一次 Flutter 版本发布和社区活动都有他的身影,可以说他是我的 Flutter 领路人之一。 Tim 是在 2017 加入 Flutter 团队࿰…...

C++学习笔记3:sort和priority_queue的比较器重载
1 sort 三种方法 1. 直接重载函数 #include <vector> #include <memory> #include <vector> #include <queue> #include <iostream> #include <algorithm>using namespace std;class Node{ public:int value;Node(){value 0;};explici…...

Java之旅——Mybatis
Mybatis 是一个基于 Java 的 ORM(Object-Relational Mapping),用于 Java 应用程序的持久层框架,它将在 Java 对象和数据库关系之间建立一个映射。Mybatis 的作用主要是简化 SQL 语句的编写和维护,以及减少代码中的冗余…...

抽奖中的分布式锁应用
开发抽奖时遇到的分布式锁问题,特此记录一下几种实现方案 背景 开发中遇到个抽奖需求,会根据当前奖池内道具数量随机道具并发送给用户。这里面涉及到超发的问题,需要使用到分布式锁,特此记录一下常用的几种方案。 “超发”&#…...

项目总结 车牌识别
代码贴:OpenCV实战5 车牌号识别_opencv车牌字符识别_爱钓鱼的歪猴的博客-CSDN博客 目录 1、效果 2、代码思路 0、准备车配字符模板图片以及字符文件 1、对整图进行预处理 得到突出车牌的cany边缘图 2、车牌字体联通在一起,形成一个区域 3、筛选出车…...