找回密码
 立即注册

QQ登录

只需一步,快速开始

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

请教一个单片机按键扫描里的判断问题

[复制链接]
跳转到指定楼层
楼主
ID:88256 发表于 2019-11-6 22:21 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 hhdsdy 于 2019-11-7 10:58 编辑

以前都是用汇编的,因为不会英文一直学不会C语言,这个是自己写的第一个c程序里的一段,P2口低四位接按键,因为不确定if里面能否直接使用端口进行比较判断,因此用变量a进行过渡,待软件仿真调试正常后,重改程序才发现我这个无法用if((P2|0xf0) != 0xff)来代替a=P2|0xf0; if(a != 0xff)语句,可是记得后来看过别人的程序是可以的,是哪里错了吗?
另外,在按键消抖那里,之前是没有do{;}这一部分的,结果一直退不出循环,后来看了好多人的按键处理程序,看到有一个和我类似的有用上do,试着加上就可以了,这个do后面只是一个空语句,加不加上不是一样的吗,怎么会有差别?


误删分号,编辑补回
  1. uchar KEY_SCAN()

  2. {   

  3.           uchar a=0;

  4.           do

  5.     {

  6.                           a=P2|0xf0;

  7.               if(a != 0xff)

  8.         {

  9.                         Delay1ms(50);

  10.             do{;}while((P2|0xf0) != 0xFF);   //因为复制过来的注释误码,在删除注释时误删分号,现编辑补回
  11.                     }

  12.     }

  13.                 while(a==0);

  14.     return a;

  15. }

复制代码




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

使用道具 举报

沙发
ID:235200 发表于 2019-11-7 08:00 | 只看该作者
do{;}while((P2|0xf0) != 0xFF)后面是不是还得有一个分号?加do{;}只是等待,不加do{;},在原while后加分号是一样的
回复

使用道具 举报

板凳
ID:275826 发表于 2019-11-7 08:07 | 只看该作者
这个DO是循环语句,怎么说是空语句?
回复

使用道具 举报

地板
ID:332444 发表于 2019-11-7 10:49 | 只看该作者
执行函数时假设按键一直没按下,那么执行到  while(a==0);这里就是无限循环即死循环了因为函数开头就赋值=0.do{;}while((P2|0xf0) != 0xFF)这个循环体内不做任何事情就去判断了这是在有按键按下情况这时a不等于0,因此不会死循环,对?
回复

使用道具 举报

5#
ID:88256 发表于 2019-11-7 10:54 | 只看该作者
csmyldl 发表于 2019-11-7 08:00
do{;}while((P2|0xf0) != 0xFF)后面是不是还得有一个分号?加do{;}只是等待,不加do{;},在原while后加分号是 ...

谢谢指教!这个语句后面确实是有分号,否则编译也无法通过,只是我复制过来的时候因为注释乱码,我把注释删除时误删了分号而没有看到
我百度到的解释是
while循环如果条件不成立,可能导致语句一次都不执行.
而do..while方法即使条件不成立,语句至少也会执行一次.

按键等待释放,程序是一直在while里循环运行的,所以理论上来讲这两个语句是一样的作用,这就是我不理解的地方。
回复

使用道具 举报

6#
ID:88256 发表于 2019-11-7 11:01 | 只看该作者
tyrl800 发表于 2019-11-7 08:07
这个DO是循环语句,怎么说是空语句?

这个do是循环语句,但里面只有一个分号,没有任何语句,最多也就是浪费一点时间,不影响程序的变量变化及走向,所以我才认为是空语句
回复

使用道具 举报

7#
ID:88256 发表于 2019-11-7 13:02 | 只看该作者
xianfajushi 发表于 2019-11-7 10:49
执行函数时假设按键一直没按下,那么执行到  while(a==0);这里就是无限循环即死循环了因为函数开头就赋值=0. ...

你这没有符号的一口气看下去,让人看不明白是什么意思
do{;}while((P2|0xf0) != 0xFF); 是一对循环的,和第24行的while(a==0);不是一对;第24行的是和第7行到第23行的这一段是一对,所以只要a==0;就一直执行这一段的程序,直到有键按下(我这个程序很简单,没用中断和LCD之外的显示,所以在调用键扫描后就在这一直等待按键按下),才返回一个非零的键值。
回复

使用道具 举报

8#
ID:637424 发表于 2019-11-7 14:20 | 只看该作者
循环这里的有问题吧
回复

使用道具 举报

9#
ID:88256 发表于 2019-11-7 15:25 | 只看该作者
dhy931023 发表于 2019-11-7 14:20
循环这里的有问题吧

什么问题?
回复

使用道具 举报

10#
ID:332444 发表于 2019-11-7 21:25 | 只看该作者

  1. uchar KEY_SCAN()
  2. {   
  3.     uchar a=0;
  4.     do
  5.     {
  6.          a=P2|0xf0;
  7.          if(a != 0xff)//按键按下执行下面
  8.         {
  9.              Delay1ms(50);
  10.             do{;}while((P2|0xf0) != xFF); //等待按键释放
  11.         }
  12.     }
  13.     while(a==0);//循环判断,假如执行该函数时按键没按下则在这里死循环了
  14.     return a;
  15. }
复制代码

这样看懂了?
回复

使用道具 举报

11#
ID:332444 发表于 2019-11-7 21:26 | 只看该作者
有按键按下时a非0,因此while(a==0);这句就结束了,不会死循环。
回复

使用道具 举报

12#
ID:213173 发表于 2019-11-7 22:02 | 只看该作者
在实际应用中P2高4位可能另有它用,它们的状态不能带入按键判断。
要用a=P2&0x0f; if(a!=0x0f)判断P2低4位。给你一个简单示例。
  1. #include <reg51.h>
  2. #define uchar unsigned char
  3. #define uint unsigned int
  4. sbit LED1=P2^4;
  5. sbit LED2=P2^5;
  6. sbit LED3=P2^6;
  7. sbit LED4=P2^7;
  8. bit flag=0;
  9. void Delay1ms(uint k)
  10. {
  11.         uint i,j;
  12.         for(i=k;i>0;i--)
  13.                 for(j=125;j>0;j--);
  14. }

  15. uchar KEY_SCAN()
  16. {   
  17.         uchar a=0;
  18.         a=P2&0x0f;
  19.         if(a!=0x0f)
  20.         {
  21.                 Delay1ms(10);
  22.                 if(a!=0x0f&&flag==0)
  23.                 {
  24.                         flag=1;
  25.                         return a;
  26.                 }
  27.         }
  28.         else        flag=0;
  29. }

  30. void main()
  31. {
  32.         uchar i=0;
  33.     while (1)
  34.     {
  35.                 i=KEY_SCAN();
  36.                 switch(i)
  37.                 {
  38.                         case 0x0e: LED1=~LED1;break;
  39.                         case 0x0d: LED2=~LED2;break;
  40.                         case 0x0b: LED3=~LED3;break;
  41.                         case 0x07: LED4=~LED4;break;
  42.                         default: break;       
  43.                 }
  44.     }
  45. }
复制代码
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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