本节以按键输入控制LED为例展开;
1.按键介绍
按键:常见的输入设备,按下导通,松手断开
按键抖动:由于按键内部使用的是机械式弹簧片来进行通断的,所以在按下和松手的瞬间会伴随有一连串的抖动。要对抖动过滤,否则会有按键一下单片机反应多次的现象。(消抖有硬件消抖:RS触发器,电容器;有软件消抖:延时函数,定时器消抖)因为在按键输入的过程中使用的是模拟输入,在io口电路中跳过了施密特触发器。
按键抖动
常见的GPIO输入还有传感器输入,对于传感器模块做一些简单的介绍:传感器元件(光敏电阻/热敏电阻/红外接收管等)的电阻会随外界模拟量的变化而变化,通过与定值电阻分压即可得到模拟电压输出,再通过电压比较器进行二值化即可得到数字电压输出。
对于上拉电阻,下拉电阻:包括有弱上拉,弱下拉,强上拉,强下拉;这里的强弱指的是电阻阻值的大小,也即是“弹簧弹力的大小”,其中阻值越小,“弹簧拉力”越强。上拉下拉指的是接到VCC还是GND,也就是“杆子”拉向“屋顶还是地面“,最终输出电压就是“弹簧”拉扯下最终“杆子”高低。
对于本stm32f103 rct6 mini开发板,案件在开发板的硬件图如下:
KEY0和 KEY1是低电平有效的,而 WK_UP是高电平有效的, 除了KEY1有上拉电阻(与 JTDI共用,其输入模式可以是上拉输入或者浮空输入),其他两个 都没有上下拉电阻,所以,需要在 STM32内部设置上下拉。对这句话的解释:例如WK_UP,当按键松开时,PA0被悬空,引脚电压出现不确定的情况,所以需要设置上下拉输入模式。
2.C语言复习
C语言数据类型:
C语言宏定义:
关键字:#define
用途:用一个字符串代替一个数字,便于理解,防止出错;提取程序中经常出现的参数,便于快速修改
定义宏定义:#define ABC 12345
引用宏定义:int a = ABC; //等效于int a = 12345;
C语言typedef:
关键字:typedef
用途:将一个比较长的变量类型名换个名字,便于使用
定义typedef: typedef unsigned char uint8_t;
引用typedef: uint8_t a; //等效于unsigned char a;
宏定义和typedef的区别在于:首先,宏定义的新名字在左边,typedef的新名字在右边。然后是,宏定义不需要分号,typedef后面必须加分号。还有就是宏定义任何名字都可以换,而typedef只能专门给变量类型换名字。宏定义范围广,只不过对于变量类型重命名,使用后者更安全。因为typedef会对命名进行检查,如果不是变量类型的名字,那是不行的。
C语言结构体:
关键字:struct
用途:数据打包,不同类型变量的集合
定义结构体变量: struct{char x; int y; float z;} StructName;
因为结构体变量类型较长,所以通常用typedef更改变量类型名
引用结构体成员:
StructName.x = 'A';
StructName.y = 66;
StructName.z = 1.23;
或 pStructName->x = 'A'; //pStructName为结构体的地址
pStructName->y = 66;
pStructName->z = 1.23;
结构体是一种组合数据类型,在函数之间的数据传递中通常用的地址传递而不是值传递(具体参考江协科技关于指针的讲解)
C语言枚举:
关键字:enum
用途:定义一个取值受限制的整型变量,用于限制变量取值范围;宏定义的集合
定义枚举变量:
enum{FALSE = 0, TRUE = 1} EnumName; //因为枚举变量类型较长,所以通常用typedef更改变量类型名
引用枚举成员:
EnumName = FALSE;
EnumName = TRUE;