51单片机中译码器以及锁存器的配合使用(有问题,待解决)

做的一个项目使用译码器配合锁存器,实现GPIO口P0的复用。

过程中有一个问题:

P0口被复用4次,第一次是用来控制数码管的显示,第二次是控制数码管的位选,第三次是8个LED灯,第四次是其他一些器件(蜂鸣器)。

我希望在数码管显示计时的同时,LED做流水灯。

我用51单片机的定时器0和1中断来实现。问题是,当程序RUN的时候,当进入while(1)后,数码管和流水灯开始运行,但是在中断中没用用到的蜂鸣器也开始响。

调试后,发现如果在流水灯中断中,如果选通LED灯后,将译码器置为000状态,此时蜂鸣器会不响,但是当数码管显示69附近时,又会又会响起。

初步考虑是译码器译码过程分步进行影响,但具体怎样尚未想通。

最近修改:16.2.1:将译码器的译码过程用位操作改为一步执行,的确消除异常,但其中机理尚未理解。

  1 #include<reg52.h>
  2 #include<math.h>
  3 #define ROL(led) ((led)<<1|(led)>>7)//循环移位1
  4 typedef unsigned char uchar;
  5 uchar code table[]={0xc0,0xf9,0xa4,0xb0,//0~3
  6 0x99,0x92,0x82,0xf8,//4~7
  7 0x80,0x90,0x88,0x83,//8~b
  8 0xc6,0xa1,0x86,0x8e //c~f
  9 };
 10 sbit A0 = P2^5;
 11 sbit A1 = P2^6;
 12 sbit A2 = P2^7;
 13 sbit NOISE = P0^6;
 14 int time;
 15 void decoder(char num);
 16 void delay(int num);
 17 void display(int num);
 18 void timer_initial();
 19 //===================================================
 20 int main()
 21 {
 22     unsigned char led = 0x01;
 23     char cnt,site;
 24     site = 0x01;
 25     decoder(5);
 26     WR = 0;
 27     NOISE = 0;//关闭蜂鸣器
 28     decoder(4);
 29     WR = 0;
 30     for(cnt = 0;cnt < 7;cnt++)//循环移位
 31     {
 32         P0 = ~led;
 33         led = ROL(led);
 34         delay(100);
 35     }
 36     EA = 1;
 37     timer_initial();
 38     while(1)
 39     {
 40         display(time);
 41     }   
 42     return 0;    
 43 }     
 44 //=================================================================
 45 void decoder(char num)//设置译码器
 46 {
 47         A0 = num%2;
 48         A1 = (num>>1)%2;
 49         A2 = num>>2;
 50 }
 51 void delay(int num)
 52 {
 53     int i,j;
 54     for(i = 0;i<100;i++)
 55         for(j = 0;j<3*num;j++);
 56 }
 57 void display(int num)
 58 {
 59     int number[4];
 60     int cnt;
 61     int site = 0x01;
 62     for(cnt = 0;cnt<4;cnt++)
 63     {
 64         number[3-cnt] =table[(num/((int)pow(10,cnt)))%10];
 65     }
 66     for(cnt = 0;cnt < 4;cnt++)
 67     {
 68         decoder(7);
 69         WR = 0;
 70         P0 = number[cnt];
 71         decoder(6);           
 72         P0 = site;
 73         site = site<<1;
 74         if(site == 0x10) site =0x01; 
 75         WR = 1;
 76         delay(1);           
 77     }
 78 }
 79 void timer_initial()
 80 {
 81     TMOD = 0x11;
 82     TH0 = (1<<16 -50000)/256;
 83     TL0 = (1<<16 -50000)%256;
 84     TH1 = (1<<16 -50000)/256;
 85     TL1 = (1<<16 -50000)%256;
 86     ET0 = 1;
 87     ET1 = 1;
 88     TR0 = 1;
 89     TR1 = 1;
 90 }
 91 //==============================================================
 92 void timer0() interrupt 1//定时器0
 93 {
 94     static int count =0;
 95     TH0 = (1<<16 -50000)/256;
 96     TL0 = (1<<16 -50000)%256;
 97     count++;
 98     if(count == 20)
 99     {
100         count =0;
101         time++;
102     }
103 }
104 void timer1() interrupt 3//定时器1
105 {   
106     static int count = 0;
107     static uchar ledx = 0x01;
108     count++;
109     TH1 = (1<<16 -50000)/256;
110     TL1 = (1<<16 -50000)%256;  
111     if(count ==2)
112     {
113         count = 0;
114         WR = 0;
115         decoder(4);
116         P0 = ~ledx;
117         ledx = ROL(ledx);
118         WR = 1;
119         decoder(0);//此处如果删除则会出现异常
120     }
121 }

 

你可能感兴趣的:(51单片机中译码器以及锁存器的配合使用(有问题,待解决))