打印

请问P3=P3|0x3c这个命令如何理解?

[复制链接]
6585|28
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
还我今生|  楼主 | 2008-2-21 15:45 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
硬件电路描述如下:89S52 单片机的P1 口接有8 个LED,当某一端口输出为“0”时,相应的LED 点亮,P3.2、P3.3、P3.4、P3.5 分别接有四个按钮K1~K4,按下按钮时,相应引脚被接地。现要求编写可键控的流水灯程序,当K1 按下时,开始流动,K2 按下时停止流动,全部灯灭,K3 使灯由上往下流动,K4 使灯由下往上流动。
下面首先给出程序,然后再进行分析。
例2-1:键控流水灯的程序
#include "reg51.h"
#include "intrins.h"
#define uchar unsigned char
void mDelay(unsigned int DelayTime)
{ unsigned int j=0;
for(;DelayTime>0;DelayTime--)
{ for(j=0;j<125;j++)
{;} }}
uchar Key()
{ uchar KeyV;
uchar tmp;
P3=P3|0x3c; //四个按键所接位置
KeyV=P3;
if((KeyV|0xc3)==0xff) //无键按下
return(0);
mDelay(10); //延时,去键抖
KeyV=P3;
if((KeyV|0xc3)==0xff)
return(0);
else
{ for(;;){ tmp=P3;
if((tmp|0xc3)==0xff)
break;}
return(KeyV);}}
void main()
{ unsigned char OutData=0xfe;
bit UpDown=0;
bit Start=0;
uchar KValue;
for(;;)
{ KValue=Key();
switch (KValue)
{ case 0xfb: //P3.2=0,Start
{ Start=1;
break; }
case 0xf7: //P3.3=0,Stop
{ Start=0;
break; }
case 0xef: //P3.4=0 Up
{ UpDown=1;
break; }
case 0xdf: //P3.5=0 Down
{ UpDown=0;
break; }
}
if(Start)
{ if(UpDown)
OutData=_crol_(OutData,1);
else
OutData=_cror_(OutData,1); P1=OutData;
}
else
P1=0xff; //否则灯全灭
mDelay(1000);
}
}

相关帖子

沙发
还我今生|  楼主 | 2008-2-21 15:50 | 只看该作者

我先把自己的理解说一下

P3=P3|0x3c; //四个按键所接位置
经过这个命令P3应该为11111111 对吗?
下一句是
KeyV=P3;  说明KeyV=11111111  对吗?
下一句是
if((KeyV|0xc3)==0xff) //无键按下
那么KeyV|0xc3)==0xff不是肯定成立了吗?
不知道我哪里理解错了,请大家看看。

使用特权

评论回复
板凳
后学| | 2008-2-21 17:15 | 只看该作者

“|”,逻辑“或”操作

使用特权

评论回复
地板
computer00| | 2008-2-21 17:27 | 只看该作者

|是按位或~~~~

程序漏掉了取反吧,改成

if((KeyV|~0xc3)==0xff)

就好理解了。

使用特权

评论回复
5
grady1125| | 2008-2-21 18:48 | 只看该作者

请问P3=P3|0x3c这个命令如何理解?

 computer00 是不是看错了,0xc3已经是~0x3c 
LZ的键盘检测看起来有点晕;还不如逐个扫描P3口如:
if(P3_2==0||P3_3==0||P3_4==0||P3_5==0)…………

使用特权

评论回复
6
还我今生|  楼主 | 2008-2-21 18:53 | 只看该作者

我知道 |是按位或

P3=P3|0x3c; //四个按键所接位置
经过这个命令P3应该为11111111 对吗?
下一句是
KeyV=P3;  说明KeyV=11111111  对吗?
下一句是
if((KeyV|0xc3)==0xff) //无键按下
那么KeyV|0xc3)==0xff不是肯定成立了吗?
不知道我哪里理解错了,请大家看看。

上面哪里错了就不知道了
00说
程序漏掉了取反吧,改成
if((KeyV|~0xc3)==0xff)
我觉得好象不会吧  上面是ox3c 
下面没必要用取反符号吧?
请00再看看

使用特权

评论回复
7
还我今生|  楼主 | 2008-2-21 19:05 | 只看该作者

5楼是思路好象不错

if(P3_2==0||P3_3==0||P3_4==0||P3_5==0)…………
不过这个语句我怎么知道是哪个键盘按下了啊

