0302GPIO外设输入功能

news2024/11/13 9:31:16

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.coloradmin.cn/o/1911827.html

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

相关文章

Error:sql: expected 1 arguments, got 2

一 背景 在测试一个API接口时,看到日志里面突然抛出一个错误:Error:sql: expected 1 arguments, got 2 看了下,对应的表里面是有相关数据的,sql语句放在mysql里面执行也是没问题!那奇了怪了,为啥会产生这样…

【MindSpore学习打卡】应用实践-热门LLM及其他AI应用-使用MindSpore实现K近邻算法对红酒数据集进行聚类分析

在机器学习领域,K近邻算法(K-Nearest Neighbor, KNN)是最基础且常用的算法之一。无论是分类任务还是回归任务,KNN都能通过简单直观的方式实现高效的预测。在这篇博客中,我们将基于MindSpore框架,使用KNN算法…

alibabacloud学习笔记11

讲解什么是配置中心及使用前后的好处 讲解Nacos作为配置中心面板介绍 官方文档 Nacos config alibaba/spring-cloud-alibaba Wiki GitHub 加入依赖: 订单服务和视频服务也加上这个依赖。 讲解Nacos作为配置中心实战 订单服务添加配置。 我们注释掉之前的配置。 …

Java项目:基于SSM框架实现的农家乐信息管理平台含前后台【ssm+B/S架构+源码+数据库+答辩PPT+开题报告+毕业论文】

一、项目简介 本项目是一套基于SSM框架实现的农家乐信息管理平台 包含:项目源码、数据库脚本等,该项目附带全部源码可作为毕设使用。 项目都经过严格调试,eclipse或者idea 确保可以运行! 该系统功能完善、界面美观、操作简单、功…

Mybatis Plus 3.X版本的insert填充自增id的IdType.ID_WORKER策略源码分析

总结/朱季谦 某天同事突然问我,你知道Mybatis Plus的insert方法,插入数据后自增id是如何自增的吗? 我愣了一下,脑海里只想到,当在POJO类的id设置一个自增策略后,例如TableId(value "id",type …

Linux多进程和多线程(八)多线程

多线程 线程定义线程与进程线程资源 线程相关命令 pidstat 命令 top 命令ps 命令常见的并发方案 1. 多进程模式2. 多线程模式 创建线程 1. pthread_create() 示例:创建一个线程 2. pthread_exit() 退出线程3. pthread_join() 等待线程结束 示例: 线程分离 创建多个线程 示例 1:…

Spring Boot集成grpc快速入门demo

1.什么是GRPC? gRPC 是一个高性能、开源、通用的RPC框架,由Google推出,基于HTTP2协议标准设计开发,默认采用Protocol Buffers数据序列化协议,支持多种开发语言。gRPC提供了一种简单的方法来精确的定义服务&#xff0c…

VUE之旅—day3

工程化开发和脚手架Vue CLI 开发Vue的两种方式: 核心包创痛开发模式:基于html/css/js文件,直接引入核心包,开发Vue。 工程化开发模式:基于构建工具(例如:webpack)的环境中开发Vue。…

『大模型笔记』GraphRAG:利用复杂信息进行发现的新方法!

GraphRAG:利用复杂信息进行发现的新方法! 文章目录 一. GraphRAG:利用复杂信息进行发现的新方法!1. 将RAG应用于私人数据集2. 整个数据集的推理3. 创建LLM生成的知识图谱4. 结果指标5. 下一步二. 参考文献微软官方推文:https://www.microsoft.com/en-us/research/blog/gra…

招投标信息采集系统:让您的企业始终站在行业前沿

一、为何招投标信息如此关键? 在经济全球化的大背景下,招投标活动日益频繁,成为企业获取项目、拓展市场的主流方式之一。招投标信息采集,作为企业战略决策的前置环节,其重要性不言而喻。它不仅关乎企业能否第一时间发…

实时消息推送系统,写得太好了!

websocket 协议是在 http 协议上的一种补充协议,是 html5 的新特性,是一种持久化的协议。其实 websocket 和 http 关系并不是很大,不过都是属于应用层的协议,接下来我们就开始实战。 websocket 定时推送 本教程基于 springboot …

如何解决群晖Docker注册表查询失败/无法拉取镜像等问题

文章目录 📖 介绍 📖🏡 演示环境 🏡📒 问题概述 📒📒 解决方案 📒🔖 方法一🔖 方法二🔖 方法三⚓️ 相关链接 🚓️📖 介绍 📖 在群晖(Synology)NAS设备上使用Docker时,我们可能会遇到查询Docker注册表失败,无法拉取Docker镜像的问题。这种情况…

一文理解 Treelite,Treelite 为决策树集成模型的部署和推理提供了高效、灵活的解决方案

🍉 CSDN 叶庭云:https://yetingyun.blog.csdn.net/ 一、什么是 Treelite? Treelite 是一个专门用于将决策树集成模型高效部署到生产环境中的机器学习模型编译器,特别适合处理大批量数据的推理任务,能够显著提升推理性能…

《RWKV》论文笔记

原文出处 [2305.13048] RWKV: Reinventing RNNs for the Transformer Era (arxiv.org) 原文笔记 What RWKV(RawKuv):Reinventing RNNs for the Transformer Era 本文贡献如下: 提出了 RWKV 网络架构,结合了RNNS 和Transformer 的优点,同…

vscode调试教程

VSCode调试 VSCode Debuggers VSCode使用launch.json进行细粒度的控制,可以启动程序或将其附加到复杂的调试场景中 打开Run and Debug视图Ctrl Shift D 点击create a launch.json file,选择C(GDB/LLDB) 会在工作目录自动创建.vscode/launch.json文…

单对以太网连接器多场景应用

单对以太网连接器应用场景概述 单对以太网(Single Pair Ethernet,简称SPE)作为一种新兴的以太网技术,以其独特的优势在多个领域得到了广泛的应用。SPE通过单对电缆进行数据传输,支持高速数据传输,同时还能…

Python学习笔记33:进阶篇(二十二)pygame的使用之image模块

前言 基础模块的知识通过这么长时间的学习已经有所了解,更加深入的话需要通过完成各种项目,在这个过程中逐渐学习,成长。 我们的下一步目标是完成python crash course中的外星人入侵项目,这是一个2D游戏项目。在这之前&#xff…

文献解读-基准与方法研究-第十六期|《GeneMind 公司的 GenoLab M 测序平台 WGS 和 WES 数据基准测试》

关键词:基准与方法研究;基因测序;变异检测; 文献简介 标题(英文):Accuracy benchmark of the GeneMind GenoLab M sequencing platform for WGS and WES analysis标题(中文&#xf…

无法连接Linux远程服务器的Mysql,解决办法

问题描述 如果是关闭虚拟机之后,二次打开无法连接Mysql,则可尝试一下方法进行解决 解决方法 关闭虚拟机的防火墙 1:查看防火墙状态 systemctl status firewalld 一下显示说明防火墙是启动的状态 2:关闭防火墙 systemctl st…

Java线程死锁及解决方法

多线程环境下,死锁即两个或两个以上的线程去争夺同一个共享资源,而导致互相等待的情况。 要产生死锁,必须满足如下四个条件: 互斥条件,共享资源x和y只能被一个线程占有请求和保持条件,T1持有x&#xff0c…