0302GPIO外设输入功能

GPIO外设输入功能

  • 输入部分硬件电路
    • 按键简介
    • 传感器模块简介
    • 按键和传感器模块的硬件电路
  • C语言的学习
    • C语言数据类型
    • 宏定义
    • typedef
    • 结构体
    • 枚举
    • C语言知识总结
  • 按键控制LED灯&光敏传感器蜂鸣器
  • GPIO总结
    • GPIO使用方法总结
    • 模块化编程的方法:

两个程序:按键控制LED,光敏传感器控制LED灯

GPIO输入部分直接从外部硬件设备开始

C语言的相关知识点
C语言的数据类型、宏定义、typedef、结构体和枚举 知识点,是库函数里经常出现的东西,了解这些有利于对库函数的执行逻辑更加清晰明了。C语言的if else、加减乘除最基本的可以自学我的C++部分
同时C语言的指针。对于指针的含义和方法,这是需要熟练掌握的

输入部分硬件电路

按键简介

在这里插入图片描述

抖动通常在5-10ms之间,人分辨不出来,但对于高速运行的单片机而言,这就漫长了。所以要对抖动进行过滤,否则会出现按键按一下,单片机反映了多次的现象。按键松手时也会有一段抖动。
最简单的方法是软件加一段延时,把抖动时间耗过去

传感器模块简介

在这里插入图片描述
这些传感器都是利用传感器元件,
比如光线越强,光敏电阻的阻值越小
温度越高,热敏电阻的阻值越小
红外光线越强,红外接收管的阻值越小。但是电阻的变化不易被直接观察,所以一般通过分压来输出

N1代表可变电阻(相对于各传感器,可以对应为光敏电阻、热敏电阻、红外接收管)
上下拉电阻在单片机中经常出现,弱上拉、弱下拉、强上拉、强下拉。这里强弱指的是电阻阻值的大小,弱上拉的电阻阻值大,驱动能力弱一点,上拉下拉指接到VCC、GND。

分到的模拟电压表示强度,
二值化比较通常用于检测通断,所以IN+阈值不需要过多的调整

按键和传感器模块的硬件电路

在这里插入图片描述
下接按键的方式(常用下接方式,这是电路设计的习惯和规范),上接按键的方式
第一个图最常用的按键接法(需要上拉输入的模式,默认高电平,否则会出现引脚电压不确定的错误现象)
第二个图外部接了上拉电阻(可以配置成浮空输入或者上拉输入,如果是上拉输入,那就是内外两个上拉电阻共同作用,这时高电平更强一些,对应的高电平更加稳定,但当引脚被强行拉低时,损耗也会大一些)
第三个图(需单片机引脚可以配置成下拉输入模式,一般的单片机可能不一定有下拉输入模式,所以用的不多)
第四个图(下拉输入模式或者浮空输入模式)

C语言的学习

C语言数据类型

在这里插入图片描述

在51单片机中int是16位的,而在STM32单片机中,int是32位的。和51的不同之处,不要弄混了

右边是C语言的stdint.h文件和ST对这些变量的重命名。因为左边的名字比较长,而且int的位数根据系统的不同还有可能不一样,还有char本义字符型意思,按名字来说应该存放字符,但是我们用单片机来存放整数而不是字符。
综合以上原因,C语言和ST就给这些变量换了个名字。C语言提供的有stdint.h这个头文件,使用了新的名字
int8_t就是char的新名字,表示意思就是8位整数数据。
-t表示这个用typedef重名命名的变量类型,
unsigned char 的新名字就是uint8_t,意思是无符号8位整型数据

代表的就是前面的数据类型,只是换了一个名字而已。
在这里插入图片描述

s8、u8、s16 、u16、就是ST库函数以前用的名字
在这里插入图片描述
新版库函数仍然支持这些写法,明确了这是库函数老的类型,是为了传统目的保留的(兼容老版本)
在这里插入图片描述

推荐使用stdint关键字的定义,因为是新版库函数使用的方式,也是C语言stdint.h头文件提供的官方定义

宏定义

在这里插入图片描述
此处就是用ABC 直接替代 12345
如:#define GPIO_Pin_10 ((uint16_t)0x0400)
GPIO_Pin_10 替换的就是 ((uint16_t)0x0400),加了强制类型转换,是为了严谨性考虑的,目前我们暂时不用管。这里0x0400表示第10号口,但这不方便理解,所以用宏定义将10号口改一下名字,叫GPIO_Pin_10。
宏定义除了替换之外,还有其他的用法,可以后期再学。

typedef

在这里插入图片描述
用途和宏定义差不多,
区别:宏定义的新的名字在左边,typedef的新名字在右边。(原来的名字也可以用)
宏定义不需要分号,typedef后面必须加分号。
宏定义任何名字都可以换,而typedef只能专门给变量类型换名字
所以宏定义的改名范围更宽,只不过对于变量类型重命名而言,使用typedef更加安全。
宏定义无脑改名,typedef会对命名进行检查,如果不是变量类型的名字,就报错

结构体

在这里插入图片描述
组合数据类型,一大堆基本数据类型的集合,数组只能组合相同类型的数据,想组合不同类型的数据就用结构体

变量就是定义数据和引用数据的
所以struct 要{}来打包变量,此处就是定义一个结构体变量StructName,包含了char 型的x,int型的y,float型的z

定义数据:
int a; 定义一个int型数据叫a,
int b[5]; 定义一个5个int型数据的数组
struct c; 定义一个结构体类型,叫c
但是既然是不同类型的数组组合,就需要告诉编译器是哪些数据的组合,所以还得加一个附加说明,告诉它是哪些数据,在struct后面加一个花括号,要打包哪些变量
struct{char x;int y;float z;} c; 这才是结构体的完整定义
定义一个结构体变量,名字叫c,其中包含了char 型的x,int型的y,float型的z3个子项

引用数据:
a=66;
b[0]=66; 数组名b加上方括号取索引,比如第0个元素等于66,
引用c 需要用结构体的名字c,然后用.运算符取索引,索引不是0,1,2,3,4,5了,而是结构体子项的名字,比如c.x=‘A’; c.y=66; c.z=3.14;
结构体成员多,一般会换行来写。

结构体的特殊用法
如果每次定义都写 struct{char x;int y;float z;} 这么一大串,那就麻烦,所以typedef的作用就出来了
typedef struct{char x;int y;float z;} StructName; 用StructName来替换前面的一长串,看上去就简单多了。

另一种引用方式:
pStructName->x=‘A’; pStructName是结构体的首地址,也就是结构体指针,加上->运算符,再加结构体成员名

加结构体指针的引用方式的原因:结构体是一种组合数据类型,在函数的数据传递过程中,通常用地址传递而不是值传递(地址传递、值传递在指针讨论 用法和利弊)

在这里插入图片描述
比如这个地方,结构体变量在传给GPIO_Init函数时,传递的是结构体的指针

在这里插入图片描述
对应GPIO_Init函数用结构体指针来接收,里面再引用结构体成员的时候,就可以使用->这个符号来引用
也可以用*号引出指针变量的内容,再用.点来引用结构体也是可以的,只不过用->这个运算符号更加方便
在这里插入图片描述
这个结构体就是一个数据打包的过程,首先将参数写到结构体的这3个变量里,然后统一打包,将结构体传递到函数里,函数里面再把这个结构体拆包出来,读取变量。这就是使用结构体的过程。(当需要参数很多时不方便管理就需要结构体了)

枚举

在这里插入图片描述
比如定义一个变量存储星期的值,那理论上取值是1-7,如果定义的整形变量,那变量任意存什么数都行,不会收到限制,这时可能出现数据不合法。比如星期8的出现,如果需要程序更加安全,就可以定义一个取值受限制的整形变量:枚举

也可以当成宏定义的集合:

定义和结构体差不多,这里是enum,然后是变量名字,中间是花括号,但注意里面是逗号,隔开
这样可以限制变量的取值范围,只能取花括号里面的定值。
另外,里面的定义,如果按照顺序累加的,那后面的幅值可以省略,编译器会自动添加上去。
同时也可以用typedef改一下名

比如:
typedef enum{
MONDAY=1,
TUESDAY,
WEDNESDAY
} week_t;

week_t week;
week MONDAY; //week = 1;
week = 8; //就会编译器报警:枚举里混入了其他变量

int a=MONDAY; //这样的用法和宏定义就差不多了,所以说枚举也是一个宏定义的集合,就是这个意思。

C语言知识总结

实际都不是C语言最根本的语法,没有这些东西照样可以完成功能,这些创造出来是为了更好地管理工程。虽然表面上多此一举,但是工程复杂起来后,使用这些知识可以使编程更加快捷、更容易理解,更不容易出错。

按键控制LED灯&光敏传感器蜂鸣器

对于驱动代码而言,一般都会封装起来,单独放在另外的.c和.h文件里。(模块化编程的方式)
led.c文件存放驱动程序的主体代码,led.h用来存放驱动程序可以对外提供的函数或变量的声明
在这里插入图片描述
led.c的第一行,需要添加 stm32f10x.h文件
led.h要添加一个防止头文件重复包含的代码
在这里插入图片描述
这里面的函数代码思想值得学习。这8个函数都值得学习
在编写代码时,如果不显示代码提示的话,可以按一下快捷键ctrl+Alt+空格,这样就可以弹出代码提示框了
在主函数里面,代码变得更加简介,初始化就是初始化,开灯就是开灯,关灯就是关灯,不需要再管底层的各种参数了。这就是模块化编程的好处。

