|
cy009 發表于 2025-9-15 09:48 可以解釋下嗎,busy = LCD_DATA;while(busy&0x80)和busy = LCD_DATA&0x80;while(busy)感覺語法上沒區別吧,為什么在仿真時有差異呢 |
cy009 發表于 2025-9-15 09:48 我把&的操作放到循環的判定條件里就行了 |
cy009 發表于 2025-9-15 09:48 你這樣寫不符合高可靠性和高實時性要求吧,一旦1602掛掉了,你整個程序就卡死在do-while循環中了,怎么也得弄個超時機制 |
| 我是直接忽略讀忙信號的。包括LCD1602和LCD12864,我都不讀忙信號的。 |
|
在要求高效、高速且可靠的項目中,使用讀忙信號是更好的選擇。 你的程序錯在第16行。 以下程序供參考: void LCD_CheckBusy(void) { unsigned char busy; LCD_DATA = 0xFF; // 設置數據端口為輸入模式(先寫1) LCD_RS = 0; // RS=0,選擇狀態寄存器 LCD_RW = 1; // RW=1,選擇讀模式 do { LCD_EN = 1; // 使能脈沖 _nop_(); busy = LCD_DATA; // 讀取狀態字 LCD_EN = 0; _nop_(); } while (busy & 0x80); // 檢測忙標志位(最高位) LCD_RW = 0; // 恢復為寫模式 } |
| 很可能是仿真模型不完備,忽略這個信號試試。 |
| 實際使用僅顯示時不需要這個讀忙,注釋掉就可以。 |
|
Lcd1602不檢測忙狀態也是可以的。 #define LCD_DATA P0 //液晶看數據口定義 sbit LCD_RS=P3^2; //LCD1602數據/命令選擇引腳,H:數據,L:命令 sbit LCD_RW=P3^3; //LCD1602讀寫引腳,H:數據寄存器,L:指令寄存器 sbit LCD_EN=P3^4; //LCD1602使能引腳,下降沿觸發 void Delay(uint i) //延時函數 { while(i--); } void Delay_MS(uint z) //z*1MS延時函數 { uint x,y; for(x=z;x>0;x--) for(y=110;y>0;y--); } void Lcd_W_Com(uchar com) //液晶寫指令函數 { LCD_RS=0; LCD_RW=0; LCD_DATA=com; Delay(20); LCD_EN=1; Delay(20); LCD_EN=0; } void Lcd_W_Dat(uchar dat) //液晶寫數據函數 { LCD_RS=1; LCD_RW=0; LCD_DATA=dat; Delay(20); LCD_EN=1; Delay(20); LCD_EN=0; } void Lcd_Show_Str(uchar hang,add,uchar *p)//液晶寫字符串函數 { if(hang==1) //液晶第一行 Lcd_W_Com(0x80+add); else //液晶第二行 Lcd_W_Com(0x80+0x40+add); while(1) { if(*p=='\0') break; Lcd_W_Dat(*p); //寫入數據 p++; } } void Lcd_Init() //液晶初始化 { Lcd_W_Com(0x38); //數據總線為8位,顯示2行,5x7點陣 Lcd_W_Com(0x0c); //開顯示,有光標,光標閃爍 Lcd_W_Com(0x06); //光標自動右移 Delay(1000); //等待設置完成 } |