STM32学习笔记3-GPIO输入部分

发布于:2025-08-07 ⋅ 阅读:(24) ⋅ 点赞:(0)

输入部分:

外设:

        按键

按键:常见的输入设备,按下导通,松手断开

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

抖动情况在单片机中会显得很漫长,所以我们需要进行对抖动的过滤,最简单的办法是加一段延时,把抖动的时间耗过去即可

       传感器模块:

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

电路结构基本相同,唯一不同只有N1电阻的传感功能的区别

N1: 传感器元件所代表的可变电阻,它阻值可以根据环境的光线,温度等模拟量进行变化

R1:  是和N1进行分压的定值电阻,与N1串联,相互连接VCC和GND

C2:  滤波电容,为了给中间的电压输出进行滤波的,保证电路的平滑,它不是基本的电路结构,在分析的时候,一般先将此元件抹去,以方便分析电路。

补:滤波是信号处理中的一种技术,主要用于去除信号中的噪声或提取有用信息

传感器的电阻的阻值对输出电压的影响:

补:电阻对电压的影响:

欧姆定律:I=V/R           电阻越大,电流越小

串联电路:电阻分压,V1=V总×(R1/(R1+R2))
​并联电路:电压相同

当N1的电阻为0时,此时AO的电压输出GND=0V,

当R1的电阻为0时,此时AO的电压输出VCC,

当两者都为0时,此时AO会处于短路的状态

当两边都存在一定的”拉力”,电压会取向”拉力”大的一方,需要考虑”拉力”差

当两边”拉力”一样,会输出水平的电压=2V

AO经过此操作就会直接输出,此端口还可以数字输出,也就是对AO进行二值化的输出

二值化输出:

主要有LM393这个芯片完成的,本身是一个电压比较器芯片,里面有两个独立的电压比较器电路,剩下的就是VCC和GND进行供电;

电压比较器本身就是运算放大器

当这个同相输入端的电压大于反相输入端的电压时,输出会瞬间升高为最大值,使输出接VCC;

反之,样就直接对一个模拟电压进行二值化了

C1:为一个电源供电的滤波电容

分压电阻,与之前的分压逻辑同理

硬件电路

通常是以下接(低电平)的方式

按键: ,当按键按下时,此时输出为低电平,松开以后,电平会进入浮动状态,所以需要将PA0默认为平;

\

这个则是用分压电路的原理,当按键按下时,引脚为低电平,同理,只是这种状态当按键松开,引脚不会存在浮动状态,所以PA0可以设置上拉状态,这样可使按键松开时,电路更稳定.

传感器的电路

C语言补充:

由于C语言本身某些类型是使用到对应的数值上的,比如:char一般对字符;但是在单片机中通常是把char用在8为整数上面,所以存在一个stdint的关键字和ST的关键字,将这个类型进行重命名以便使用和观察

实验:

有关常用的带返回值的函数:

GPIO中的输入函数

uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); //读取输入数据寄存器某一个端口的输入值

uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx); //读取整个输入数据寄存器,返回16位,每一个端口数据返回

GPIO的输入函数

uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);  //读取输出数据寄存器的某一位,一般用输出模式下,用来看自己的数据输出什么样子

uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);  //读取整个输出数据寄存器

注:编程中尽可能的进行模块化的函数管理

按键控制LED

接线图

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

//按键控制LED :LED+按键:通过函数拿到值,根据0或1来判断LED
uint8_t Keynum;
int main(void){
	LED_Init();//初始化LED
	Key_Init();//初始化按键

	while(1){
			Keynum=Get_Keynum();
		if(Keynum==1){ 	//当取得的输入值为1,则按1按键
			LED1_Turn();
		}
		if(Keynum==2){
			LED2_Turn();
		}
	}

LED.c
#include "stm32f10x.h"                  // Device header
void LED_Init(void){
		//定义LED
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//定时钟
	//调用GPIO
	//创建GPIO_Init函数中的结构体变量
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1|GPIO_Pin_2;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);//由于LED接入的是低电压,所以我们配置的也是低电压,所以不需要配置输出电压就能让LED灯点亮
	GPIO_SetBits(GPIOA,GPIO_Pin_1|GPIO_Pin_2);//将LED灯配置为高电压,避免一直亮
}

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

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

//加功能,目前的情况是按下,会使灯亮,但是松开则不行
void LED1_Turn(void){
	 //通过查看输出电压值,来自动跳动灯的情况
	if(GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_1)==0){//读取输出数据寄存器的某一位,一般用输出模式下,用来看自己的数据输出什么样子
		GPIO_SetBits(GPIOA,GPIO_Pin_1);
	}
	else{
		GPIO_ResetBits(GPIOA,GPIO_Pin_1);
	}
}
void LED2_Turn(void){
	if(GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_2)==0){
		GPIO_SetBits(GPIOA,GPIO_Pin_2);
	}
	else{
		GPIO_ResetBits(GPIOA,GPIO_Pin_2);
	}
}

Key.c
#include "stm32f10x.h"                  // Device header
#include "Delay.h"
void Key_Init(void){
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	
	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 Get_Keynum(void){
	uint8_t Keynum=0;//记录按键1和按键2,按键1按的记录为1,按键2按的记录为2;
	if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1)== 0){//1按键,读取输入数据寄存器某一个端口的输入值,如果输入的值为0,则说明按下按键,则逻辑使LED灯亮
		//由于按键是存在抖动的情况(按下和松开)的,所以需要考虑到过滤抖动的情况
		Delay_ms(20);
		while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1)==0);//当返回值为0,则为按下的状态,松开时则为1
		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;
} 

光敏传感器控制蜂鸣器

接线图

main.c
#include "stm32f10x.h"                  // Device header
#include "LED.h"
#include "Key.h"
#include "Delay.h"
#include "Sensor.h"
#include "Buzzer.h"
//3-5 光敏传感器控制蜂鸣器:
//1对其外设进行初始化
//2蜂鸣器的启动:输出设备
//3光敏传感器的启动:输入设备
//4拿到输入值,通过输入值来启动蜂鸣器
//目的:当光敏传感器不亮时蜂鸣器报警
int main(void){
	Sensor_Init();
	Buzzer_Init();
	while(1){
		if(Get_Sensor()==1){
			Buzzer_ON();
		}
		else
			Buzzer_OFF();
	}

}

Sensor.c
#include "stm32f10x.h"                  // Device header
void Sensor_Init(void){
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	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 Get_Sensor(void){
	return GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_13); 
}

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);
}
//蜂鸣器的开关,默认是低电压叫
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);
	}
}


网站公告

今日签到

点亮在社区的每一天
去签到