点灯与按键实验
点灯实验
步骤
1.初始化HAL库
2.设置时钟
3.开启时钟
4.配置GPIO参数
5.初始化GPIO
6.调用HAL库往引脚写入信号

编译结果

Code:表示程序所占用 FLASH 的大小(FLASH)。
RO-data:即 Read Only-data,表示程序定义的常量(FLASH)。
RW-data:即 Read Write-data,表示已被初始化的变量(SRAM)
ZI-data:即 Zero Init-data,表示未被初始化的变量(SRAM)
有了这个就可以知道你当前使用的 flash 和 sram 大小了,所以,一定要注意的是程序的大小不是.hex 文件的大小,而是编译后的 Code和 RO-data 之和
按键输入实验
按键介绍
物理按键是一个机械开关,按下时两端短接,松开时断开
疑难
前置:按键的高/低电平有效是指被按下后的电平状态
例子:
松开时为低电平(默认状态)。
按下时为高电平(有效状态)。
解释:
以KEY_UP为例,当按键松开时,按键两端断开,电路不连通,PA0 引脚被拉到低电平(0),保持稳定;当按键按下时,按键两端短接,电路连通,PA0 引脚直接连接到 VCC,变为高电平(1)。KEY_UP采用下拉电阻。

问题:为什么要用下拉电阻?
当按键未被按下时,按键两端断开,电路不连通,此时PA0会受到KEY_UP电位变化的影响(比如如果KEY_UP此时是高电平,则PA0也是高电平;KEY_UP此时是低电平,则PA0也是低电平)。
如果采用浮空输入,那么电平可能是0也可能是1,最有可能是0-1之间的电平,PA0收到的电平不稳定,不采用。
如果采用上拉输入,此时默认电平为1,则PA0收到的也是1,没问题;但是当按键被按下时,按键两端短接,电路连通,KEY_UP会产生低电平,电源会产生高电平,此时相当于PA0直接接到电源上(因为引脚在接收到按键的低电平后,后续始终会收到电源的高电平),收到的是1,按与没按没区别,不采用
如果采用下拉输入,此时默认电平是0,则PA0收到的也是0;当按键被按下时,按键两端短接,电路连通,KEY_UP会产生高电平,电源会也产生高电平,则PA0收到的是1。没按是0,按了是1,采用。
KEY0 ,KEY1,KEY2同理
总结:接了电源时,按下按键,引脚收到的信号和电源一样,所以在没按下按键时默认电平要选择和电源信号不一样的,从而选择是上拉还是下拉

代码分析
u8 KEY_Scan(u8 mode)
{
static u8 key_up=1; //按键松开标志
if(mode==1)key_up=1; //支持连按
if(key_up&&(KEY0==0||KEY1==0||KEY2==0||WK_UP==1))
{
delay_ms(10);
key_up=0;
if(KEY0==0) return KEY0_PRES;
else if(KEY1==0) return KEY1_PRES;
else if(KEY2==0) return KEY2_PRES;
else if(WK_UP==1) return WKUP_PRES;
}else if(KEY0==1&&KEY1==1&&KEY2==1&&WK_UP==0)key_up=1;
return 0; //无按键按下
}static u8 key_up=1; 语句并不是函数的一部分,因为静态变量和全局变量在程序调入内存是就已经就位了。运行函数是static u8 key_up=1; 看起来是跳过了。key_up的存储类是空连接的静态。
函数中 static u8 key_up=1; 定义后,当KET_Scan运行结束后,key_up并不消失,而是保留了赋予的0值,函数下一次运行时仍旧是执行0值

使用读取函数获取按键信息,并用宏定义增加可读性

但是获取输出的函数不能直接换成HAL库,因为有个设置参数,这里只是想要获得状态

PH2,3省略是因为GPIO配置除了引脚都和上面一样,只需改引脚然后直接套用上面的,可用CubuMX生成

