6563|16

74

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

keil 里变量的问题 [复制链接]

我在用keil写一个89s52的矩阵键盘输入程序,其中我想纪录键盘输入的次数,但是变量"y"老是无变化,
都不知道怎么回事。哪位老大能告诉我一下是怎么回事?还有keil的C语言和VC或TC有什么不同吗(语句、变量、类型...)?
keil的C语言里有类似VC里的CString这种东西吗?这东西我刚用,不是很明白,请老大们多指教一下,先谢谢了。

  1. #include
  2. #define uchar unsigned char
  3. #define uint  unsigned int
  4. unsigned char code seg[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};//分别对应相应的数码管点亮


  5. uchar keyscan(void);
  6. void delay(uint i);
  7. void printdata(uint i,uint j);

  8. void main()
  9. {
  10.         uint y=0;
  11.         uchar key;
  12.         while(1)
  13.         {
  14.                 key=keyscan();//调用键盘扫描,
  15.                 switch(key)
  16.                 {
  17.                         case 0xee:        //printdata(0,7);  //这里都是没问题的,只是为了单独测试注释掉了
  18.                                                 y++;        //为按下的字符串记数
  19.                                                 break;
  20.                         case 0xed:        //printdata(1,7);
  21.                                                 y++;
  22.                                                 break;
  23.                         case 0xeb:        //printdata(2,7);
  24.                                                 y++;
  25.                                                 break;               
  26.                         case 0xe7:        //printdata(3,7);
  27.                                                 y++;
  28.                                                 break;               
  29.                         case 0xde:        //printdata(4,7);
  30.                                                 y++;
  31.                                                 break;               
  32.                         case 0xdd:        //printdata(5,7);
  33.                                                 y++;
  34.                                                 break;               
  35.                         case 0xdb:        //printdata(6,7);
  36.                                                 y++;
  37.                                                 break;               
  38.                         case 0xd7:        //printdata(7,7);
  39.                                                 y++;
  40.                                                 break;               
  41.                         case 0xbe:        //printdata(8,7);
  42.                                                 y++;
  43.                                                 break;               
  44.                         case 0xbd:        //printdata(9,7);
  45.                                                 y++;
  46.                                                 break;               
  47.                         case 0xbb:        y=0;        //清楚输入数量
  48.                                                 break;               
  49.                         case 0xb7:        y--;        //删除一个输入数量
  50.                                                 break;
  51.                         case 0x7e:        break;
  52.                         case 0x7d:        break;
  53.                         case 0x7b:        break;
  54.                         case 0x77:        break;
  55.                         default:        //printdata(10,7);        //默认 没有输入就下划线 _
  56.                                                 break;
  57.                                                
  58.                 }
  59.                 printdata(y, 0);    //问题主要是这里,数字管老显示的是下划线,不知道为什么
  60.                
  61.         }
  62. }
  63. uchar keyscan(void)//键盘扫描函数,使用行列反转扫描法
  64. {
  65.         uchar cord_h,cord_l;//行列值
  66.         P3=0xf0;
  67.         cord_h=P3&0xf0;
  68.         if(cord_h!=0xf0)    //先检测有无按键按下
  69.         {
  70.                 delay(100);
  71.                 if(cord_h!=0xf0)
  72.                 {
  73.                         cord_h=P3&0xf0;  //逐个检测是哪个按键按下?
  74.                         P3=cord_h|0x0f;
  75.                         cord_l=P3&0x0f;
  76.                         return(cord_h+cord_l);//键盘最后码值
  77.                 }
  78.         }
  79.         return(0xff);     //返回该值
  80. }

  81. void delay(uint i)//延时函数
  82. {
  83.         while(i--);
  84. }

  85. void printdata(uint i,uint j)        //输出数字到数码管
  86. {
  87.         P2=seg[j];        //表示最后一个数码管
  88.         switch(i)
  89.         {
  90.                  case 0:                P0=0xc0;break;        //0
  91.                 case 1:                P0=0xf9;break;        //1
  92.                 case 2:                P0=0xa4;break;        //2
  93.                 case 3:                P0=0xb0;break;        //3
  94.                 case 4:                P0=0x99;break;        //4
  95.                 case 5:                P0=0x92;break;        //5
  96.                 case 6:                P0=0x82;break;        //6
  97.                 case 7:                P0=0xf8;break;        //7
  98.                 case 8:                P0=0x80;break;        //8
  99.                 case 9:                P0=0x90;break;        //9
  100.                 case 10:        P0=0xf7;break;        //_
  101.         }
  102. }
复制代码

最新回复

