stm32入门-----GPIO口输入的学习与使用

 

前言

        本期继续学习stm32的GPIO口,上一期是学习了GPIO口进行输出操作,那么本期就学习GPIO口的输入操作,本期分为两个实际项目,分别是通过按键控制LED灯的亮灭、通过光敏传感器去控制蜂鸣器的警报。(视频:[3-4] 按键控制LED&光敏传感器控制蜂鸣器_哔哩哔哩_bilibili

一、硬件介绍

1.按键

按键:常见的输入设备,按下导通,松手断开
按键抖动:由于按键内部使用的是机械式弹簧片来进行通断的,所以在按下和松手的瞬间会伴随有一连串的抖动

对此我们在编写代码的时候要对按键进行消抖处理,学过51的都知道了吧。下面在看看按键的硬件电路,对于按键的硬件电路,我们一般情况都是用第一行的样式,也就是IO口低电平有效,当按键没有按下的时候IO口就保持高电平状态,所以上面会接一个上拉电阻来实现保持电平,当按键按下的时候,IO口就接地,此时为低电平整体,按键导通电路。对于下面的第第二行样式效果是一样的,不过跟上面的方式相反,是属于高电平有效,但是一般情况都是不用到,基本上都是用第一行低电平有效的方式,所以稍微了解一下就行了。

2.传感器模块

传感器模块:传感器元件(光敏电阻 / 热敏电阻 / 红外接收管等)的电阻会随外界模拟量的变化而变化,通过与定值电阻分压即可得到模拟电压输出,再通过电压比较器进行二值化即可得到数字电压输出

 传感器模块是经常用到的,比如红外线传感器,超声波传感器等等,不过本期我们用到的是光敏电阻传感器,学过光敏电阻的都知道,光敏电阻就是光线越量的时候电阻就越小,光线暗的时候电阻就变大,对于光敏电阻传感器同样的,下面电路图我们可以看出,光线量的时候DO口就会被导入高电平,此时LED指示灯就会量,DO口为低电平,反之光线暗的时候LED指示灯就会灭,此时DO口为高电平。(想了解更多传感器请看这个:IoT物联网嵌入式设备中30种常见传感器模块简介及原理讲解_数据采集各个模块的传感器-CSDN博客) 

知道了这些,下面就开始今天的项目吧。

二、按键控制LED灯亮灭

1.电路连线图

先看电路的接线图:

这里我们要用到的是GPIOA口的1和2引脚,GPIB口的1和11引脚,前者是LED的引脚,后面是按键的引脚。对于编程,我们最好用模块化编程去做。

2. 工程文件添加 

这里打开项目的根目录,然后创建一个hardware的文件夹:

然后打开三个小方块这个图标,把这个文件夹添加进去,后面就是在这里创建圈起来的这四个文件。 

然后就是打开魔术棒图标:

 按照下面123步骤去把根目录下的hardware这个文件夹添加进去就行了。

3.GPIO口读取函数介绍

这里我们要学习下面几个GPIO口的读取函数,其实也很简单,也就是读取IO口输入输出寄存器里面的数据。

(1)输入数据的读取 

uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
这个函数是用来读取输入数据寄存器某一个端口的输入值,参数是GPIOx和GPIO_Pin,用来指定某一个端口。

返回值是uint8_t,代表这个端口的高低电平。


uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx);
这个函数比上一个函数少了一个Bit,它是用来读取整个输入数据寄存器的,参数只有一个GPIOx,用来指定外设。

返回值是uint16_t,是一个16位的数据,每一位代表一个端口值。

(2)输出数据的读取 

uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
这个函数是用来读取输出数据寄存器的某一位,所以它并不是用来读取端口的输入数据的,这个函数一般用于输出模式下,用来看一下自己输出的是什么。


uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);
这个函数比上一个函数少了一个Bit,是用来读取整个输出寄存器的。

4.代码编写

这里要用到相关的延时函数,我会上传到本期的资源绑定,自行下载。

要用到的模块也就这些:

(1)按键模块

Key.c文件:

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

void Key_init(){

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	
	GPIO_InitTypeDef GPIO_initstruct; 
	GPIO_initstruct.GPIO_Mode=GPIO_Mode_IPU; 
	GPIO_initstruct.GPIO_Pin=GPIO_Pin_1 | GPIO_Pin_11;
	GPIO_initstruct.GPIO_Speed=GPIO_Speed_50MHz;
	
	GPIO_Init(GPIOB,&GPIO_initstruct);
	
}

uint8_t Keynum(){

	uint8_t num=0;
	
	if (GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1)==0){
		
		Delay_ms(20);
		while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1)==0)
		Delay_ms(20);
		num=1;
	}
	if (GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11)==0){
		
		Delay_ms(20);
		while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11)==0)
		Delay_ms(20);
		num=2;
	}
	return num;
}

Key.h文件

#ifndef __KEY_H
#define __KEY_H

void Key_init();

uint8_t Keynum();
#endif
(2)LED模块

LED.c文件

#include "stm32f10x.h"                  // Device header

void LED_init(void){
	//定义时钟 GPIOA
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	
	GPIO_InitTypeDef GPIO_initstruct; 
	GPIO_initstruct.GPIO_Mode=GPIO_Mode_Out_PP; 
	GPIO_initstruct.GPIO_Pin=GPIO_Pin_1 | GPIO_Pin_2;
	GPIO_initstruct.GPIO_Speed=GPIO_Speed_50MHz;
	
	GPIO_Init(GPIOA,&GPIO_initstruct);
	
	GPIO_SetBits(GPIOA,GPIO_Pin_1 | GPIO_Pin_2);
	
}
//低电平亮
void LED1_ON(){
	GPIO_ResetBits(GPIOA,GPIO_Pin_1);
}
void LED1_OFF(){
	GPIO_SetBits(GPIOA,GPIO_Pin_1);
}


//电平翻转
void LED1_turn(){
	if (GPIO_ReadOutputDataBit(GPIOA,GPIO_Pin_1)==0){
		GPIO_SetBits(GPIOA,GPIO_Pin_1);
	}
	
	else{
		GPIO_ResetBits(GPIOA,GPIO_Pin_1);
	}	
}


void LED2_ON(){
	GPIO_ResetBits(GPIOA,GPIO_Pin_2);
}
void LED2_OFF(){
	GPIO_SetBits(GPIOA,GPIO_Pin_2);
}

//电平翻转
void LED2_turn(){
	if (GPIO_ReadOutputDataBit(GPIOA,GPIO_Pin_2)==0){
		GPIO_SetBits(GPIOA,GPIO_Pin_2);
	}
	
	else{
		GPIO_ResetBits(GPIOA,GPIO_Pin_2);
	}	
}

LED.h文件

#ifndef __LED_H
#define __LED_H

void LED_init(void);

void LED1_ON();
void LED1_OFF();
void LED2_ON();
void LED2_OFF();
void LED1_ON();
void LED2_ON();
#endif
(3)主函数main.c 

最后就是主函数main.c文件

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

uint8_t keynum;

int main(void)
{	
	LED_init();
	Key_init();
	
	while(1){
		keynum=Keynum();
		if (keynum==1){
			LED1_turn();
		}
		if (keynum==2){
			LED1_turn();
		}
		
	}
}

三、光敏传感器控制蜂鸣器警报

1.电路连接图

工程文件添加的操作步骤跟上面的一模一样的,这里我就给大家看结果,要添加哪些文件,步骤不熟悉的话请重新看什么的就行了,这里就不多说了。

2.代码编写

(1)蜂鸣器模块

Buzzer.c文件

#include "stm32f10x.h"                  // Device header


