找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 802|回复: 3
收起左侧

单片机定时器数码管程序调试卡着了,求指教

[复制链接]
ID:619500 发表于 2023-4-29 23:50 | 显示全部楼层 |阅读模式
利用动态扫描和定时器0在数码管上显示出从543210开始以1%秒的速度往下递减直至543111并保持显示此数,与此同时利用定时器0以500MS速度进行流水灯从上至下移动,同时蜂鸣器发声,当数码管上数减到停止时,实验板上流水灯全部闪烁4次,数码管全熄灭。单片机进入休眠状态。
我写的单片机程序:
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,
0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
sbit ledla=P2^5;
sbit dula=P2^6;
sbit wela=P2^7;
sbit laba=P2^3;
uint num,n,e;
uchar b,i,c,d;
display();
delay(uchar);


void main()
{      
        TMOD=0x01;
        TH0=(65536-10000)/256;
        TL0=(65536-10000)%256;
        EA=1;
        ET0=1;
        TR0=1;      //开中断
        num=999;     //项目 只有后三位变化。我就给999;
        b=7;       //用来给八个流水灯循环用
        laba=0;     //蜂鸣器开
        d=0;       //自己写的数码开始保持543111标志位
        while(1)
        {
      
                 display();//数码管显示
                P1=~(1<<b);//流水灯显示
               
                if(i==8)
                {
                        i=0;
                        b=7;
                }


               
                if(d==1)//数码管保持在543111后d=1,进入以后操作
                {
                       
                       
                        for(c=0;c<3;c++)
                        {
                                P1=0x00;
                                for(e=0;e<65535;e++);
                                P1=0xff;
                                for(e=0;e<65535;e++);//流水灯全亮并亮灭三次
                        }


                        laba=1;                        //关蜂鸣器
                        P1=0xff;                //关流水灯
            P0=0xff;
                        wela=1;
                        wela=0;
                        P0=0xff;
                        dula=1;
                        dula=0;                        //关数码管
                        PCON=0x02;                //进入休眠
                }


        }
}


delay(uchar x)    //延时
{      
        uchar a,b;
        for(a=x;a>0;a--)
                for(b=200;b>0;b--);
}
void t0() interrupt 1
{      
      
        n++;
        if(num>111)   //num数码管的后三位
        {
                num--;
                d=0;
        }
        if(num==111)
        {
                d=1;
        }
               
        TH0=(65536-10000)/256;
        TL0=(65536-10000)%256;
      
        if(n==50)
        {
                i++;
                b--;
                n=0;
        }
}
display()
{
        P0=0xff;
        wela=1;
        wela=0;
        P0=table[6];
        dula=1;
        dula=0;
        P0=0xfe;
        wela=1;
        wela=0;
        delay(5);


P0=0xff;
        wela=1;
        wela=0;
        P0=table[5];
        dula=1;
        dula=0;
        P0=0xfd;
        wela=1;
        wela=0;
        delay(5);
P0=0xff;
        wela=1;
        wela=0;
        P0=table[4];
        dula=1;
        dula=0;
        P0=0xfb;
        wela=1;
        wela=0;
        delay(5);
P0=0xff;
        wela=1;
        wela=0;
        P0=table[num/100];
        dula=1;
        dula=0;
        P0=0xf7;
        wela=1;
        wela=0;
        delay(5);
P0=0xff;
        wela=1;
        wela=0;
        P0=table[num%100/10];
        dula=1;
        dula=0;
        P0=0xef;
        wela=1;
        wela=0;
        delay(5);
P0=0xff;
        wela=1;
        wela=0;
        P0=table[num%100%10];
        dula=1;
        dula=0;
        P0=0xdf;
        wela=1;
        wela=0;
        delay(5);
}
以上是单片机代码
下面是问题:
惟一的出错的在于。没办法保持543111;运行到最后数码管前五个不亮,第六个保持亮1到结束。 
if(d==1)下面这些内容不要。确实可以保持在543111;有了if(d==1)下面这些就会最后一个管亮1.
请各位大神指教。十分感谢。
回复

使用道具 举报

ID:619500 发表于 2023-4-30 10:04 | 显示全部楼层
找出来了。DISPLAY()要放中断函数里面才是一直运行,不然停下后。只能最后一个数码管显示1
回复

使用道具 举报