不过想想,按键按下的值和放开的值是不一样的,应该也不需要那样处理。 应该还是很合理的触发事件的过程,除非作那种像电脑键盘一样的按钮,常按下按钮时, 定时触发一次输入事件。非常感谢各位的帮助,谢谢  详情 回复 发表于 2008-12-18 23:31
点赞 关注

回复
举报

76

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
矩阵按键?你的按键扫描不对。
 
 

回复

73

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
按键扫描没问题,我单独在单片机上测试过,数字管显示了相应的数字,
所以 y++; 是运行了的。
 
 
 

回复

90

帖子

0

TA的资源

一粒金砂(初级)

4
 
电路图是这样的,也不知道对不对,也请大家帮看看
其实我是想做一个密码锁。所以加了一个继电器来控制开锁的电磁阀。
主要没信心的是供电部分,不知道是该供电到VCC还是EA/VPP
 
 
 

回复

80

帖子

0

TA的资源

一粒金砂(初级)

5
 
好像忘记在P0加电阻了,呵呵
 
 
 

回复

70

帖子

0

TA的资源

一粒金砂(初级)

6
 
“uchar keyscan(void)//键盘扫描函数,使用行列反转扫描法”
这个函数有严重的问题。应该用两个嵌套的FOR循环对P3口进行逐位的读/写。
还有,修改后如能工作,要对键盘按键作防抖动处理。
 
 
 

回复

49

帖子

0

TA的资源

一粒金砂(初级)

7
 
引用 5 楼 areful 的回复:
“uchar keyscan(void)//键盘扫描函数,使用行列反转扫描法”
这个函数有严重的问题。应该用两个嵌套的FOR循环对P3口进行逐位的读/写。
还有,修改后如能工作,要对键盘按键作防抖动处理。

谢谢你的回答,但是问题不在键盘扫描上,因为程序改为这样是能够正常显示按键数字的。

  1. void main()
  2. {
  3.     uint y=0;
  4.     uchar key;
  5.     while(1)
  6.     {
  7.          key=keyscan();//调用键盘扫描,
  8.         switch(key)
  9.         {
  10.             case 0xee:    printdata(0,7);  //这里都是没问题的,只是为了单独测试注释掉了
  11.                         y++;    //为按下的字符串记数
  12.                         break;
  13.             case 0xed:    printdata(1,7);
  14.                         y++;
  15.                         break;
  16.             case 0xeb:    printdata(2,7);
  17.                         y++;
  18.                         break;        
  19.             case 0xe7:    printdata(3,7);
  20.                         y++;
  21.                         break;        
  22.             case 0xde:    printdata(4,7);
  23.                         y++;
  24.                         break;        
  25.             case 0xdd:    printdata(5,7);
  26.                         y++;
  27.                         break;        
  28.             case 0xdb:    printdata(6,7);
  29.                         y++;
  30.                         break;        
  31.             case 0xd7:    printdata(7,7);
  32.                         y++;
  33.                         break;        
  34.             case 0xbe:    printdata(8,7);
  35.                         y++;
  36.                         break;        
  37.             case 0xbd:    printdata(9,7);
  38.                         y++;
  39.                         break;        
  40.             case 0xbb:    y=0;    //清楚输入数量
  41.                         break;        
  42.             case 0xb7:    y--;    //删除一个输入数量
  43.                         break;
  44.             case 0x7e:    break;
  45.             case 0x7d:    break;
  46.             case 0x7b:    break;
  47.             case 0x77:    break;
  48.             default:    //printdata(10,7);    //默认 没有输入就下划线 _
  49.                         break;
  50.                         
  51.         }
  52.         //printdata(y, 0);    //问题主要是这里,数字管老显示的是下划线,不知道为什么
  53.         
  54.     }
  55. }

复制代码

注意,不是程序模拟结果,而是将程序下载到单片机上测试的。所以键码及扫描问题应该不是问题。
还有,你所说的防抖动处理,这个程序上也有,就是延时操作 delay(100);...。
 
 
 

回复

69

帖子

0

TA的资源

一粒金砂(初级)

8
 
友情up
 
 
 

回复

75

帖子

0

TA的资源

一粒金砂(初级)

9
 
引用 6 楼 SupermanKing 的回复:
引用 5 楼 areful 的回复:
“uchar keyscan(void)//键盘扫描函数,使用行列反转扫描法”
这个函数有严重的问题。应该用两个嵌套的FOR循环对P3口进行逐位的读/写。
还有,修改后如能工作,要对键盘按键作防抖动处理。

谢谢你的回答,但是问题不在键盘扫描上,因为程序改为这样是能够正常显示按键数字的。

