|
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); //等待设置完成 } |