在这里插入图片描述
GPIO_ReadInputDataBit 读取输入数据寄存器某一个端口的输入值的 参数:GPIOx,GPIO_Pin 用来指定某一个端口,返回值是uint8_t,代表这个端口的高低电平
GPIO_ReadInputData 读取整个输入数据寄存器的 参数GPIOx 用来指定外设,返回值uint16_t,是16位的数据,每一位代表一个端口值
GPIO_ReadOutputDataBit 读取输出数据寄存器某一个端口的输入值的 参数:GPIOx,GPIO_Pin 用来指定某一个端口,返回值是uint8_t,代表这个端口的高低电平(原则上来说,并不是用来读取端口的输入数据的,一般用于输出模式下,用来看一下自己的输出是什么)
GPIO_ReadOutputData 读取整个输出数据寄存器的
下面是读取的对应关系
在这里插入图片描述

在这里插入图片描述

变量全局变量,局部变量,定义域不一样。名称相同但是强龙不压地头蛇。

函数写好后,尽量在函数上方加一些注释,说明函数的用途,参数的取值和返回值的意思。时间久了自己看起来也知道,别人看也容易理解。

GPIO总结

GPIO使用方法总结

首先初始化时钟,然后定义结构体,赋值结构体,
GPIO_MODE 可以选择8中输入输出模式
GPIO_Pin 可以选择引脚,可以用按位或的方式同时选中多个引脚
GPIO_Speed 选择输出速度,要求不高的话直接使用50MHz即可
最后使用GPIO_Init函数,将指定的GPIO外设初始化好

然后是8个读取和写入的函数,读写主要用这些函数即可。
在这里插入图片描述

模块化编程的方法:

自己做产品外围硬件比较多,这时候就尽量把每个硬件的驱动函数单独提取出来,封装在.c和.h文件里,这样有利于简化主函数的逻辑。主函数里面有更重要的任务要完成,不要让驱动函数混在主函数里面。另外把硬件驱动提取出来,也有利于我们移植程序,还有利于进行分工合作,比如让别人来写驱动函数。主要的精力就可以集中在主函数的逻辑上了。
最后既然要做封装,函数的注释就要写清楚,这样方柏霓使用这个模块的人快速上手这些函数。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

图像分割-编码解码网络的训练-kreas实现

一、数据集加载: 纯手工打造一个函数用来加载数据,数据分别为image和mask 我们所需要的类型:(B数量,长,宽,通道数),只要将数据加载成这样并mask和image对应就行。 第一步…

S271系列RTU在旅游景区人流监控中的应用案例

S271系列RTU在旅游景区人流监控中的应用案例 随着全球旅游业的迅猛发展,旅游景区的管理者越来越关注如何利用先进的技术手段提升游客体验、优化管理效率以及确保安全。S271系列RTU作为一款先进的无线工业物联网设备,在旅游景区的人流监控中展现出了其独…

PTA - 编写函数计算圆面积

题目描述: 1.要求编写函数getCircleArea(r)计算给定半径r的圆面积,函数返回圆的面积。 2.要求编写函数get_rList(n) 输入n个值放入列表并将列表返回 函数接口定义: getCircleArea(r); get_rList(n); 传入的参数r表示圆的半径&#xff0c…

批量下载手机中APP程序中文件

需求 利用 adb pull 下载手机中app的某目录 adb pull 命令本身不支持直接下载整个目录(文件夹)及其所有子目录和文件作为一个单一的操作。但是,可以通过一些方法来间接实现这一目的。 方法 1. 首先将要下载的目录进行 tar 打包 # 在 And…

2020 ICPC Shanghai Site B. Mine Sweeper II 题解 构造 鸽巢原理

Mine Sweeper II 题目描述 A mine-sweeper map X X X can be expressed as an n m n\times m nm grid. Each cell of the grid is either a mine cell or a non-mine cell. A mine cell has no number on it. Each non-mine cell has a number representing the number of…

Raylib 实现超大地图放大缩小与两种模式瓦片地图刷新

原理: 一种刷新模式: 在宫格内整体刷新,类似九宫格移动到边缘,则九宫格整体平移一个宫格,不过这里是移动一个瓦片像素,实际上就是全屏刷新,这个上限是 笔记本 3060 70帧 100*100个瓦片每帧都…

《赌局的诱惑》-反赌反诈剧情脚本

场景1: 一家普通公司的休息室,有一张桌子,上面摆放着扑克牌和一些现金。墙上挂着一个时钟,显示时间是下午5点。 人物: 张伟:新员工,被同事拉入赌局。 赵刚:资深员工,赌…