使用特权

评论回复
8
computer00| | 2008-2-21 19:24 | 只看该作者

哈哈,的确是我看错了,眼晕了...下面的0xC3刚好是~0x3C

这样就好理解了。

P3=P3|0x3c;  //将P3.2,P3.3,P3.4,P3.5设置为1,不影响其它位

if((KeyV|0xc3)==0xff) //只要P3.2,P3.3,P3.4,P3.5中有一位为0,那么结果就不为0xFF了,即有键按下

等同于if((KeyV|~0x3c)==0xff),我更喜欢这样写,呵呵。因为0x3C刚刚既然已经有了,直接加个取反符比较快。

if((KeyV|0xc3)==0xff)也可以改成if((KeyV&0xc3)!=0xc3),逻辑意思一样的。

使用特权

评论回复
9
兰天白云| | 2008-2-21 19:25 | 只看该作者

接7楼

if(P3_2==0||P3_3==0||P3_4==0||P3_5==0)…………
不过这个语句我怎么知道是哪个键盘按下了啊

if(P3_2==0)
 {.....}
else if(P3_3==0)
 {....}
.
.
.

使用特权

评论回复
10
还我今生|  楼主 | 2008-2-21 20:44 | 只看该作者

一直不理解这个

P3=P3|0x3c;  //将P3.2,P3.3,P3.4,P3.5设置为1,不影响其它位
这句后KeyV=P3;  //KeyV被赋值成P3,那么KeyV 的中间四位是1 
那么下一句
if((KeyV|0xc3)==0xff)  //**1111** 或上11000011  不是肯定等于0xff吗?
那么不是程序出问题拉 return永远是0 



P3=P3|0x3c;  //将P3.2,P3.3,P3.4,P3.5设置为1,不影响其它位
这句是不是不应该存在?

还是我理解错误?

使用特权

评论回复
11
computer00| | 2008-2-21 21:09 | 只看该作者

P3是一个IO口,51的IO是准双向结构。读回的值是IO口的电平值

由外部电路状态决定(例如这里的开关按下后就为低电平,读入就是0了),跟写入值不一定相同。

使用特权

评论回复
12
ayb_ice| | 2008-2-22 09:00 | 只看该作者

“或”,还有什么问题。。。

使用特权

评论回复
13
还我今生|  楼主 | 2008-2-22 10:08 | 只看该作者

按 00的意思

P3是一个IO口,51的IO是准双向结构。读回的值是IO口的电平值 
由外部电路状态决定(例如这里的开关按下后就为低电平,读入就是0了),跟写入值不一定相同。 
 
那么这句P3=P3|0x3c;  //将P3.2,P3.3,P3.4,P3.5设置为1,不影响其它位
如果有个键盘被按下了 即使经过这个等式P3=P3|0x3c
 P3口的内容还是不被改变的,对不对?
如果这样 那么这句不是没必要存在了吗?

使用特权

评论回复
14
ayb_ice| | 2008-2-22 15:31 | 只看该作者

这条指令读的不是端口的值

而是缓冲器的值。。。
这是典型的读-改-写指令,具体请看51手册。。。

使用特权

评论回复
15
还我今生|  楼主 | 2008-2-22 15:38 | 只看该作者

是啊 我老是分不清 哪个是读 哪个是写

能不能举例说明 ?

使用特权

评论回复
16
ayb_ice| | 2008-2-22 16:03 | 只看该作者

具体请看51手册。。。

使用特权

评论回复
17
还我今生|  楼主 | 2008-2-22 16:32 | 只看该作者

问题我看不明白啊

看了还是分不清楚。。。。

P3=P3|0x3c; //四个按键所接位置    这个是写?
KeyV=P3;    //                    这个是读?

使用特权

评论回复
18
dld2| | 2008-2-22 16:37 | 只看该作者

前一句先读后写

使用特权

评论回复
19
还我今生|  楼主 | 2008-2-22 19:39 | 只看该作者

快被弄迷糊了 谁解释清楚点啊

使用特权

评论回复
20
stycx| | 2008-2-22 20:20 | 只看该作者

17楼理解正确

P3=P3|0x3c; //四个按键所接位置    这个是写!
KeyV=P3;    //                    这个是读!


使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

218

主题

1382

帖子

1

粉丝