• 已解决 73482 个问题
  • 已帮助 5993 位优秀工程师

如何让其他延时程序进行时不影响数码管动态扫描

Suwian 2016-10-26 浏览量:1854
例如:使用定时器进行一分钟的定时,然后在数码管上显示时,分,秒,然后每到1分钟蜂鸣器会报警3声.
当我进行蜂鸣器的延时时,数码管的动态扫描会暂停我所延时的时间.(单片机现象数码管在蜂鸣器响的时候不显示)
所以问一下大家有什么好的解决方法,谢谢.稍后上传我的源代码.
再次感谢!
1 0 收起

我来回答

上传资料:
选择文件 文件大小不超过15M(格式支持:doc、ppt、xls、pdf、zip、rar、txt)
最佳答案
  • 本帖最后由 MOP 于 2016-10-27 20:12 编辑

    Suwian 发表于 2016-10-27 20:03
    逻辑是对的,但是现象和预想的不符合,我等下回去把电路图和仿真文件发给您,您看看,是不是我哪里还有漏 ...
    嗨,我剛看了ALARM_TIME不用改喔,是5喔,前面沒講清楚抱歉:)
    也就是說除了PNP/NPN的邏輯差別,其他不用改
    之前的alarm()函数的第一个入口的判断为if(MIN>0&&val==0)这个是否也是需要相应的修改,因为第二次进来这个val!=0了。还有那个ALARM_TIME也是要改成6的吧,然后最后的那个判断函数if(beeper)的否则里那个BEEPER应该等于1吧,不然之后会一直响的。这是我的疑问如果说错了帮我解惑一下,谢谢
    再貼一次,就是判斷,ALARM_TIME都不用改,BEEPER會錯意是因為我以為你實體可能沒電晶體或者NPN,而PNP的話如我剛剛提到的初始化跟BEEPER=1即可,這樣應該都沒問題了:)

    • 发布于 2016-10-26
    • 举报
    • 评论 0
    • 0
    • 0

