历史上的今天
今天是:2024年10月09日(星期三)
2019年10月09日 | 4*4键盘程序代码 基于STM32
2019-10-09 来源:eefocus
这是自己写的扫描第一行按键的程序代码。
PE的位8~位11设置为下拉输入。
PE的位12~位15设置为推挽输出
其中PE的位11是4*4键盘的第一列,PE的为键盘的第一行。
先将第一行设置为高电平,检测列中是否有高电平
u8 KEY_Scan(u8 mode)
{
staticu8 key_up=1;//按键按松开标志
if(mode)key_up=1; //支持连按
GPIO_SetBits(GPIOE,GPIO_Pin_15);
if(key_up&&( (GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_8))
||(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_9))
||(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_10))
||(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_11)) ) )
{
delay_ms(10);//去抖动
key_up=0;
if(GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_8) )return 10;
elseif( GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_9) )return 3;
elseif( GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_10) )return 2;
elseif( GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_11) )return 1;
}elseif( (GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_8))==0
&&(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_9))==0
&&(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_10))==0
&&(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_11))==0 )key_up=1;
return 0;// 无按键按下
}
写好扫描一行后,对比网上别人写的代码,发现写的十分冗长,原因:调用了库函数的位操作函数对4位进行操作。而不是进行整理处理。然后改写如下:
GPIO_Write(GPIOE,0x8000);
if((key_up) && (GPIOE->IDR & 0x0f00) )
{
delay_ms(10);//去抖动
key_up=0;
switch(GPIOE->IDR & 0x0f00 )
{
case 0x0100: KeyVal=10; break;
case 0x0200: KeyVal=3; break;
case 0x0400: KeyVal=2; break;
case 0x0800: KeyVal=1; break;
}
}
elseif ( ( GPIOE->IDR & 0x0f00) ) ;key_up=1; //若松开按键,则将key_up置一。
改写成功后,自己就以为4*4键盘只要将代码复制,改动一下GPIO_Write(GPIOE, 0x8000);中的数值。
结果发现只有最后一行的按键不支持连按。其他的若一直按着,就会一直刷新按键值(自己在串口中观察,相关代码未贴出来)。不符合自己设计的要求,即按键不支持连按。
于是进入Debug模式。逐行调试,观察GPIOE的输入数据寄存器(GPIOx_IDR),由于是if语句判断,当没松开后就程序就会运行扫描第二行的代码时,写GPIO_Write(GPIOE,0x4000)时候,(GPIOx_IDR) 的值就改变了,因此后面的if语句就会将key_up就会被置一,而非等到自己按键松开了。长按自然会反复刷新按键值。
只要将if语句改为while语句即可。即按键送下来之前不进行后面的扫描!
这个问题很简单,自己在写的时候都没有发现。不过最终还是调试出来了。
自己写程序会犯各种低级错误,比如自己甚至连 & 和 &&都未区分开来,后面自己在编译器写了一段测试代码才区分开来。
这会让在上面浪费很多时间。上面说的小问题,就耗费了自己数个小时,因为自己之前都是在脑袋中想象代码的的执行流程。。。
但是我还是要坚持这种学习方法,问题虽然会很多,但也正是如此才能发现自己的缺陷,自己去思考,去写了代码,对知识的理解也会更深。
史海拾趣
|
各位前辈们 谁用过 sc32442这系列的芯片?很想知道这系列的不同型号有什么区别? 怎么命名的? 各位前辈们 你们谁用过 sc32442这系列的芯片?小弟要用这颗料做个手持设备 发现有很多型号 SC32442BL-33 SC32442B43-7080 SC32442B54 SC32442AL-43S SC32442AL-45 SC32442XL-31 SC32442X33-7080 SC32442X31-7080 SC32442AL-33 SC32442A45 ...… 查看全部问答> |
|
感谢helenhf的回复我上个问题,那个问题已经解决。是MPC8280的PCI内部空间和外部空间有一个转换关系,即outwindow地址,PCI设备的基地址应设置为0x50000000,此时 d 0x80000000 就可以看到PCI设备的寄存器了。 &nb ...… 查看全部问答> |
|
我通过vs2005 部署到wince板子上 但是重启又没了 我新建的文件夹也没了. 现在有一个 sd存储卡, 要不就写入到卡里 ,让他开机自动运行,但是 不知道怎么弄?… 查看全部问答> |
|
最近在学NIOSII编程,参考别人的,写了一个很简单的程序定时器程序,编译老是出错。一直找不出原因,老是出现这个错误 multiple definition of `main\' 快疯了。现把程序贴上,求高手指点。 #include\"system.h\"#include \"altera_avalon_timer ...… 查看全部问答> |




