32单片机基础:GPIO输入

news2024/11/23 15:41:56

1.1按键控制LED

按键介绍:

两种方式,我们一般用下接的方式。

第一个图:注意点。当按键按下,PA0接地,被置为低电平, 但是一旦按键松手,PA0悬空,引脚电压不确定。所以无论怎么读引脚也不知道知否被按下,所以为了解决这个问题,所以必须要求PA0是上拉输入的模式,这样引脚悬空的话,就会被置为高电平,这样我们我们就可以读取PA0的电压就知道按键是否被按下。

但是第二个图就不会出现问题,按下时,被置为低电平,松手,由于上拉电阻的作用,被置为高电平。这样引脚就不会出现浮空状态。所以此时PA0可以配置浮空输入和上拉输入。上拉输入,两个电阻共同作用,这样高电平就会更加稳定一些,

第三个图同样注意要使用下拉输入模式。

下面是面包板接线图:

用哪个端口看自己的,我这里也没按上面连接,我是接A0,A1两个端口 

采用模块化编程:

把LED的代码和按键的代码封装开来,不要一起放在主函数里。分别放在自己的.c和.h文件里。

新建一个文件夹,用来存放硬件驱动

 点击keil5的魔术棒: 

把文件夹添加进来之后,像建立main函数一样建立下图文件。 

LED.h用来存放这个驱动程序可以对外提供的函数或变量声明。 

按照Ctrl+Alt+空格,会弹出相应函数的提示框。

LED.c

#include "stm32f10x.h"                  // Device header

void LED_Init(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_0|GPIO_Pin_1;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
}

LED.h

#ifndef __LED_H_
#define __LED_H_

void LED_Init(void);//打开时钟,配置端口

#endif

main.c

#include "stm32f10x.h"                 
#include "Delay.h"
#include "LED.h"
int main()
{
   LED_Init();
	while(1)
	{

	}
}

 这是,就会观察两个LED灯亮起来了,为啥我们没有配置高低电平,他会亮呢,因为我们的电路是低电平点亮,GPIO配置好了之后默认是低电平。

可以在初始化后面加GPIO_SetBits(GPIOA,GPIO_Pin_0|GPIO_Pin_1);让LED熄灭。

GPIO_pin_0|GPIO_pin_1(×)p小写了

GPIO_Pin_0|GPIO_Pin_1(√)

 后面我们配置好LED开的函数,灭的函数。

LED.c

void LED_Init(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_0|GPIO_Pin_1;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	GPIO_SetBits(GPIOA,GPIO_Pin_0|GPIO_Pin_1);
}

void  LED0_ON(void)
{
     GPIO_ResetBits(GPIOA,GPIO_Pin_0);
}	

void  LED0_OFF(void)
{
	GPIO_SetBits(GPIOA,GPIO_Pin_0);
}

void  LED1_ON(void)
{
     GPIO_ResetBits(GPIOA,GPIO_Pin_1);
}	

void  LED1_OFF(void)
{
	GPIO_SetBits(GPIOA,GPIO_Pin_1);
}

LED.h

#ifndef __LED_H_
#define __LED_H_

void LED_Init(void);//打开时钟,配置端口
void  LED0_ON(void);
void  LED0_OFF(void);
void  LED1_ON(void);
void  LED1_OFF(void);

#endif

 同理按上述方法,建立Key.c和Key.h

GPIO读取的四个函数:(按键需要读取I/O端口)

GPIO_ReadInputDataBit:这个函数是用来读取输入数据寄存器某一个端口的输入值的。

参数是 GPIOx,GPIO_Pin用来指定某一个端口,返回值是uint8_t,代表高低电平

GPIO_ReadInputData:这个函数比上一个函数少了一个Bit,它是用来读取整个输入数据寄存器的,参数只有一个GPIOx,用来指定外设。返回值是uint16_t,是一个16位数据,每一位代表一个端口值,

 GPIO_ReadOutputDataBit:这个函数是用来读取输出数据寄存器的某一位,所以原则来说,它并不是用来读取端口的输入数据的。这个函数一般用于输出模式下,用来看一下自己输出的是什么。

下面LED的翻转就用了这个。

GPIO_ReadOutputData:这个函数也是少了一个Bit,意思也一样,是用来读取整个输出寄存器的。

