找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3106|回复: 13
打印 上一主题 下一主题
收起左侧

为什么接受按键的数组元素个数要比按键个数多一个才正常?

[复制链接]
跳转到指定楼层
楼主
ID:262 发表于 2016-3-11 22:44 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
开始是一样多的,显示会有问题,但是通过按键10直接跳出来就正常,后来数组元素多+了一个才正常了,但是想不通为什么要多加一个才正常,又不是字符串。按键返回值得那个函数就没贴了,包含在anjian.c里面。还有外部函数调用我怎么没反应,delay()、key()使用前声明了extern啊,编译也通过,下载到单片机里没反应。
  1. #include<reg52.h>
  2. #include "anjian.c"//按键检测函数key()
  3. #define uint unsigned int
  4. #define uchar unsigned char
  5. #define NUM 4//等待按键个数为NUM
  6. #define time 10000//按键抖动延时,大概90ms
  7. uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,
  8. 0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
  9. uchar str[NUM+1]={0};//按键字符数组,必须加1,否则会乱码!
  10. void strkey()//按键值赋给str[]数组
  11. {
  12.         uchar i;
  13.         for(i=0;i<NUM;i++)
  14.         {
  15.                 str[i]=key();
  16.                 if(str[i]==10)//按键10表示确认
  17.                 {
  18.                         break;
  19.                 }
  20.                 if(str[i]==11)//按键11表示取消,数组清零
  21.                 {
  22.                         for(i=0;i<NUM;i++)
  23.                                 str[i]=0;
  24.                         i=0;
  25.                         str[i]=key();
  26.                 }
  27.         }

  28. }
  29. void main()
  30. {
  31.         uchar a,x;
  32.         strkey();
  33.         while(1)
  34.         {
  35.                 for(x=0;x<4;x++)//显示str[]数组元素到4个数码管
  36.                 {
  37.                         a=str[x];
  38.                         P3=table[a];
  39.                         P2=(~(0x01<<x));
  40.                         delay(200);
  41.                         P2=0xff;
  42.                 }
  43.                 a=0;
  44.         }

  45. }
复制代码



分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:262 发表于 2016-3-11 22:44 | 只看该作者
硬件不对也可出现乱码啊

硬件没问题啊,上面有说,有按键10跳出break就正常,多加个数组元素的个数就可以正常了。
回复

使用道具 举报

板凳
ID:262 发表于 2016-3-11 22:44 | 只看该作者
问下,c语言的一个问题:返回指针的函数,这个指针指向的是这个函数的内部一个变量,这个函数完了,这个变量不是销毁了吗?那还返回那个指针有什么用?是不是那个变量要是全局或者静态局部啊?
回复

使用道具 举报

地板
ID:262 发表于 2016-3-11 22:44 | 只看该作者
建议把其他函数贴一下,必须写NUM+1,是因为你数字按键一共按了四次,但是确认或删除你 for(i=0;i<NUM;i++)循环计数时算入在内了,也就是说你总共是按了5次,所以导致的。
回复

使用道具 举报

5#
ID:262 发表于 2016-3-11 22:45 | 只看该作者
确认、删除这两个键还没处理好(暂时不管),确认按了还是会算按键10,我贴下按键检测
回复

使用道具 举报

6#
ID:262 发表于 2016-3-11 22:45 | 只看该作者

  1. anjian.c文件里就只有延时delay()+key()函数
  2. #include<reg52.h>
  3. #define uint unsigned int
  4. #define uchar unsigned char
  5. #define time 10000//按键抖动延时,大概90ms
  6. void delay(uint  z)
  7. {
  8.         while(z--);
  9. }
  10. uchar key()//按键检测程序,返回的是0-F的字符
  11. {
  12.         uchar x,temp,k,flag,temp2;
  13.         flag=1;
  14.         while(flag)
  15.         {
  16.         for(x=0;x<4;x++)
  17.         {
  18.                 temp2=~(0x01<<x);//利用1左移后反转,即0左移
  19.                 P1=temp2;
  20.                 temp=P1;
  21.                 while(temp!=temp2)
  22.                 {
  23.                         delay(time);
  24.                         P1=temp2;
  25.                         temp=P1;
  26.                         while(temp!=temp2)
  27.                         {
  28.                                 switch(temp)
  29.                                 {
  30.                                         case 0xee:k=12;break;
  31.                                         case 0xde:k=13;break;
  32.                                         case 0xbe:k=14;break;
  33.                                         case 0x7e:k=15;break;

  34.                                         case 0xeD:k=8;break;
  35.                                         case 0xDD:k=9;break;
  36.                                         case 0xBD:k=10;break;
  37.                                         case 0x7D:k=11;break;

  38.                                         case 0xeB:k=4;break;
  39.                                         case 0xDB:k=5;break;
  40.                                         case 0xBB:k=6;break;
  41.                                         case 0x7B:k=7;break;

  42.                                         case 0xe7:k=0;break;
  43.                                         case 0xD7:k=1;break;
  44.                                         case 0xB7:k=2;break;
  45.                                         case 0x77:k=3;break;
  46.                                 }
  47.                                 flag=0;
  48.                                 do
  49.                                 {
  50.                                         P1=temp2;
  51.                                         temp=P1;
  52.                                         delay(time);
  53.                                 }
  54.                                 while(temp!=temp2);
  55.                         }

  56.                         
  57.                 }


  58.         }
  59.         }
  60.         return k;
  61. }
