![]() |
借助這帖就說說阻塞與查詢延時的轉換,把代碼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; 試試。 |
每個數碼管顯示前都要消隱,是每個。 |