发新帖我要提问
12
返回列表
打印

倒计数器

[复制链接]
楼主: cyc200267
手机看帖
扫描二维码
随时随地手机跟帖
21
没有硬件连接说明,没有注释(这个习惯不好:)),没有其他部分程序说明,怎么找问题啊???

你确定是你贴的这部分程序的问题吗?
这部分程序感觉是按下S1键并去抖判断,然后等待按键释放后就去立即检测S2键,而且是扫描的方式,我觉得以人的动作速度,S1一释放,等你再按下S2,PC早就跳出keycan()这个子程序,根本等不到S2==0为真,当然检测不到按键了。
另外,按你的代码,if(s1num==4)这种情况是跟if(s1==0)并列的两个判断(即或的关系),而不是像if(s1num==1)等那样跟if(s1==0)是与的关系,请确认是否是你的意图?

使用特权

评论回复
22
cyc200267|  楼主 | 2011-11-14 22:12 | 只看该作者
21# yirongfu
谢谢楼上的评论,我的意思是想先按S1进入设置状态,并通过按S1来切换要调的位,如你上面所说检测不到按键,应该怎么操作呢?谢谢
我的硬件是:P0口接数码管段码。P2口接数码管位码,S1为P3^3,S2为P3^3,S3为P3^5.

使用特权

评论回复
23
yirongfu| | 2011-11-14 23:08 | 只看该作者
你的流程图中第三行方框,按S1超过1次该如何判断?每两次按S1之间的时间间隔如何控制?关键问题就在这个部分,你写的太简单了,没看出怎么处理的。

每次按键处理作为主循环中的一个事件,就是说按下S1并处理后就退出本次按键处理,然后主循环等待下一次按键处理,而不宜在keycan()中同时处理两次按键动作。因为不知道你的主程序情况,只能给你提供这些信息了,你可以按照自己的动作进行分解,按照程序一步一步读下来,注意程序是不依赖于你的意念转移的,只要时钟跑着,它就会向下一个PC去走^_^,这样才能掌握。

可以参考一下下面这本书第4章:
http://dl.21ic.com/download/-380-8-7m-pdf-ic-2458.html

使用特权

评论回复
24
yirongfu| | 2011-11-14 23:30 | 只看该作者
补充一下,keyscan()中可以同时判断三个按键,并分别处理对应的事件

keyscan()
{
if( s1== 0 )
{
  判断当前S1被按下次数,若小于6次,则次数变量加1,相应位闪烁,置设置状态标志;
  若为5次,则不理会或者退出设置状态,若退出设置状态则清设置状态标志,即表示进入工作状态;
  //这里有个问题,如果不理会,则必须待S2或者S3按下后再按S1才能认为是退出设置状态,
  //这样就无法让操作者循环设置每个位,即位选到最低位后再回到最高位.你自己看情况决定怎么操作。
}
if( s2 == 0 )
{
  若处于设置状态,则相应位加1;
  若处于运行状态,则不理会,退出本函数;
}
if( s3 == 0 )
{
  若处于设置状态,则相应位减1;
  若处于运行状态,则不理会,退出本函数;
}
}

当然,这只是事件处理的大概思路,还得考虑多个键同时按下的处理、键释放的处理等等。

使用特权

评论回复
25
杨立业yly| | 2011-11-15 18:11 | 只看该作者
1# cyc200267
我写出来了,如果需要的话联系我QQ:1024549573

使用特权

评论回复
26
cyc200267|  楼主 | 2011-11-19 00:16 | 只看该作者
非常感谢24楼的评论和25楼写的程序,我有些小改动,现在可以工作了,但还有个问题,如何能实现在设置数据是相对的数码管闪烁,我用中断程序试过不能实现,希望大家能提出建议!
#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
//sbit dula=P2^6; //数码管段选
//sbit wela=P2^7;  //数码管位选
sbit en=P3^3; //确定要调节的位置(个、十、百、千)
sbit jia=P3^2;//加一
sbit m=P3^5; //确定。时间调好后,按这个键开始计数
sbit led=P1^0; //进入设置状态Led亮
sbit led1=P1^1;//调节个位时led1亮
sbit led2=P1^2;//调节十位时led2亮
sbit led3=P1^3;//调节百位时led3亮
sbit led4=P1^4;//调节千位时led4亮
sbit signal=P3^4; //减信号输入端
sbit signal_out=P1^7;
  unsigned int i,j,n;
  unsigned long num,num1,l;
uchar code table[]={0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,0x7f,0x6f};
void delay(uchar x);
void init();
void keyscan();
void display(uint num);
void delay(uchar x);
void main()
{   init();           
     while(1)                    
     {    keyscan();
              signal_out=0;
              if(i==20)
                  {
                    i=0;
                    signal_out=1;
           if(signal==0)
                   {
                    delay(3);
                        if(signal==0)
                        {
                         while(!signal);                  
                         num--;
                         if(num==0)       
                         TR0=0;
                         signal_out= 1;
                         }
                        }
                }
          display(num);
        }
}
void init()  //定时器初始化
{   TMOD=0X01;
    TH0=(65536-45872)/256;
    TL0=(65536-45872)%256;
    EA=1;
    ET0=1;
    TR0=1;
}
void time0()interrupt 1//中断函数
{   TH0=(65536-45872)/256;
    TL0=(65536-45872)%256;
    i++;

}
void keyscan() //按键扫描
{   if(en==0)
         {delay(5);
                if(en==0)
                 {  while(!en);
                TR0=0;
                    j++;
             if(j==4)
               j=0;
               switch(j)
                                { case 0:{led=0;led1=1;led2=1;led3=1;};break;
                  case 1:{led=1;led1=0;led2=1;led3=1;};break;
                                  case 2:{ led=1;led1=1;led2=0;led=1;};break;
                                  case 3:{led=1;led1=1;led2=1;led3=0;};break;
                                }
          }
     }
         if(jia==0)
         {delay(5);
                if(jia==0)
                 {  while(!jia);
                  n++;
                      if(n==2)
                           { n=1;
                             l++;
                                }
                     switch(j)
                        { case 1:{  num1=n*10;
                                   if(l>10)
                         { l=0;
                                                   num1=num1-100;
                                                 }
                     };break;
                          case 2:{num1=n*100;
                       if(l>10)
                         { l=0;
                                                   num1=num1-1000;
                                                 }
                                     };break;
              case 3:{num1=n*1000;
                       if(l>10)
                         { l=0;
                                                   num1=num1-10000;
                                                 }
                        
                                };break;
                       
                }
            num=num+num1;
                 display(num);
     }
   }
    if(m==0)
      { delay(5);
                if(m==0)
           TR0=1;
       while(!m);
           led=1;
           led1=1;
           led2=1;
           led3=1;
        }
}
void display(uint num)//显示
{   
    uchar qian, bai,shi,ge;
     //num=num1+num;
         if(num==10000)
           num=0;
         qian=num/1000;          
     bai=num%1000/100;
     shi=num%100/10;
     ge=num%10;

         P2=0xf7;
         P0=table[qian];
         delay(2);
         P2=0xff;

         P2=0xfb;
         P0=table[bai];
         delay(2);
         P2=0xff;
         
         P2=0xfd;
         P0=table[shi];
         delay(2);
         P2=0xff;
         
         P2=0xfe;
         P0=table[ge];
         delay(2);
         P2=0xff;
                     
}

void delay(uchar x)//延时
{    uchar i,j;
     for(i=x;i>0;i--)
     for(j=110;j>0;j--);

}

使用特权

评论回复
27
cyc200267|  楼主 | 2011-11-28 17:19 | 只看该作者
请高手指点一下,实现在设置数据时相对的数码管闪烁的方法,谢谢!

使用特权

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

本版积分规则