打印

问个C51的小程序,哪个高手来解决一下?

[复制链接]
2177|11
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
辉扬的心|  楼主 | 2009-5-6 08:56 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
单片机P0口高4位接上拉电阻接4个LED灯,低4位开关接GND。P00合上,P04的LED亮,P01合上,P05的LED亮,依次,P03合上,P07的LED亮。开关合上就接地了,高4位输出0,灯就亮了。
我的程序编好了,效果也出来了,如下:
思路1
#include <reg52.h>
#define uint unsigned int
#define uchar unsigned char
void main()    
{
uchar a,b,c,m,n,i;

b=0xff; 
P0=0xff;
while(1)
    {  a=0x01; 
    for(c=0;c<5;c++)

{  m=P0|(~a);
    if(m==(~a))    //检测P1_0按键是否按下
       {
         i=a;
        b=(b&(~i))&(~(i<<4));
        P0=b;
       }
       else
       {
       b=((b|i)|(i<<4));
       P0=b;
       }
       a=a<<1;
       
//       for(m=0;m<255;m++)
       for(n=0;n<200;n++);
      
             
          }}
   }
用的是循环,教材上是用的低4位逐一判断,然后输出,很易懂。

我又尝试这样的思路:首先将P0口的状态读入赋给a,然后a=((a<<4)|(a&0x0f)),再把a赋给P0口,这样不是简单很多,程序如下:
#include <reg52.h>
#define uint unsigned int
#define uchar unsigned char
void main()    
{
uchar a,n;
while(1)
{
   a=P0;
   a=((a<<4)|(a&0x0f));
   P0=a;
   for(n=0;n<200;n++);
}
}
结果肯定错了,不然我也不会上来请教了,想了半宿,硬是没有想通,哪里错了。

最后再问一个Keil51软件的问题,如图:程序仿真时,port0框内,P0栏8个状态位和下面的Pins状态位有什么关系?为什么有时上下状态一致有时不一致?为什么聂?



搬个板凳坐到等,^_^


 

相关帖子

沙发
JayGong| | 2009-5-6 09:16 | 只看该作者

低4位开关

如果是AT89C51,P0口接开关,要有上拉电阻...

使用特权

评论回复
板凳
jxb163| | 2009-5-6 09:17 | 只看该作者

a=((a<<4)|(a&0x0f)),

b=((a<<4)|(a&0x0f));
P0=b;

使用特权

评论回复
地板
smileagain| | 2009-5-6 12:19 | 只看该作者

那个关于keil I/O口窗口的问题

下面一行代表引脚状态,也就是外界输入状态
上面一行代表该I/O口的锁存器状态
不知道这样解释是否明白

使用特权

评论回复
5
computer00| | 2009-5-6 13:39 | 只看该作者

引用俺书里的一段:

“这样就可以看到P2口的每个引脚电平了,打勾的表示高电平1,没打勾的表示低电平0。显示有两行,上面一行表示程序设置的状态,而下面一行表示管脚实际的电平状态,如图2.11.10所示。
    我们可以修改下面一行的值,来模拟外部电平输入。注意,51单片机在输出低电平时,是强驱动的,这时我们不能强行将一个高电平加在端口上。在仿真中也是如此,如果上面一行没打勾,而将下面一行打勾时,就会弹出一个出错的对话框。输出为高电平时,是弱驱动,可以直接将低电平加在端口上。因此当我们需要将IO口作为输入口使用时,应该给将对应的端口设置为1。这个特性就是所谓的准双向IO口,51单片机的特色之一。

使用特权

评论回复
6
刘前辈| | 2009-5-6 14:11 | 只看该作者

)|(a|0x0f)); //“想了半宿,....”嘻嘻。

void main()    
{
uchar a,n;
while(1)
{
   a=P0;
   P0=((a<<4)|(a|0x0f));    //????????????????????
   //P0=a;
   for(n=0;n<200;n++);
}
}

使用特权

评论回复
7
gaohq| | 2009-5-6 14:21 | 只看该作者

不懂

   a=P0;
   a=((a<<4)|(a&0x0f));
   P0=a;


   a=P0;
   P0=((a<<4)|(a&0x0f));

这有什么区别呢?

使用特权

评论回复
8
刘前辈| | 2009-5-6 14:27 | 只看该作者

看清楚。

   a=P0;
   a=((a<<4)|(a&0x0f));
   P0=a;


   a=P0;
   a=((a<<4)|(a|0x0f));  //  与“&”、或“|” 关系弄清楚。
   P0=a;

有什么区别?

使用特权

评论回复
9
gaohq| | 2009-5-6 15:47 | 只看该作者

哦,谢谢提醒

是我粗心了,
不过我觉得如下就可:
a=P0;
P0=(a<<4)|0x0f;

使用特权

评论回复
10
刘前辈| | 2009-5-6 20:33 | 只看该作者

正解

不过我觉得如下就可:
 
P0=(P0<<4)|0x0f;


使用特权

评论回复
11
辉扬的心|  楼主 | 2009-5-6 23:51 | 只看该作者

^_^

恩,大的问题解决了,还有个小问题,先自己解决,解决不了再来求教,谢了,楼上各位.

PS:圈圈,程序匠人到底是男的还是女的?要真实回答哟

使用特权

评论回复
12
电脑圆圆| | 2009-5-7 00:23 | 只看该作者

从提高效率和实时性考虑还得这样写比较好

while(1)

   while(P0&0x0f ==0x0F);
   P0STATE = P0&0x0F;
   P0 = P0STATE<<4;

使用特权

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

本版积分规则

24

主题

312

帖子

0

粉丝