按键:常见的输入设备,按下导通,松手断开
按键抖动:由于按键内部使用的是机械式弹簧片来进行通断的,所以在按下和松手的瞬间会伴随有一连串的抖动
1.2 传感器模块简介传感器模块:传感器元件(光敏电阻/热敏电阻/红外接收管等)的电阻会随外界模拟量的变化而变化,通过与定值电阻分压即可得到模拟电压输出,再通过电压比较器进行二值化即可得到数字电压输出
分别是光敏电阻传感器(光线越强,光敏电阻的阻值就越小)
热敏电阻传感器(温度越强,热敏电阻的阻值就越小)
对射式红外传感器(红外越强,红外接收管的阻值就越小)
反射式红外传感器
滤波电容:保持电路稳定
硬件电路
一般是这种(下接模式)
第一张图,当K1按下,PA0被下拉到GND,此时读取PAO口的电压就是低电平;
当K1松开,PA0被悬空,引脚的电压不确定,此时必须要求PA0是上拉输入,否则会出现引脚电压不稳定的错误现象。
第二张图多了一个上拉电阻。当按键按下时,PA0被下拉到GND,此时读取PAO口的电压就是低电平;
当按键松开时,引脚由于上拉作用,自然保持高电平。
这种接法下,PA0需要配置成上拉输入或者浮空输入。
所以上面这两种接法,按键按下是低电平,松手是高电平。
上接模式
第三张图,PA0通过按键接到3.3V,要求PA0必须配置成下拉输入的模式。
当按键按下时,引脚为高电平;松手时,引脚为低电平。(一般单片机可能没有下拉输入模式)
第四张图,PA0需要配置成下拉输入或者浮空输入。
下面这两种接法,按键按下是高电平,松手是低电平。
传感器模块
DO是数字输出;AO是模拟输出(ADC模拟转换器)。
C语言数据类型
关键字
位数
表示范围
stdint关键字
ST关键字
char
8
-128 ~ 127
int8_t
s8
unsigned char
8
0 ~ 255
uint8_t
u8
short
16
-32768 ~ 32767
int16_t
s16
unsigned short
16
0 ~ 65535
uint16_t
u16
int
32
-2147483648 ~ 2147483647
int32_t
s32
unsigned int
32
0 ~ 4294967295
uint32_t
u32
long
32
-2147483648 ~ 2147483647
unsigned long
32
0 ~ 4294967295
long long
64
-(2^64)/2 ~ (2^64)/2-1
int64_t
unsigned long long
64
0 ~ (2^64)-1
uint64_t
float
32
-3.4e38 ~ 3.4e38
double
64
-1.7e308 ~ 1.7e308
2 GPIO输入之按键控制LED灯 2.1 接线图低电平点亮
2.2 封装模块新建文件夹HardWare,模块化代码
先封装GPIO。LED.c,记得加上LED.h
#include "stm32f10x.h" // Device header// LED初始化函数void LED_Init(void){// 1使用RCC开启GPIO的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);// 2使用GPIO_Init函数初始化GPIO[推挽输出50MHz]GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;// 推挽输出GPIO_Init(GPIOA, &GPIO_InitStructure);// 3初始化熄灭GPIO_SetBits(GPIOA, GPIO_Pin_1 | GPIO_Pin_2);}// 点亮LED1函数void LED1_ON(void){GPIO_ResetBits(GPIOA, GPIO_Pin_1);}// 熄灭LED1函数void LED1_OFF(void){GPIO_SetBits(GPIOA, GPIO_Pin_1);}// 点亮LED2函数void LED2_ON(void){GPIO_ResetBits(GPIOA, GPIO_Pin_2);}// 熄灭LED2函数void LED2_OFF(void){GPIO_SetBits(GPIOA, GPIO_Pin_2);}// LED1反转void LED1_Turn(void){// 读取当前端口输出状态,如果输出是0,就置1;否则置0if (GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_1) == 0){GPIO_SetBits(GPIOA, GPIO_Pin_1);}else{GPIO_ResetBits(GPIOA, GPIO_Pin_1);}}// LED2反转void LED2_Turn(void){// 读取当前端口输出状态,如果输出是0,就置1;否则置0if (GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_2) == 0){GPIO_SetBits(GPIOA, GPIO_Pin_2);}else{GPIO_ResetBits(GPIOA, GPIO_Pin_2);}}再封装按键。KEY.c,记得加上KEY.h
#include "stm32f10x.h" // Device header#include "Delay.h"// 按键初始化函数// 上拉输入模式void KEY_Init(void){// 1使用RCC开启GPIO的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);// 2使用GPIO_Init函数初始化GPIO[推挽输出50MHz]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;// 1号端口if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0){// 刚按下,有抖动Delay_ms(20);// 检查按键松手while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0){Delay_ms(20);KeyNum = 1;}}// 11号端口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;} 2.3 主函数测试代码,主函数
#include "stm32f10x.h" // Device header#include "Delay.h"#include "LED.h"#include "KEY.h"uint8_t keyNum;int main(){LED_Init();KEY_Init();while (1){keyNum = KEY_GetNum();// 按键1按下,点亮LED1if (keyNum == 1){LED1_Turn();}// 按键2按下,熄灭LED1if (keyNum == 2){LED2_Turn();}}}代码结构图
我的按键11不起作用,不能控制GPIOA_Pin_2的亮灭。