void Buzzer_init(){

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	
	GPIO_InitTypeDef GPIO_initstruct; 
	GPIO_initstruct.GPIO_Mode=GPIO_Mode_Out_PP; 
	GPIO_initstruct.GPIO_Pin=GPIO_Pin_12;
	GPIO_initstruct.GPIO_Speed=GPIO_Speed_50MHz;
	
	GPIO_Init(GPIOB,&GPIO_initstruct);
	
	GPIO_SetBits(GPIOB,GPIO_Pin_12);
	
}
//低电平亮
void Buzzer_ON(){
	GPIO_ResetBits(GPIOB,GPIO_Pin_12);
}
void Buzzer_OFF(){
	GPIO_SetBits(GPIOB,GPIO_Pin_12);
}


//电平翻转
void Buzzer_turn(){
	//读取输出的电平,然后去调整
	if (GPIO_ReadOutputDataBit(GPIOB,GPIO_Pin_12)==0){
		GPIO_SetBits(GPIOB,GPIO_Pin_12);
	}
	
	else{
		GPIO_ResetBits(GPIOB,GPIO_Pin_2);
	}	
}


Buzzer.h文件

#ifndef __BUZZER_H
#define __BUZZER_H

void Buzzer_init();
void Buzzer_ON();
void Buzzer_OFF();
void Buzzer_turn();


#endif
(2)光敏传感器模块

Lightsensor.c文件

#include "stm32f10x.h"                  // Device header


void Lightsensor_init(){

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	
	GPIO_InitTypeDef GPIO_initstruct; 
	GPIO_initstruct.GPIO_Mode=GPIO_Mode_IPU; 
	GPIO_initstruct.GPIO_Pin=GPIO_Pin_13;
	GPIO_initstruct.GPIO_Speed=GPIO_Speed_50MHz;
	
	GPIO_Init(GPIOB,&GPIO_initstruct);
	
}

uint8_t Lightsensor_get(){
	//有光的时候,io口输入高电平到stm32,被读取到;光线不好,就输入低电平
	return GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_13);
}

Lightsensor.h文件

#ifndef __LIGHTSENSOR_H
#define __LIGHTSENSOR_H
void Lightsensor_init();
uint8_t Lightsensor_get();

#endif
(3)主函数main.c 
#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "Lightsensor.h"
#include "Buzzer.h"

int main(void)
{	
	
	Buzzer_init();
	Lightsensor_init();
	while(1){
		
		
		if(Lightsensor_get()==1){
			Buzzer_ON();
		}
		
		else{
		
		Buzzer_OFF();
		
		}
		
	}
}


现象的话就是,当你用手遮住光敏传感器的时候,蜂鸣器就会响起来。

以上就是本期的全部内容了,我们下次见!

每日壁纸:

相关推荐

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-17 09:32:01       67 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-17 09:32:01       72 阅读
  3. 在Django里面运行非项目文件

    2024-07-17 09:32:01       58 阅读
  4. Python语言-面向对象

    2024-07-17 09:32:01       69 阅读

热门阅读

  1. 通过手机控制家用电器的一个程序的设计(一)

    2024-07-17 09:32:01       25 阅读
  2. 深度学习中的正则化技术 - 稀疏表示篇

    2024-07-17 09:32:01       27 阅读
  3. CPTAC蛋白数据库在线蛋白分析(癌与癌旁)

    2024-07-17 09:32:01       24 阅读
  4. Shiro 学习总结

    2024-07-17 09:32:01       24 阅读
  5. 面试题 27. 二叉树的镜像

    2024-07-17 09:32:01       30 阅读
  6. 从三个方向来谈谈开源项目有哪些机遇与挑战

    2024-07-17 09:32:01       25 阅读
  7. 告别自动激活:掌握如何在Conda中禁用Base环境

    2024-07-17 09:32:01       29 阅读
  8. 中国电子学会青少年编程等级考试真题下载

    2024-07-17 09:32:01       24 阅读
  9. Shell

    Shell

    2024-07-17 09:32:01      24 阅读
  10. 01.Verilog基础语法

    2024-07-17 09:32:01       22 阅读
  11. 音视频开发入门教程(1)如何安装FFmpeg?共210节

    2024-07-17 09:32:01       21 阅读