目录
前言
本期继续学习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(); } } }
现象的话就是,当你用手遮住光敏传感器的时候,蜂鸣器就会响起来。
以上就是本期的全部内容了,我们下次见!
每日壁纸: