|
借助这帖就说说阻塞与查询延时的转换,把代码if(++sy==0)修改while(++sy)就是阻塞延时,阻塞延时放前后都可以. |
鹈鹕 发表于 2023-11-20 15:53 谢谢你,目前所有的问题已经解决。确实有位选码(显示掩码)逻辑颠倒的问题。详情见我最新的置顶楼。 另外,我的中断函数里除了”timer==20“这一句有错误,也忘了令timer=0;所以后来无论怎么改timer都不影响速度(因为都是从0到255再到0)(哭笑) |
yzwzfyz 发表于 2023-11-20 09:32 谢谢你的分享。你讲的这个技巧看起来很惊艳,我会下来仔细琢磨并实践的 |
ydatou 发表于 2023-11-20 09:09 问题已经解决了,您说得真对,确实是硬件有一些问题没注意到或者是没法注意到(哭笑) |
tyrl800 发表于 2023-11-20 08:31 谢谢你的回复,消隐程序正反逻辑颠倒确实是问题之一 |
tyrl800 发表于 2023-11-19 19:49 谢谢你的回复,我已经解决了这个问题。板子与仿真原理图不一致确实是问题之一 |
你这个程序实际上是两个错误,第一个是我12楼说的那个,第二个我昨天晚上没看出来。第一个错误会导致这个计时器快10倍,我以为你所说的“重影”实际是走的快引起来显示8的原因,但早上起来我想想即使快10倍也不至于引起“重影”现象,即充其量秒的个位会因为变化快看起来像8,其他的就不会了,秒的10位肯定看得清楚因为快10倍也就是1秒一变,分钟就更加不会了。中午吃完饭没事就把你的程序复制下来稍加修改适合我的板子,上电一看果然4个8字,但凭经验看明显的不是因为跳变快引起的,这跟我前一段时间碰到的一个故障非常像,因为有这个经验仔细看了一下你的有关显示的代码,看出了问题所在,跟我的那个故障的原因虽然不完全一样,但现象确实会很像——是你把显示掩码(显示掩码,很多书上称为“位码”)的正负逻辑弄颠倒了,你的显示掩码电路肯定是负逻辑,一般的都是,而你把它当正逻辑来处理了,即display_time()函数中P3=,,,那4行右面是正逻辑01、02、04、08,这样该亮的不亮不该亮的3个同时亮,这么个扫描循环当然就乱七八糟了,所以正确的数值应该是这4个数的反码才对,或者你把他们的反码替代他们比如FE替代01等或者懒得算的话就在每个数字前面加个非号“~”即可。 之所以两个数码管时正常,那是假象,是因为只有两个数码管,它仍然遵循该亮的不亮其它都亮的规则,但这时的“其它”只有1个了,所以看上去就正常了,但这时,两位是颠倒的,即秒的10位显示的是个位数值,而个位显示的是十位。 第一个错误也要改否则的话根本就谈不上准确,且错误还不止那一句,虽然都是同一个错误。 |
你的位驱动是I0口直接驱动吗? 没有原理图,确实挺难帮你分析的 |
51单片机8位并行IO口一组,段码和位码不是并行发送的,所以需要消隐,16位以上不需要,新的位码送出去了,段码还是旧的,所以就出现影子了。 |
小小小初学者 发表于 2023-11-20 13:26 把板子的原理图发出来。 |
这个是老师发的原理图,单片机型号是STC 89C51RC |
DIY_MCU_51_REV1.0(2015.11.06)原理图.pdf
1.08 MB, 下载次数: 3
谢谢各位的回复,学业繁忙,我等晚上或者明天再一一回复。不过目前我越来越感觉问题不是代码,而是板子。因为我只保留输出秒个位的代码后,在调试中,拔掉了四个位选线。接下来按道理,其中只有一个位选线能让对应的数码管闪亮,但实际情况是:每条位选线都能让数码管闪亮。 这可能意味着位选线4个端总是0xff!!(即让数码管生效) 我换了我两个舍友的板子重新烧,结果是一样的,感觉同时焊错的可能性比较小.... |
忘记打括号了,加的要括号,或者删除+(ls==8||ls==32?SmZiFu[10]:0)加小数点,另外6位的话删除最后2位即64和128,修改条件 if(ls==0||ls==32) |
应该很好调试的,我没有仔细看楼主的程序只看了图片,如果不是消隐反向的话,建议楼主先不要忙那么多位显示,首先调试最后一位显示1->9正常后辐射4位就简单的多,如果连一位都不能正常显示那仔细磨驱动代码吧. |
数码管动态驱动是最基本的,它的原则:消隐-送段值-送位值-延时,按这样的顺序执行和编写代码. 看仿真图片数码管应该是共阳,我这里有个简单的荔枝,显示固定的日期小数点分割,修改了一下,仿真和下载开发板试看.
|
"扫屏显示的切换应当用最少的指令完成,在不多于8个LED的情况下:三条指令即可完成,对于STC的单片机,10us不到就完成了,例:8个LED哪个亮(位选)受P1控制,显示什么内容(段码)由P0决定。 要点:技巧如下!!! 先将哪个LED需要亮的参数事先准备好,放在:P1_OUT变量中,同样将这个LED需要显示的段码放在P0_OUT中。【这个做法最关键,不要直接切换操作P0、P1口,而是通过这两个变量来操作。原因是,无论你用多长时间对P1_OUT、P0_OUT进行操作,操作期间,显示不受影响。】 切换: 第一条指令:关断所有显示:P1=FFH ;关闭所有显示 第二条指令:切换LED段码:P0=P0_OUT ;这时显示已关,切换不会有残留,重影,闪烁了。 第三条指令:更新显示的LED管:P1=P1_OUT ;点亮需要显示的LED,例如:11101111B 【这个做法是最优秀的扫描显示切换方法,用时最短,最合理,没有之二!!!】 重复一下关键点:事先处理准备好变量P1_OUT、P0_OUT的值。" |
仿真结果和实验结果应该相差不大。 这种现象表示仿真模型和实验硬件不符。 |
小小小初学者 发表于 2023-11-19 21:41 你这个消隐程序错了,改成P3=0xff,你应该把电路板原理图发上来才能解决下载后的问题 |
鹈鹕 发表于 2023-11-19 20:30 你好,谢谢你的回复,首先我很抱歉我的叙述可能有些混乱,因为这东西搞得我有些焦头烂额。接下来我来回复你的质疑: 1.重影或者说残影,这个是我最原本代码确实存在的问题,因为没有消影。这个问题在大家的帮助下解决了。现在在仿真上是一切正常的。 2.我在1楼说的现象是真实的,只不过造成那个现象的代码和我在9楼说的现象所使用的代码相比,做了很多修改,两者代码不一样,现象也不一样,不是一回事。 现在的问题是,即时添加了消影,数码管仍然不能正确显示(大部分时间是8,9这种多个段接通的数字)。 我尝试在代码中删除显示分钟的,保留显示秒钟的,那么烧录到机子后,将有这样的现象:显示秒钟的两位正常显示,分钟位也显示(代码中已经删去显示分钟了),并且显示的是秒钟两位个位和十位的叠加
|
小小小初学者 发表于 2023-11-19 19:12 |
我根本就没法理解你的叙述,牛头不对马嘴的,数码管如何重影呢,它要么亮要么就不亮,总是清晰的,它就是个普通物体怎么个重影法,,,,但根据你的程序看,我知道你说的“重影”是什么意思,只是用这个词实在是太词不达意了;而且另一个现象更加不可能,【如果只显示两位,即秒的部分,那么则不会出现上述问题,】——这根本不可能,4位都都显示时,决不会4位都“重影”,左面两位不“重影”,右面的两位才“重影”,右面的是秒,而你偏偏说秒正常,这完全不可能 。。。。。 |
消隐并不重要,display_time函数中没有最后一行也不致引起很大的影响,几乎看不出来。 |
把这行语句多看几遍,直到看出问题来: if(timer==20){ //到达1s |
板子与仿真原理图肯定不一样才这样 |
P3 = 0x00; DIGIT_O=segCode[seconds/10]; P3 = 0x01; delay(5); 延时可适当加长 |
谢谢大家的回复,我重新在每个数码管显示前都添加了消隐(禁用位选,输出空段码两种方式都尝试了) 仿真结果均正常,但是烧录到机子里仍然有重影 |
Hephaestus 发表于 2023-11-19 16:37 谢谢,我这样试了。仿真恢复正常,但是板子仍然有重影好无奈啊 |
xianfajushi 发表于 2023-11-19 16:09 谢谢,我试了试后仿真没有问题,但是烧到板子上仍然有重影,不知道是哪的问题了现在(苦),头大 |
核心问题是动态扫描数码管没有消隐。
|
DIGIT_O=0XFF; 再复制3个 |
在每条 DIGIT_O= ; 前面加上 P3 = 0x0; 试试。 |
每个数码管显示前都要消隐,是每个。 |