現象:5 位數碼管共陽極動態掃描,P3.0~P3.4 位選,P0 段碼輸出。Proteus 仿真顯示只有後四位(P3.1~P3.4)亮,第一位(P3.0)常暗,邏輯分析儀顯示 P3.0 無電平翻轉。
while(1) {
P3 = 0x01; // 僅初始化一次?應在迴圈內每次更新
for(i=0; i<5; i++) {
if(P0_7==0) P0 = num1[i];
else P0 = num2[i];
P3 <<= 1; // 左移:0x01→0x02→0x04→0x08→0x10
delay();
P0_7 = !P0_7; // 切換顯示內容?
}
}
P3 = 0x01; 放在 while(1) 外,導致第一次進入 for 迴圈前 P3 已被左移。修正:移入 for 迴圈開頭或 while 迴圈開頭。
// 修正後的掃描邏輯
uchar pos = 0x01; // P3.0 對應第一位
for(i=0; i<5; i++) {
P0 = (P0_7==0) ? num1[i] : num2[i]; // 輸出段碼
P3 = pos; // 選中當前位
delay(2); // 2-5ms
P0 = 0xFF; // 消隱
pos <<= 1; // 下一位
if (pos == 0x20) pos = 0x01; // 循環(5位:0x01,0x02,0x04,0x08,0x10)
}
num1/num2 為共陽極編碼(段亮=0)。常見編碼:0: 0xC0 (1100 0000)。
void main() {
P0_7 = 0;
uchar pos = 0x01;
while(1) {
for(uchar i=0; i<5; i++) {
P0 = (P0_7==0) ? num1[i] : num2[i];
P3 = pos;
delay(2);
P0 = 0xFF;
pos <<= 1;
if (pos == 0x20) pos = 0x01;
}
P0_7 = !P0_7; // 若需切換顯示內容,放在整輪掃描後
}
}
printf 輸出當前 i, pos, P0 值驗證邏輯。delay,檢查迴圈計數是否正確。「只有後四位亮」經典癥結在於位選信號更新時機與迴圈邊界條件。將位選變數 pos 獨立維護、在迴圈內先輸出段碼再更新位選、嚴格控制 5 位循環,配合 Proteus 邏輯分析儀觀察波形,即可快速定位並解決。單片機顯示驅動的核心是時序精確,任何多餘指令導致的時序抖動都會造成顯示異常。