UE5.3-基础蓝图类整理一

常用蓝图类整理: 1、获取当前关卡名:Get Current LevelName 2、通过关卡名打开关卡:Open Level(by name) 3、碰撞检测事件:Event ActorBeginOverlap 4、获取当前player:Get Player Pawn 5、判断是否相等&#xff1…

反弹球python小游戏

1.准备图片(可以替换) 2.python Pygame类 class Ls(pygame.sprite.Sprite):def __init__(self,pos):#pos 鼠标点击的位置super().__init__()self.image pygame.image.load(ji.png)self.dx2self.dx r.randint(20,500)self.image pygame.transform.scale(self.image,(self.dx…

昇思25天学习打卡营第21天|LSTM+CRF序列标注

1. 学习内容复盘 概述 序列标注指给定输入序列,给序列中每个Token进行标注标签的过程。序列标注问题通常用于从文本中进行信息抽取,包括分词(Word Segmentation)、词性标注(Position Tagging)、命名实体识别(Named Entity Recognition, NER)等。以命名…

iis部署前后端分离项目(React前端,Node.js后端)

iis虽然已经有点过时,但不少用户还在用,故总结一下。 1. 安装iis 如果电脑没有自带iis管理器,打开控制面板->程序->启用或关闭Windows功能,勾选iis安装即可 2. 部署前端项目 打开iis,添加网站,物理…

Linux基本命令的使用示例

目录 1实现效果:在downloads目录下创建1个空文件夹empty,创建1个空文件lake.txt,输入任意数据保存后退出 2实现效果:搜索包含关键字"泉眼"的行 3实现效果:重命名文件夹empty为full,复制文件cc…

Anaconda+Pycharm 项目运行保姆级教程(附带视频)

最近很多小白在问如何用anacondapycharm运行一个深度学习项目,进行代码复现呢?于是写下这篇文章希望能浅浅起到一个指导作用。 附视频讲解地址:AnacondaPycharm项目运行实例_哔哩哔哩_bilibili 一、项目运行前的准备(软件安装&…

锅总反驳李彦宏说的“不要卷模型,要卷应用”

李彦宏的观点是大家不要卷模型,要卷应用,但我认为这种看法是荒谬的。以下是24条反驳李彦宏观点的论点和论据: 模型的准确性直接决定应用的质量和用户体验: 论据:在自然语言处理、计算机视觉等领域,模型的准…

Java虚拟机面试题汇总

目录 1. JVM的主要组成部分及其作用? 1.1 运行时数据区划分? 1.2 哪些区域可能会发生OOM? 1.3 堆和栈的区别? 1.4 内存模型中的happen-before是什么? 2. HotSpot虚拟机对象创建流程? 2.1 类加载过程…

kafka 消费者

消费者 消费者。消费者连接到Kafka上并接收消息,进而进行相应的业务逻辑处理。 消费组 消费者负责订阅Kafka中的主题,并且从订阅的主题上拉取消息。 消费组:每个消费者都有一个对应的消费组,每一个分区只能被一个消费组中的一个…

windows JDK11 与JDK1.8自动切换,以及切换后失效的问题

1.windows安装不同环境的jdk 2.切换jdk 3.切换失败 原因:这是因为当我们安装并配置好JDK11之后它会自动生成一个环境变量(此变量我们看不到),此环境变量优先级较高,导致我们在切换回JDK8后系统会先读取到JDK11生成的…

Docker镜像拉取失败/下载缓慢?如何正确的更换Docker镜像源?(含镜像源,亲测有效!)

文章目录 📖 介绍 📖🏡 演示环境 🏡📒 Docker镜像源 📒📝 为何更换镜像源📝 如何更换Docker镜像源📝 验证镜像源更换成功📝 一些可用的Docker镜像源⚓️ 相关链接 ⚓️📖 介绍 📖 在当今快速迭代的软件开发环境中,Docker以其轻量级、可移植和高效的特…

新浪API系列:支付API打造无缝支付体验,畅享便利生活(3)

在当今数字化时代,支付功能已经成为各类应用和平台的必备要素之一。作为开发者,要构建出安全、便捷的支付解决方案,新浪支付API是你不可或缺的利器。新浪支付API提供了全面而强大的接口和功能,帮助开发者轻松实现在线支付的集成和…

【嵌入式DIY实例-ESP8266篇】-LCD ST7735显示BME280传感器数据

LCD ST7735显示BME280传感器数据 文章目录 LCD ST7735显示BME280传感器数据1、硬件准备与接线2、代码实现本文中将介绍如何使用 ESP8266 NodeMCU 板(ESP12-E 模块)和 BME280 气压、温度和湿度传感器构建气象站。 NodeMCU 微控制器 (ESP8266EX) 从 BME280 传感器读取温度、湿度…