复制代码



按键检测key()没问题,我单独在一个main中试过了,才做成.c文件方便包含的
回复

使用道具 举报

7#
ID:262 发表于 2016-3-11 22:45 | 只看该作者

打个比方:你十个按键键值分别是0-9,那么0-9就刚好是10个键值了;要看你是从那个数起的,1-10是10个,0-9也是10个!能明白不?
回复

使用道具 举报

8#
ID:262 发表于 2016-3-11 22:46 | 只看该作者
小蜜蜂o
anjian.c文件里就只有延时delay()+key()函数
#include
#define uint unsigned int

//////还有外部函数调用我怎么没反应,delay()、key()使用前声明了extern啊,编译也通过,下载到单片机里没反应。//////////没太看懂什么意思。你是说包含在anjian。c的文件不能被主函数调用吗?还是说可以调用,但不做反应。看了一下你上边的函数没什么问题,延时函数好像不是90ms,如果真是的话建议改小点,一般按键抖动在10-15ms之间,延时的话写20ms就可以,人正常按按键的时间在100ms-300ms,如果按得较快,延时90ms是会发生问题的。
回复

使用道具 举报

9#
ID:262 发表于 2016-3-11 22:47 | 只看该作者
我之前没包含anjian.c文件,直接在使用前声明为extern函数,最后编译出来的程序好小,我那个包含文件跟.c同一个文件夹,但是,.c跟工程不是同一个文件夹,是不是这个问题?。然后试了另一种,就是包含那个文件,但是不声明为外部函数,这样就正常
回复

使用道具 举报

10#
ID:262 发表于 2016-3-11 22:47 | 只看该作者
heicad 发表于 2016-3-11 22:45
打个比方:你十个按键键值分别是0-9,那么0-9就刚好是10个键值了;要看你是从那个数起的,1-10是10个,0- ...

我是从str[0]开始赋值的啊,显示也是从它开始
回复

使用道具 举报

11#
ID:262 发表于 2016-3-11 22:48 | 只看该作者
本帖最后由 heicad 于 2016-3-11 22:50 编辑

引用:
-------------------------------------------
小蜜蜂o 发表
我之前没包含anjian.c文件,直接在使用前声明为extern函数,最后编译出来的程序好小,我那个包含文件跟.c ...-------------------------------------------

我是这样理解的,问题的关键不在于你用extern去声明函数,而实际你没有进行函数声明(extern不是声明函数用的),在C语言中书中我只看到了extern可以用于声明变量,没有看到extern可以声明函数。于是我上网查了一下,是这样说的你细细理解一下这两句话,很绕口,:C语言外部函数 //
1、在定义函数时,若在函数首部的最左端加关键字extern,则表示此函数是外部调用,可被其他文件调用,函数首部可以为

Extern int fun(int a,int b);
C语言规定,声明函数和外部变量时(即外部声明)缺省是extern,可被其他文件见调用或使用。

2、在需要调用函数的文件中,用extern(缺省默认)对函数声明,表示该函数是在其他文件中定义的外部函数

注意:C语言没有局部函数!
照他的意思C语言中的函数全是全局函数,而你用extern声明,写不写没有关系因为extern是程序默认写上的,也就是说,问题关键不再extern,而在于没有声明函数。声明的话,你把key()函数声明写到anjian.h中在让主函数包含以下anjian.h就可以了。
回复

使用道具 举报

12#
ID:262 发表于 2016-3-11 22:50 | 只看该作者
还是搞不明白这些 ABC 字母组合的意思,别人编写的就没出现 LZ 这样的问题 。同样是16个按键输入显示字符与数字,还是你的编写思路有误呢?
回复

使用道具 举报

13#
ID:262 发表于 2016-3-11 22:50 | 只看该作者
heicad 发表于 2016-3-11 22:50
还是搞不明白这些 ABC 字母组合的意思,别人编写的就没出现 LZ 这样的问题 。同样是16个按键输入显示字符与 ...

框架很简单啊,key()没问题,不用看。就是那个strkey()函数里的数组赋值那里,下面那两个if也可以不用看,那是额外的,/**/掉,main()里面就是把str【】数组前4个元素显示到数码管。
回复

使用道具 举报

14#
ID:262 发表于 2016-3-11 22:50 | 只看该作者
就只知道{0xc0~0x8e}用于共阳数码管显示的,其它的英文还真没明白是啥意思。
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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