其他答案 数量:38
  • MOP 发表于 2016-10-26 22:11
    噗,我文章有提醒您要自己定義Beeper的PIN腳位設置成GPIO輸出,因為我看你的Code似乎沒看到Beeper的定義腳位 ...

    这是我弄的仿真引脚图,那个Beeper的宏定义要怎么设置:o,
    初学者,刚刚接触这个东西,您的那篇文章对我来说还是有点吃力的,我现在还没学到实时时钟和lcd模块。
    • 发布于2016-10-26
    • 举报
    • 评论 0
    • 0
    • 0

  • 本帖最后由 MOP 于 2016-10-27 00:46 编辑

    Suwian 发表于 2016-10-26 23:38
    这是我弄的仿真引脚图,那个Beeper的宏定义要怎么设置,
    初学者,刚刚接触这个东西,您的那篇文章对我 ...
    嗨,電路中那個半圓形應該就是Beeper了,下面電晶體PNP放大電流用,那接角就是P2.3,即P23

    sbit  P23 = P2^3;
    
    #define BEEPER(X) ((X)? P23=1:P23=0)

    • 发布于2016-10-27
    • 举报
    • 评论 0
    • 0
    • 0

  • MOP 发表于 2016-10-27 00:44
    嗨,電路中那個半圓形應該就是Beeper了,下面電晶體PNP放大電流用,那接角就是P2.3,即P23



    我的编译器改了那个BEEPER以后,下面那个时钟程序就报错,然后我就把BEEPER(1)和BEEPER(0)改成了直接用P23,之后可以运行,但是那个VAL<3的那个判断语句好像是蜂鸣器响的时长而非次数,现在时间有点晚,我明天在修改,感谢您的耐心指导!
    • 发布于2016-10-27
    • 举报
    • 评论 0
    • 0
    • 0

  • 本帖最后由 MOP 于 2016-10-27 03:18 编辑

    Suwian 发表于 2016-10-27 01:57
    我的编译器改了那个BEEPER以后,下面那个时钟程序就报错,然后我就把BEEPER(1)和BEEPER(0)改成了直接 ...
    嗨,這版本是時長沒錯,不過要改成間隔1秒,共三次也是So easy的,您說Macro問題,C/C++不同外,C99規則也不同,改為以下就可過
    #define BEEPER(X) ((X)? (P23=1):(P23=0))
    改為三次版本的話,這樣比較方便,如下定義
    #define BEEPER P23
    然後,改判斷式如下
        if(beeper)
      {
        if(val以上第1秒會叫,第2秒關,第3秒叫,第4秒關,第5秒叫,第6秒之後都是關,共叫3次:)


    • 发布于2016-10-27
    • 举报
    • 评论 0
    • 0
    • 0

  • Suwian 发表于 2016-10-26 11:04
    谢谢你啊不过,蜂鸣器的响3声的程序不是这样写的吗
    void T1_Time() interrupt 3
    {

    大哥,你在定时器中断里面用 delay(100);这个死延时函数,我也是醉了……
    • 发布于2016-10-27
    • 举报
    • 评论 0
    • 0
    • 0

  • MOP 发表于 2016-10-27 02:43
    嗨,這版本是時長沒錯,不過要改成間隔1秒,共三次也是So easy的,您說Macro問題,C/C++不同外,C99規則也不同, ...

    之前的alarm()函数的第一个入口的判断为if(MIN>0&&val==0)这个是否也是需要相应的修改,因为第二次进来这个val!=0了。还有那个ALARM_TIME也是要改成6的吧,然后最后的那个判断函数if(beeper)的否则里那个BEEPER应该等于1吧,不然之后会一直响的。这是我的疑问如果说错了帮我解惑一下,谢谢
    • 发布于2016-10-27
    • 举报
    • 评论 0
    • 0
    • 0

  • SingleYork 发表于 2016-10-27 08:21
    大哥,你在定时器中断里面用 delay(100);这个死延时函数,我也是醉了……

    哈哈,因为之前只学过这个,蜂鸣器接触的不多
    • 发布于2016-10-27
    • 举报
    • 评论 0
    • 0
    • 0

  • Suwian 发表于 2016-10-27 09:42
    之前的alarm()函数的第一个入口的判断为if(MIN>0&&val==0)这个是否也是需要相应的修改,因为第二次 ...

    不需要的喔,因為那只是讓你開機時候不會鳴叫的標誌(flag),因為之後永遠是true了,當00:01:00,00:02:00...都會正常觸發
    • 发布于2016-10-27
    • 举报
    • 评论 0
    • 0
    • 0

  • 本帖最后由 Suwian 于 2016-10-27 12:41 编辑

    MOP 发表于 2016-10-27 09:51
    不需要的喔,因為那只是讓你開機時候不會鳴叫的標誌(flag),因為之後永遠是true了,當00:01:00,00:02:00... ...
    哦哦,那我刚才说到的除了那个啊不用改其他的呢?我不知道是那个仿真的叫的有问题还是程序问题,我下午去拿物理机试一下。 #include
    #define uchar unsigned char
    #define uint unsigned int
    //#define BEEPER(X) ((X)? (P23=1):(P23=0)) //要控制的GPIO Output Pin,假設0輸出低電位,1輸出高電位
    #define BEEPER P23
    #define ALARM_TIME 6
    sbit dula=P2^6;
    sbit wela=P2^7;
    sbit P23 = P2^3;
    uchar beeper = 0; //global
    uchar started=0; //global
    volatile uchar shi,ge,f_shi,f_ge,s_shi,s_ge,num,num1,num2,val,val1;
    uchar CLK,MIN;
    uchar code table[]={

    0x3F, //"0"
    0x06, //"1"
    0x5B, //"2"
    0x4F, //"3"
    0x66, //"4"
    0x6D, //"5"
    0x7D, //"6"
    0x07, //"7"
    0x7F, //"8"
    0x6F //"9"


    };


    void delay(uint xms)
    {
    uint i,j;
    for(i=xms;i>0;i--)
    for(j=110;j>0;j--);

    }

    void display1(uchar shi,uchar ge)
    {

    P0=0xfe;
    wela=1;
    wela=0;
    P0=table[shi];
    dula=1;
    dula=0;
    delay(3);


    P0=0xfd;
    wela=1;
    wela=0;
    P0=table[ge];
    dula=1;
    dula=0;
    delay(3);



    }
    void display2(uchar shi,uchar ge)
    {

    P0=0xf7;
    wela=1;
    wela=0;
    P0=table[shi];
    dula=1;
    dula=0;
    delay(3);


    P0=0xef;
    wela=1;
    wela=0;
    P0=table[ge];
    dula=1;
    dula=0;
    delay(3);



    }
    void display3(uchar shi,uchar ge)
    {

    P0=0xbf;
    wela=1;
    wela=0;
    P0=table[shi];
    dula=1;
    dula=0;
    delay(3);


    P0=0x7f;
    wela=1;
    wela=0;
    P0=table[ge];
    dula=1;
    dula=0;
    delay(3);



    }
    void SFM()
    {
    if(num==20)
    {
    num=0;
    val++;
    if(val==60)
    {
    val=0;
    MIN++;
    if(MIN==60)
    {
    MIN=0;

    CLK++;
    if(CLK==1)
    CLK=0;
    }
    }
    shi = val/10;
    ge = val%10;
    f_shi = MIN/10;
    f_ge = MIN%10;
    s_shi = CLK/10;
    s_ge = CLK%10;
    }

    }

    void alarm(void)
    {


    if(MIN>0 && val==0) // When booting up, the beeper didn't need to beep.
    {
    if(!started)
    started=1;
    }

    if(started && val==0)
    {
    if(!beeper)
    beeper=1;
    }

    if(beeper)
    {
    if(val BEEPER=!BEEPER;
    else
    {
    BEEPER=1;
    beeper=0;
    }
    }

    // if(beeper)
    // {
    //
    // if(val // //BEEPER(1) ;
    // fm=0;
    // else
    // {
    // //BEEPER(0);
    // fm=1;
    // beeper=0;
    //
    //
    // }
    //
    // }

    }

    void main()
    {
    TMOD=0x01;
    TH0=(65536-50000)/256;
    TL0=(65536-50000)%256;
    // TH1=(65536-50000)/256;
    //TL1=(65536-50000)%256;
    EA=1;
    ET0=1;
    // ET1=1;
    // TR1=1;
    TR0=1;
    while(1)
    {
    SFM();
    display3(shi,ge);
    display2(f_shi,f_ge);
    display1(s_shi,s_ge);
    alarm();
    }


    }


    void T0_Time() interrupt 1
    {
    TH0=(65536-50000)/256;
    TL0=(65536-50000)%256;
    num++;

    }


    • 发布于2016-10-27
    • 举报
    • 评论 0
    • 0
    • 0

  • 本帖最后由 MOP 于 2016-10-27 19:52 编辑

    嗨,您的Code還是有問題,除非你實體電路也是PNP電晶體?
    那初始化也要更改才對
    void main()
    {
      //BEEPER=0; //NPN
      //BEEPER=1; //PNP
       TMOD=0x11;
       TH0=(65536-50000)/256;
       TL0=(65536-50000)%256;
       TH1=(65536-50000)/256;
       TL1=(65536-50000)%256;
       EA=1;
       ET0=1;
       ET1=1;
       TR1=1;
       TR0=1;
       while(1)
    同樣修改以下邏輯部分:
      if(beeper)
      {
        if(val                                            
    • 发布于2016-10-27
    • 举报
    • 评论 0
    • 0
    • 0

  • MOP 发表于 2016-10-27 19:32
    嗨,您的Code還是有問題

    BEEPER=0是让蜂鸣器响,这我理解的没错吧
    • 发布于2016-10-27
    • 举报
    • 评论 0
    • 0
    • 0

  • MOP 发表于 2016-10-27 19:32
    嗨,您的Code還是有問題,除非你實體電路也是PNP電晶體?
    那初始化也要更改才對
    同樣修改以下邏輯部分:

    我的仿真图是按照实体机来弄的,修改了之后还是之前那个效果,不理想
    • 发布于2016-10-27
    • 举报
    • 评论 0
    • 0
    • 0

  • MOP 发表于 2016-10-27 19:53
    嗯,要看你實體是不是也是PNP電晶體,你看我補充的,確保邏輯正確

    逻辑是对的,但是现象和预想的不符合,我等下回去把电路图和仿真文件发给您,您看看,是不是我哪里还有漏洞
    • 发布于2016-10-27
    • 举报
    • 评论 0
    • 0
    • 0

  • MOP 发表于 2016-10-27 20:07
    嗨,我剛看了ALARM_TIME不用改喔,是5喔,前面沒講清楚抱歉
    也就是說除了PNP/NPN的邏輯差別,其他不用改
    再 ...

    谢谢您的耐心指导,程序终于调试出来了,但我修改了您给我的代码的以下几个方面:
    1、 while(1)
    {
    SFM();
    display3(shi,ge);
    display2(f_shi,f_ge);
    display1(s_shi,s_ge);
    alarm();
    }
    }

    void alarm(void)
    {


    if(MIN>0 && val==0) // When booting up, the beeper didn't need to beep.
    {
    if(!started)
    started=1;
    }

    if(started && val==0)
    {
    if(!beeper)
    beeper=1;
    }

    if(beeper)
    {
    if(val BEEPER=!BEEPER;
    else
    {
    BEEPER=1;
    beeper=0;
    }
    }

    这是您之前的,这个程序您是想要让他就每秒进来一次翻转一次BEEPER的电平,但是这个这个alarm()函数
    是在while(1)这个大循环里面的,当我的定时器还没有计数到1秒的时候只要alarm()在while(1)里面他在定时器计数期间就会一直执行alarm(),所以当val 随后我就修改了这一段,修改如下:
    #define ALARM_TIME 6
    void main()
    {
    BEEPER=1;
    TMOD=0x11;

    TH0=(65536-50000)/256;
    TL0=(65536-50000)%256;
    TH1=(65536-50000)/256;
    TL1=(65536-50000)%256;
    EA=1;
    ET0=1;
    ET1=1;
    TR1=1;
    TR0=1;
    while(1)
    {
    SFM();
    if(num1==20)
    {
    num1=0;
    alarm();
    }
    //alarm();
    display3(shi,ge);
    display2(f_shi,f_ge);
    display1(s_shi,s_ge);
    }
    }
    void T1_Time() interrupt 3
    {
    TH1=(65536-50000)/256;
    TL1=(65536-50000)%256;
    num1++;
    }
    以上的意思是多加一个定时器1每一秒进入一次alarm()这个函数里面然后
    #define ALARM_TIME 6 这个的含义是0响1不响2响......

    最后再次真诚感谢您提供的建议!
    • 发布于2016-10-27
    • 举报
    • 评论 0
    • 0
    • 0

  • 感谢所有参与回复的所有人,谢谢你们的建议!
    • 发布于2016-10-27
    • 举报
    • 评论 0
    • 0
    • 0

  • 本帖最后由 MOP 于 2016-10-27 23:32 编辑

    嗯,這樣學習是好的,翻轉問題是故意這樣寫的,因為直接給您Code還是不太好:)
    所以還需要改動的,While loop會一直執行,而BEEPER值必須跟著val值改變,所以正確做法如下,單一定時器
    const uchar on_off[5]={0,1,0,1,0};
    
    那麼While loop修改如下:
    if(beeper)
    {
      if(val另外ALARM_TIME之所以是5不是6是因為:
    第0秒之後,if成立,BEEPER=0,鳴叫
    第1秒之後,if成立,BEEPER=1,關閉
    第2秒之後,if成立,BEEPER=0,鳴叫
    第3秒之後,if成立,BEEPER=1,關閉
    第4秒之後,if成立,BEEPER=0,鳴叫
    第5秒之後,if不成立,進入else,BEEPER=1,關閉
    這樣應該很明白了:)



    • 发布于2016-10-27
    • 举报
    • 评论 0
    • 0
    • 0

  • MOP 发表于 2016-10-27 23:24
    嗯,這樣學習是好的,翻轉問題是故意這樣寫的,因為直接給您Code還是不太好
    所以還需要改動的,While loop會 ...

    嗯嗯,谢啦
    • 发布于2016-10-27
    • 举报
    • 评论 0
    • 0
    • 0

相关问题

问题达人换一批

如何让其他延时程序进行时不影响数码管动态扫描