##源于b站up主 竞赛窖头 使用的是 hal库 芯片:STM32F103VET6 野火指南者
对于平常读取按键的写法 大家可能就是按照 江科大 或者 其他商家给的模板来进行读取。
今天,我将使用寄存器的角度 来分析读取。 先给大家上代码
1.ws_driver_borad.c (我自己的文件 大家可以改)
/*
读取 方法:
// 使用(uint8_t) 就是取GPIOX->IDR的低8位
// 0xfffe ---> 0x1111 1111 1111 1101 为1 的地方是屏蔽 为 0的地方保留下来读取
key = GetKeyDFallingEdge((uint8_t)(GPIOA->IDR | 0xfffe)); // sw1
*/
// 获取按键 下降沿函数,调用无要求: 1~10 间隔使用
char GetKeyDFallingEdge(unsigned char io) // char : 0-255
{
char key = 0; //局部变量
static char countFlag = 0; //静态变量
if(io != 0xff) //说明有按键按下
{
if(countFlag < 3) countFlag++; // 1,2,3
if(countFlag == 2) //连续进入两次 实现去抖
{
switch(io)
{
case 0xfe: key=1;break; // 1111 1110,sw1
case 0xfd: key=2;break; // 1111 1101 ,sw2
case 0xfb: key=3;break; // 1111 1011 ,sw3
case 0xf7: key=4;break; // 1111 0111, sw4
case 0xef: key=5;break; // 1110 1111, sw5
}
}
}
else
{
countFlag = 0;
}
return key; //返回键值
}
1.对于这个读取, 我们给了一个 io作为传入参数 io 是 寄存器 与 我们想要读取的按键范围 进行逻辑或的结果。
2.0xff 作为没有按下按键的判断 因为 我们这里是上拉操作,GPIO口的读取是默认---高电平,那么没有进行按键按下操作时,我们读入的,不都是高电平。
3.countflag 是我们用来进行 按键消除抖动的 ,并且给了它一个静态处理,当每次进入该函数时,这个变量才会改变。 这里是利用单片机 中的while(1) 循环读取 按键。 所以countflag 一旦到2的时候,就进入 对按键的键值判断。
4.这里的判断是 以io的值进行判断 , 请看到我的注释处 罗列出来的二进制,可以看到 键值与0的位置相对应。 符合对应的条件 就返回 键值。
// 使用(uint8_t) 就是取GPIOX->IDR的低8位
// 0xfffe ---> 0x1111 1111 1111 1101 为1 的地方是屏蔽 为 0的地方保留下来读取
key = GetKeyDFallingEdge((uint8_t)(GPIOA->IDR | 0xfffe)); // sw1
这个代码就是对应的读取方法。
用法:
1.GPIOx 是 你按键所在的GPIO, 我这里的按键1 是在 PA0 所以我给的是 GPIOA
2.GPIOX->IDR 这个请查你的数据手册了解具体作用,这个是通用的哈。 我们只能读取它的低16位数,所对应的就是它的引脚。每一位都有对应的引脚。
比如说 PA0 --- GPIOA->IDR的第0位, 那么如果我们只需读取第0位呢? 使用逻辑或的方式。想要读取的那一位,我们设置为0 .其他的都为1 , 这个寄存器是32位的,所以高16位,我们都给1。也就是0xff , 低16位,是我们要进行操作的。 比如说我要读取第0位 。 那么我就给
0xfffe. 我们现在只关注低16位 也就是 1111 1110 你看我这里的第0位 是不是0? 如果想多读连续几位, 比如说读5位,那么按键范围就是 sw1- sw5 ---- 0xffe0 低16位 也就是 这个---1110 0000 。
在这里,你看到我还有一个(uint8_t)的强制类型转换操作。 因为我只需读取低8位的话,我就直接限制读取范围了,这样就更加精确了。 记住了GPIOx->IDR 的高16位是不能进行操作的。 只有低16位才可以进行操作。
以上就是我对这次学习的总结。如果有任何疑问,欢迎留言讨论。
本站资源均来自互联网,仅供研究学习,禁止违法使用和商用,产生法律纠纷本站概不负责!如果侵犯了您的权益请与我们联系!
转载请注明出处: 免费源码网-免费的源码资源网站 » 关于STM32型号按键读取的不同思想
发表评论 取消回复