主要问题是没理解138译码原理,从上述文字来看,现在可能还理解得不够! |
楼主为什么要用delay呢??这样写的额程序很容易出问题,特别是对时序要求高的地方,建议用查询的方法来控制时序动作。 |
GOD丿小男孩 发表于 2017-9-13 15:20 也可能是软件差别,我用protues8.6,keil3.8a没问题 |
GOD丿小男孩 发表于 2017-9-13 15:20 我仿真了下没问题呀,很完美。可能仿真电路有些差别 |
18707072428 发表于 2017-9-13 21:00 没有问题的!对照真值表写的。 |
看来被人解决了啊 |
138译码器对应的程序有问题,数字显示错乱 |
我现在会了,代码发在上面,有什么不懂的尽管问 |
不会啊 |
犯了一个基本错误。每一行的table没有赋值给P0端,只是写出来而已;另外if语句中应该是等于2时为真,还有最后一个if语句内容也稍作修改,才能加满后循环,感谢大家的帮助;下面把代码附上,亲测可用; #include<reg52.h> sbit A=P2^2; //定义控制数码管管脚 sbit C=P2^3; sbit D=P2^4; typedef unsigned char u16; typedef unsigned int u8; unsigned char code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d, 0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e, 0x79,0x71,0x00}; void delay(u16 z) //延时函数 { u16 x,y; for(x=z;x>0;x--) for(y=100;y>0;y--); } void main() //数码管显示二进制累加函数 { u16 k,j,i,g; u16 h,f,m,a,l; //定义变量 j=0;i=0;g=0;h=0;f=0;m=0;l=0; while(1) //大循环 { for(k=0;k<3;k++) //控制1数码管显示 { for(a=50;a>0;a--) //使数码管显示时间足够人眼识别 { A=0;C=0;D=0;P0=table[k];delay(3); //1数码管显示0或1 if(k==2){j++;k=0;} //当1数码管显示1后,使二数码管显示1; A=1;C=0;D=0;P0=table[j];delay(3); //控制2数码管显示0或1; if(j==2){i++;j=0;} //以下相同; A=0;C=1;D=0;P0=table[i];delay(3); if(i==2){g++;i=0;} A=1;C=1;D=0;P0=table[g];delay(3); if(g==2){h++;g=0;} A=0;C=0;D=1;P0=table[h];delay(3); if(h==2){f++;h=0;} A=1;C=0;D=1;P0=table[f];delay(3); if(f==2){m++;f=0;} A=0;C=1;D=1;P0=table[m];delay(3); if(m==2){l++;m=0;} A=1;C=1;D=1;P0=table[l];delay(3); if(l==2){k=3;l=0;} //退出循环 } } } } |
漫步经心 发表于 2017-9-13 08:54 那样是好一点,不过我前面按照你这种方式写了一个十进制累加的,发现其实都一样的,因为后面是相同的,错误都是一样的,很方便改 |
mengzhixinheng 发表于 2017-9-13 01:34 嗯,多谢提醒。我写的时候是对照真值表写的,所以不会出错 |
mengzhixinheng 发表于 2017-9-13 01:25 感谢的你帮助,不是电路问题,犯了一个最基本的错误 |
mengzhixinheng 发表于 2017-9-13 01:24 非常感谢你的帮助,不过你这个代码出来后是不显示1的,只有0或者不显示,应该是该显示1的时候数码管没点亮。看了你的代码才知道我错在哪了,是每一行的table没有赋值给P0;显示才没有意义,现在已经改过来了,并且稍作修改后能正常显示,待会我会放下面,谢谢你了,你这个比较高端一点,我的代码就是最简单的逻辑来写的 |
我个人建议你先让数码管显示一个数字,然后再动态刷新。循序渐进这样比较稳妥。一次性写那么多,出错了你都找不到北。否则也就没有那么多人说模块化了。 |
自己改程序匹配你的电路 |
#include<reg51.h> typedef unsigned int uint; typedef unsigned char uchar; sbit A1=P1^4; sbit B1=P1^3; sbit C1=P1^2; unsigned char code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; void delayms(uchar x) { uint i,j; for(i=x;i>0;i--) for(j=120;j>0;j--); } /*void display() { uchar X,Y; for(X=0;X<16;X++) for(Y=0;Y<100;Y++) { A1=0;B1=0;C1=0;P2=table[X];delayms(3); A1=0;B1=0;C1=1;P2=table[X];delayms(3); A1=0;B1=1;C1=0;P2=table[X];delayms(3); A1=0;B1=1;C1=1;P2=table[X];delayms(3); A1=1;B1=0;C1=0;P2=table[X];delayms(3); A1=1;B1=0;C1=1;P2=table[X];delayms(3); A1=1;B1=1;C1=0;P2=table[X];delayms(3); A1=1;B1=1;C1=1;P2=table[X];delayms(3); } } */ void hex() { uchar m,su; for(m=0x00;m<0xff;m++) for(su=0;su<50;su++) { A1=1;B1=1;C1=1; if(m&0x01)P2=table[1];else P2=table[0];delayms(3); A1=1;B1=1;C1=0; if(m&0x02)P2=table[1];else P2=table[0];delayms(3); A1=1;B1=0;C1=1; if(m&0x04)P2=table[1];else P2=table[0];delayms(3); A1=1;B1=0;C1=0; if(m&0x08)P2=table[1];else P2=table[0];delayms(3); A1=0;B1=1;C1=1; if(m&0x10)P2=table[1];else P2=table[0];delayms(3); A1=0;B1=1;C1=0; if(m&0x20)P2=table[1];else P2=table[0];delayms(3); A1=0;B1=0;C1=1; if(m&0x40)P2=table[1];else P2=table[0];delayms(3); A1=0;B1=0;C1=0; if(m&0x80)P2=table[1];else P2=table[0];delayms(3); } } void main() { while(1) { // display(); hex(); } } 16进制输出到一个完整的端口用led亮灭直接就可以表示出二进制状态。你要用数码管0和1表示,只需要判断哪个数码管该显示什么就行。这个由你的累加数决定 |