ID:213173 发表于 2023-4-30 10:33 | 显示全部楼层
楼主的意图本身就存在逻辑问题 ,“543210开始以1%秒的速度往下递减直至543111” 其过程就是990ms,在此区间以500mS速度进行流水灯从上至下移动???
运行到最后数码管前五个不亮,第六个保持亮1到结束。是因为流水灯全亮并亮灭4次期间数码管停止扫描。
给你改了:把543210递减至543111的时间改为9.9s以便观察。重点是要理解数码管动态显示函数的运行方式。
  1. #include <reg51.h>
  2. #include <intrins.h>
  3. #define uchar unsigned char
  4. #define uint  unsigned int

  5. sbit dula=P2^6;
  6. sbit wela=P2^7;
  7. sbit buzzer=P2^3;

  8. uchar code table[]={//共阴数码管段码"0~f-."
  9.                 0x3f,0x06,0x5b,0x4f,
  10.                 0x66,0x6d,0x7d,0x07,
  11.                 0x7f,0x6f,0x77,0x7c,
  12.                 0x39,0x5e,0x79,0x71,0x40,0x80};
  13. uchar data dis_buf[6];                //缓存数组
  14. uchar b,c;
  15. uchar count,num;
  16. bit stop,mark,sign;

  17. void Timer0Init()                //1毫秒@11.0592MHz
  18. {
  19.         TMOD= 0x01;                //设置定时器模式
  20.         TL0 = 0x66;                //设置定时初始值
  21.         TH0 = 0xFC;                //设置定时初始值
  22.         TF0 = 0;                //清除TF0标志
  23.         TR0 = 1;                //定时器0开始计时
  24.         EA  = 1;
  25.         ET0 = 1;
  26. }

  27. void display()//数码管动态显示函数
  28. {
  29.         static uchar i;
  30.         P0=0x00;      dula=1;dula=0;//消隐
  31.         P0=~(0x01<<i);wela=1;wela=0;//送位码
  32.         P0=dis_buf[i];dula=1;dula=0;//送段码
  33.         i=++i%6;//循环计数
  34. }

  35. void main()
  36. {      
  37.         Timer0Init();
  38.         dis_buf[0]=table[5];//固定显示部分
  39.         dis_buf[1]=table[4];
  40.         dis_buf[2]=table[3];
  41.         P1=0xfe;
  42.         buzzer=0;
  43.         num=210;
  44.         while(1)
  45.         {
  46.                 if(mark)//周期100ms
  47.                 {
  48.                         mark=0;
  49.                         if(stop==0)//流水灯
  50.                         {
  51.                                 P1=P1<<1|0x01;
  52.                                 if(P1==0xff)
  53.                                         P1=0xfe;
  54.                         }
  55.                         else  //闪烁灯
  56.                         {
  57.                                 if(++b==5)//500ms
  58.                                 {
  59.                                         b=0;       
  60.                                         P1=~P1;
  61.                                         if(++c==8)//闪烁4次结束运行,全部复位
  62.                                         {
  63.                                                 c=0;
  64.                                                 EA=0;
  65.                                                 buzzer=1;   //关蜂鸣器
  66.                                                 P1=0xff;  //关LED
  67.                                                 P0=0xff;  //关数码管
  68.                                                 dula=1;
  69.                                                 wela=1;
  70.                                                 _nop_();
  71.                                                 _nop_();
  72.                                                 PCON=0x02;//进入休眠
  73.                                         }
  74.                                 }
  75.                         }
  76.                 }
  77.                 dis_buf[3]=table[num/100%10];
  78.                 dis_buf[4]=table[num/10%10];
  79.                 dis_buf[5]=table[num%10];
  80.         }
  81. }

  82. void Timer0Interrupt() interrupt 1
  83. {   
  84.         TH0 = 0xFC;                //1毫秒@11.0592MHz
  85.         TL0 = 0x66;

  86.         if(++count==100)//100ms
  87.         {
  88.                 count=0;
  89.                 mark=1;//100ms标志
  90.                 if(!stop)
  91.                 {
  92.                         num--;
  93.                         if(num==111)
  94.                         {
  95.                                 stop=1;//计数结束
  96.                                 P1=0xff;//流水灯结束
  97.                         }
  98.                 }
  99.         }
  100.         display();//数码管动态显示函数
  101. }



复制代码
回复

使用道具 举报

ID:619500 发表于 2023-4-30 17:07 | 显示全部楼层
wulin 发表于 2023-4-30 10:33
楼主的意图本身就存在逻辑问题 ,“543210开始以1%秒的速度往下递减直至543111” 其过程就是990ms,在此区 ...

哈哈。是的。动态扫描理解的不到位。你这代码写的太漂亮了。很感谢。我好好消化一下。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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