这就是四个函数的用途:

 Key.c

 #include "stm32f10x.h"                  // Device header
#include "Delay.h"

void Key_Init(void)//按键初始化,初始化为上拉输入模式
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//我们按键接到GPIOB上
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;//上拉输入
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1|GPIO_Pin_11;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStructure);
}

uint8_t Key_GetNum(void)
{
	uint8_t Keynum=0;
	//读取GPIO端口
	if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1)==0)//表示按键按下
	{
		Delay_ms(20);//消抖
		while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1)==0);//直到松手
		Delay_ms(20);//消抖
		Keynum=1;
	}
	if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11)==0)//表示按键按下
	{
		Delay_ms(20);//消抖
		while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11)==0);//直到松手
		Delay_ms(20);//消抖
		Keynum=2;
	}
	return Keynum;
}

Key.h

#ifndef __LED_H_
#define __LED_H_

void Key_Init(void);
uint8_t Key_GetNum(void);
#endif

main.c

#include "stm32f10x.h"                 
#include "Delay.h"
#include "LED.h"
#include "Key.h"

uint8_t KeyNum;

int main()
{
   LED_Init();
   Key_Init();
	while(1)
	{
//      LED0_ON();
//	  LED1_OFF();
//	  Delay_ms(500);
//	  LED1_ON();
//	  LED0_OFF();
//	  Delay_ms(500);
	  KeyNum=Key_GetNum();
		if(KeyNum==1)
		{
			  LED0_turn();
		}
		if(KeyNum==2)
		{
			 LED1_turn();
		}
	}
}

当然,还有Delay函数没有拿进来,自己可以写一个Delay函数,自己写代码时可以加一些注释,方便自己和他人理解,注释的规范可以参考32库函数里面的

这就是按键控制LED点亮的全部过程了。

1.2光敏传感器控制蜂鸣器

光敏电阻介绍:

因为电阻变化不容易直接观察,所以我们将传感器元件通常与定值电阻进行串联分压,

接地电容就是滤波用的。 滤除一些干扰,保证输出电压波形平滑

AO得到的是模拟电压,要想得到数字电压,要对AO进行二值化的输出,,二值化是通过芯片LM393来完成的,LM393是一个电压比较器芯片。看下图所示。电容对VCC滤波。

电压比较器就是一个运算放大器。运算放大器当做比较器的情况如下,

 左边的是电源指示灯,通道电就亮,

右边是DO输出指示灯,它可以指示DO的输出电平。低电平点亮,高电平熄灭。

上拉电阻R5是为了保证默认输出为高电平的。

 电路连接图:

 

上电时,可以看到两个灯都亮了,当我们遮住光线,输出指示灯灭,代表输出高电平(DO),松手时,输出指示灯1灭,代表输出低电平(DO),电位器可以调节高低电平的判断阈值。

Buzzer.c(蜂鸣器模块)

#include "stm32f10x.h"                  // Device header

void Buzzer_Init(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);
	
	GPIO_SetBits(GPIOB,GPIO_Pin_0|GPIO_Pin_12);
}

	
void Buzzer_ON(void)
{
     GPIO_ResetBits(GPIOB,GPIO_Pin_12);
}	

void Buzzer_OFF(void)
{
	GPIO_SetBits(GPIOB,GPIO_Pin_12);
}

void Buzzer_turn(void)
{
	if(GPIO_ReadOutputDataBit(GPIOB,GPIO_Pin_12)==0)
	{
		GPIO_SetBits(GPIOB,GPIO_Pin_12);
	}
	else
	{
		GPIO_ResetBits(GPIOB,GPIO_Pin_12);
	}
}

 Buzzer.h

#ifndef __BUZZER_H_
#define __BUZZER_H_

void Buzzer_Init(void);
void Buzzer_ON(void);
void  Buzzer_OFF(void);
void Buzzer_turn(void);

#endif

LightSensor.c(光敏传感器模块)

#include "stm32f10x.h"                  // Device header
#include "stm32f10x.h"                  // Device header
#include "Delay.h"

void LightSensor_Init(void)//按键初始化,初始化为上拉输入模式
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//我们按键接到GPIOB上
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;//上拉输入
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_13;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStructure);
}

uint8_t LightSensor_Get(void)//得到DO的返回值,暗是1
{
	return GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_13);
}

 LightSensor.h

#ifndef __LightSensor_H_
#define __LightSensor_H_

void LightSensor_Init(void);
uint8_t LightSensor_Get(void);

#endif

 main.c

#include "stm32f10x.h"                 
#include "Delay.h"
#include "Buzzer.h"
#include "LightSensor.h"


int main()
{
	Buzzer_Init();
	LightSensor_Init();
	
	while(1)
	{
      if( LightSensor_Get()==1)//光线比较暗的情况
	  {
		  Buzzer_ON();
	  }
	  else
	  {
		   Buzzer_OFF();
	  }
	}
}

32单片机的C语言(与51些许不同)

数据类型 

 

在库函数用了许多。下面是例子, 

 只是这些不好理解,我们都换了一个让我们看得懂的名字。

 与上面有什么区别呢,宏定义任何名字都可以换,而typedef只能给变量类型换名字。所以宏定义的改名字范围要宽一些。

 这些没学好的再去学一下C语言吧。

 

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

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

相关文章

MySQL 核心模块揭秘 | 06 期 | 事务提交之前,binlog 写到哪里?

1. 准备工作 参数配置: binlog_format ROW binlog_rows_query_log_events OFF创建测试表: CREATE TABLE t_binlog (id int unsigned NOT NULL AUTO_INCREMENT,i1 int DEFAULT 0,str1 varchar(32) DEFAULT ,PRIMARY KEY (id) USING BTREE ) ENGINEIn…

使用 Nuxt 构建简单后端接口及数据库数据请求

写在前面 本文主要为大家介绍,如何使用 Nuxt 框架实现一个简单的后端接口,并且从数据库中请求数据返回给前端。 实现 创建 serverMiddleware 文件夹 首先我们新建一个名字为 serverMiddleware 文件夹用来存储接口相关信息 目录结构如下:…

探索 JavaScript ES8 中的函数式编程并通过实例加以实践

💂 个人网站:【 海拥】【神级代码资源网站】【办公神器】🤟 基于Web端打造的:👉轻量化工具创作平台💅 想寻找共同学习交流的小伙伴,请点击【全栈技术交流群】 介绍 函数式编程是一种强大的范式&#xff0c…

【buuctf--outguess】

看题目就知道应该要用到 outguess 这个工具了,具体用处和下载方式请参照这篇博客Outguess下载和使用方法_outguess工具-CSDN博客 下载的 tar 压缩包解压,huhuhu.zip是伪加密的,直接用 binwalk -e 提取一下就可以,也可以修改压缩源…

python游戏代码大全可复制,python基础游戏代码

本篇文章给大家谈谈python游戏编程入门游戏代码,以及python游戏代码大全可复制,希望对各位有所帮助,不要忘了收藏本站喔。 仅限技术学习参考 分享13个游戏源码,可以自己复现玩玩,研究下里面的编程逻辑,对学…

PMP考试难度怎么样?

PMP考试整体难度并不大,因为目前的考试题型都是选择题,所以通过率相对较高。然而,新考纲中增加了更多关于敏捷方法的题型,这些题目相对更加变化多样,也有不少考生觉得难以抉择,四个选项都似乎都是正确的。P…

电商数据采集+跨境电商|API电商数据采集接口洞悉数字新零售发展

随着全球经济一体化和电子商务的快速发展,网络购物的需求日益增加。不断涌现的电商企业使得行业的竞争情况愈演愈烈。在这种情况下,企业不仅要加大经营力度,还要在自己的基础设施和技术上持续投入,才能更好的适应市场和消费习惯。…

开源CMS Drupal本地快速部署并实现无公网ip环境远程访问

文章目录 前言1. Docker安装Drupal2. 本地局域网访问3 . Linux 安装cpolar4. 配置Drupal公网访问地址5. 公网远程访问Drupal6. 固定Drupal 公网地址 前言 Dupal是一个强大的CMS,适用于各种不同的网站项目,从小型个人博客到大型企业级门户网站。它的学习…

TP4366 1A 低成本 天源 同步移动电源方案 SOP-8

