OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 7161|回复: 1

如何根据扫描键码组合成多位数字显示

[复制链接]

9

主题

20

帖子

0

精华

初级会员

Rank: 2

积分
85
金钱
85
注册时间
2012-11-22
在线时间
3 小时
发表于 2012-11-24 16:45:53 | 显示全部楼层 |阅读模式
现在的问题是,我用STM32接了一个4*4键盘,还有一块12864液晶,显示,还有键盘扫描都已调试成功,我定义的键码是0-15,当我按下10键时进入参数设置子程序,接下来就是需要按下0-9之间的键了,那么我如何才能根据我多次按下的单个按键,最后组合成3位 或多位数字呢  ?

参考了如下的程序:矩阵键盘扫描程序,程序名是void anjian(),他最后得到一个返回的键值,把这个键值传给一个变量key,关系式是key=anjian(),这样我只要去检测key的值就可以知道是哪个键按下了,因为矩阵键盘需要循环调用,所以我用的是do....while语句,程序如下:
n=0;
flag=0;
do
{
    key=anjian();
    if(key<10)//按下的是0-9的数字键
    {
       n=10*n+key;
    }
    if(key==11)//OK键被按下
        flag=1;
    if(key==12)//EXIT被按下
        flag=1;
}
while(!flag)

我也经过修改尝试过了,但是不对头啊,请各位大神看看那个   if(key<10) { n=10*n+key;}      岂不是自己就在do循环内做累加运算了啊,我调试的时候发现只要一有数字键按下,数据N直接就直接溢出了啊,请大家给点建议,谢谢,
下面是我修改的部分程序:
 while(1)
{

int n=0,keyv;
char flag=0;
if(key()==10) //SET KeyPressed
 {
do
{
delay_ms(50);
    keyv=key();
 
  if(keyv<10)//按下的是0-9的数字键
  {
      n=10*n+keyv;      
  }
   if(keyv==11)//OK键被按下
       flag=1;
   if(keyv==12)//EXIT被按下
       flag=1;
LCD_Dis_Digital(3, 4,n) ; //键码显示
}
while(!flag);
}
其中的key()函数已经做成 只允许单次有效 ,长按不会持续有扫描输出     
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

9

主题

20

帖子

0

精华

初级会员

Rank: 2

积分
85
金钱
85
注册时间
2012-11-22
在线时间
3 小时
 楼主| 发表于 2012-11-24 16:48:03 | 显示全部楼层
int key(void)  //实现矩阵键盘。返回值为,各按键的键值,此键值由用户自己定义。
{
  
 static int KeyVal=0;  //keyVal为最后返回的键值。

    GPIOB->ODR&=0x00ff; //先让PB8到PB11全部输出高。
GPIOB->ODR|=0x0f00 ;

if((GPIOB->IDR&0xf000)==0x0000)  //如果,PB12到PB15全为0,则,没有键按下。此时,返回值为-1.
{
return 66;
}
else
{
delay_us(5000);    //延时5ms去抖动。
if((GPIOB->IDR&0x0f000)==0x0000)  //如果,延时5ms后,PB4到PB7又全为0,则,刚才引脚的电位变化是抖动产生的.
   {

LED0=0; //无按键操作Red-ELD点亮
KK1=0;KK2=0;
return 66;
}
}

if(KK1==0x55)
 {
if(KK2==0x55)
   {return 0;}
 else
   {
LED0=1; //有按键操作Red-ELD熄灭

GPIOB->ODR=GPIOB->ODR&0x00ff|0x0100;   //让PB8到PB11输出二进制的0001.

switch(GPIOB->IDR & 0xf000)                 //对PB12到PB15的值进行判断,以输出不同的键值。
{
case 0x1000: KeyVal=0; break;
case 0x2000: KeyVal=1; break;
case 0x4000: KeyVal=2; break;
case 0x8000: KeyVal=3; break;
}
GPIOB->ODR=GPIOB->ODR&0x00ff|0x0200; 
  

switch(GPIOB->IDR & 0xf000)                 //对PB12到PA15的值进行判断,以输出不同的键值。
{
case 0x1000: KeyVal=4; break;
case 0x2000: KeyVal=5; break;
case 0x4000: KeyVal=6; break;
case 0x8000: KeyVal=7; break;
}

GPIOB->ODR=GPIOB->ODR&0x00ff|0x0400; 

switch(GPIOB->IDR & 0xf000)                 //对PB12到PB15的值进行判断,以输出不同的键值。
{
case 0x1000: KeyVal=8; break;
case 0x2000: KeyVal=9; break;
case 0x4000: KeyVal=10; break;
case 0x8000: KeyVal=11; break;
}

    GPIOB->ODR=GPIOB->ODR&0x00ff|0x0800; 

switch(GPIOB->IDR & 0xf000)                 //对PB12到PB15的值进行判断,以输出不同的键值。
{
case 0x1000: KeyVal=12; break;
case 0x2000: KeyVal=13; break;
case 0x4000: KeyVal=14; break;
case 0x8000: KeyVal=15; break;
}


KK2=0X55;
return KeyVal;
   }
   }
 else
{KK1=0x55;return 0;}

}
这是我的键盘扫描部分程序
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-7-18 21:41

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表