C/C++ code
void main()
{
    uint y=0;
    uchar key;
    while(1)
    {
         key=keyscan()…


楼主这个线反转法我用过。你这样写没有问题。

问题在于你没有用程序实现防抖动处理
——以前我想了好多方法,才解决这个问题。

你想想,这个case 0xee:    printdata(0,7);  //这里都是没问题的,只是为了单独测试注释掉了
                        y++;    //为按下的字符串记数
按下这个对应的键盘时候,按照机械抖动来讲,其实已经抖动了无数次,也就说,我们人按一下(我们理所当然这么认为),就已经在程序触发了很多次上面的程序。
导致这个y++被迅速执行多次。
你现在要想个办法,让程序只接收到第一次按下的动作,后面的机械抖动忽略它,注意用延时是不能解决问题的,即使偶尔成功也会浪费很多时间。
你先想想,如果实在不行,我过两天回家发个程序给你看看。
 
 
 

回复

83

帖子

0

TA的资源

一粒金砂(初级)

10
 
uint y=0;
这个y用来干什么?
如果想从IO口输出就别用这个。单片机是八位的。

你现在是16/32位了。
 
 
 

回复

71

帖子

0

TA的资源

一粒金砂(初级)

11
 
谢谢,我先看看是怎么回事先,现在手头上没东西测试。
至于用uint,是因为习惯了Windows编程,本来还想用DWORD的,呵呵。
我的目的其实是为了记忆按键按下的次数,也不知道是不是我用uint类型的缘故,
如果不用uint类型,该用什么类型计数好呢?
 
 
 

回复

85

帖子

0

TA的资源

一粒金砂(初级)

12
 
unsigned char
 
 
 

回复

63

帖子

0

TA的资源

一粒金砂(初级)

13
 
我发现问题了,我改了一下程序看了一下

  1. ...
  2.                         default:        //printdata(10,7);        //默认 没有输入就下划线 _
  3.                                         break;
  4.                                                
  5.                 }
  6.                 //我加了这里
  7.                 if(y>=10){
  8.                         y=0;
  9.                 }
  10.                 printdata(y, 0);
  11. ...
复制代码

发现显示的不是 _ 线了,有了数字,虽然很随机的,但是说明了个问题,
可能就是楼上所说的抖动问题。好像可以用中断解决,不知道对不对。
 
 
 

回复

81

帖子

0

TA的资源

一粒金砂(初级)

14
 
发现显示的不是 _ 线了,有了数字,虽然很随机的,但是说明了个问题,
可能就是楼上所说的抖动问题。好像可以用中断解决,不知道对不对。

--------------------------------------------------------
肯定不是中断了
中断,那这样不知道产生多少个中断了。

随即显示就是你没有去抖动,导致误判按键按下的的结构。
 
 
 

回复

76

帖子

0

TA的资源

一粒金砂(初级)

15
 
给你个思路:就是按下之后你再次判断是否有按下,如果有按下,你就不处理它,让单片机什么都不做。即可。
其实这个判断是否有键盘按下,你的键盘扫描程序已经有用过了,——哈哈,现在我想你知道怎么做了。
做软件和做硬件驱动的一个较大区别,就是硬件更加接近发生的事情,有时候还真是不是我们想的那样的。
good luck
 
 
 

回复

83

帖子

0

TA的资源

一粒金砂(初级)

16
 
呵呵,谢谢这位兄弟的帮忙。大致有点想法了,不过如果真的按了重复按键的话就无效了,呵呵(程序还是有问题的),
看来还要再想想。
我是这么改了一下。

  1. ...
  2. void main()
  3. {
  4.         uchar key;
  5.         uchar skey=0xff;   //这里加了一个判断用的值
  6.         while(1)
  7.         {
  8.                 key=keyscan();
  9.                 if(skey!=key)  //这里判断是否需要处理相同的信息,我在想根据时间判断,过了一定时间就清除一次skey
  10.                 {
  11.                         //这里开始处理,有点Windows程序触发事件的味道
  12.                         skey=key;
  13.                         switch(key)
  14.                         {
  15.                                 case 0xee:        //printdata(0,7);
  16.                                                         y++;        //为按下的字符串记数
  17.                                                         break;
  18.                                 case 0xed:        //printdata(1,7);
  19.                                                         y++;
  20.                                                         break;
  21. ...
复制代码
 
 
 

回复

69

帖子

0

TA的资源

一粒金砂(初级)

17
 
不过想想,按键按下的值和放开的值是不一样的,应该也不需要那样处理。
应该还是很合理的触发事件的过程,除非作那种像电脑键盘一样的按钮,常按下按钮时,
定时触发一次输入事件。非常感谢各位的帮助,谢谢
 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/6 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表