描述 TP4366是一款专为移动电源设计的同步升压的单芯片解决方案,内部集成了线性充电管理模块、同步放电管理模块、电量检测与LED指示模块、保护模块。TP4366内置充电与放电功率MOS,充电电流固定为0.8A,同步升压支持1A 输出电流。TP4366内部集成了温度补偿、过温保护、过充与过…

MySQL数据库基础(十二):子查询(三步走)

文章目录 子查询(三步走) 一、子查询(嵌套查询)的介绍 二、子查询的使用 三、总结 子查询(三步走) 一、子查询(嵌套查询)的介绍 在一个 select 语句中,嵌入了另外一个 select …

数据结构与算法:栈

朋友们大家好啊,在链表的讲解过后,我们本节内容来介绍一个特殊的线性表:栈,在讲解后也会以例题来加深对本节内容的理解 栈 栈的介绍栈进出栈的变化形式 栈的顺序存储结构的有关操作栈的结构定义与初始化压栈操作出栈操作获取栈顶元…

基于springboot实现的音乐网站

一、系统架构 前端:html | js | css | bootstrap 后端:springboot | mybatis 环境:jdk1.8 | mysql | maven 二、 代码及数据库 三、功能介绍 01. 登录页 02. 用户注册 03. 首页 04. 喜欢 05. 查询

以程序员的视角,看前后端分离的是否必要?

Hello,我是贝格前端工场,本篇分享一个老生常谈的话题,前后端分离是必然趋势,但也是要区分具体的场景,欢迎探讨,关注,有前端开发需求可以私信我,上车了。 一、什么是前后端分离和不分…

【dc-dc】世微AP5125 外置MOS 5-100V 8A平均电流型LED降压恒流驱动器 SOT23-6

产品描述 AP5125 是一款外围电路简单的 Buck 型平均电流检测模式的 LED 恒流驱动器,适用于 8-100V 电压范围的非隔离式大功率恒流 LED 驱动领域。芯片采用固定频率 140kHz 的 PWM 工作模式, 利用平均电流检测模式,因此具有优异的负载调整 率特…

一种简单高效的新算法(2021)|算术优化算法AOA原理及其利用 (Matlab/Python)

文章来源于我的个人公众号:KAU的云实验台,主要更新智能优化算法的原理、应用、改进 CEC2005中的测试 本文KAU将介绍一个由Abualigah等人于2021年发表在Comput. Methods Appl. Mech. Eng.上的元启发式算法——算术优化算法(Arithmetic Optimization Al…

书生·浦语大模型实战营-第三课笔记

1、langchain工作流程 2、数据收集及向量化处理 数据收集是向量数据库的源头,可以理解为后续我们要长期采集和更新的知识库或者数据源,在本课中采用了几个项目中的txt和md文档作为数据源 3、接入langchain

搜索专项---DFS之连通性模型

文章目录 迷宫红与黑 一、迷宫OJ链接 本题思路:DFS直接搜即可。 #include <iostream> #include <cstring> #include <algorithm>constexpr int N110;int n; char g[N][N]; bool st[N][N]; int x1, y1, x2, y2;int dx[4] {-1, 0, 1, 0}, dy[4] {0, 1, 0, …

如何复制IDEA中的提示?

在idea中&#xff0c;例如下面的提示我使用ctrl c怎么都复制不了&#xff0c;其实是有窍门的。 窍门很简单&#xff1a; 首先先把光标移动到提示框内&#xff0c;然后用alt 鼠标左键复制&#xff0c;提示框会自动关闭&#xff0c;这时就已经复制成功了&#xff01;&#xff…

ARM处理器运行Windows系统的三防加固平板|亿道三防

大家好&#xff01;今天我要为大家介绍一款引人注目的三防加固平板电脑——亿道三防系列产品。它们采用高通ARM处理器&#xff0c;并能够运行Windows 11操作系统&#xff0c;给用户带来了前所未有的强大性能和多样化的应用体验。 首先&#xff0c;让我们来聊聊这款平板电脑的核…

数字世界的探索者:计算机相关专业电影精选推荐

目录 推荐计算机专业必看的几部电影 《黑客帝国》 《社交网络》 《乔布斯传》 《心灵捕手》 《源代码》 《盗梦空间》 《头号玩家》 《我是谁&#xff1a;没有绝对安全的系统》 《战争游戏》(WarGames) 《模仿游戏》(The Imitation Game) 《硅谷》(Silicon Valley) …