![]() |
不知道這個程序能不能用,學飛一下 |
上面程序有點錯誤,改了一下。還是不顯示 #include"reg51.h" #include"intrins.h" #include"crc.h" #define LCD1602_DB P0 sbit LCD1602_RS = P1^0; sbit LCD1602_RW = P1^1; sbit LCD1602_E = P1^5; void InitLcd1602(); void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str); #define uint unsigned int #define uchar unsigned char uchar code sendbuf[]={0x01,0x03,0x02,0x00,0x00,0x03,0x04,0x73}; //0x01 從站地址,0x03功能碼,0x20寄存器地址高位,0x00寄存器地址低位,0x00數(shù)據(jù)個數(shù)高位,0x03數(shù)據(jù)個數(shù)低位,0x04CRC校驗碼高位,0x73CRC校驗碼低位 uchar code tab[]={'0','1','2','3','4','5','6','7','8','9'}; uchar code error[]={"error!"}; uchar tem[5],tem1[9]; uchar resvbuf[11]; int i,j; uchar resvend,temp2; uint crctemp,temp,temp1; void convert10(uint dat) { uchar i; tem1[0]='U'; tem1[1]='='; tem1[7]='V'; tem1[8]='\0'; tem[0]=dat/10000; dat=dat%10000; tem[1]=dat/1000; dat=dat%1000; tem[2]=dat/100; dat=dat%100; tem[3]=dat/10; tem[4]=dat%10; for (i=0;i<5;i++) { tem1[i+2]=tab[tem[i]]; } } void serial_int() interrupt 4 using 1 { if(RI) { RI=0; //temp2=SBUF; resvbuf[j++]=SBUF; if(j==11) { j=0; resvend=1; } } } void initserial () { resvend=0; TMOD=0x20; PCON=0x00; SCON=0xd8; TL1=0xfd; TH1=0xfd; TR1=1; ES=1; } void displayout() { crctemp=crccheck(resvbuf,9); temp=resvbuf[9]; temp=temp << 8 | resvbuf[10]; if(temp==crctemp) { temp1=0; temp1 |=resvbuf[3]; temp1= temp1<<8 | resvbuf[4]; convert10(temp1); LcdShowStr(0, 1, tem1); //printf(tem1,8); } else { LcdShowStr(0,1,error); //printf(error,16); } } void delay_10us(uchar n) { do { _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); }while(--n); } void delay_ms(uint n) { do { delay_10us(131); }while(--n); } /* 等待液晶準備好 */ void LcdWaitReady() { unsigned char sta; LCD1602_DB = 0xFF; LCD1602_RS = 0; LCD1602_RW = 1; do { LCD1602_E = 1; sta = LCD1602_DB; //讀取狀態(tài)字 LCD1602_E = 0; } while (sta & 0x80); //bit7等于1表示液晶正忙,重復檢測直到其等于0為止 } /* 向LCD1602液晶寫入一字節(jié)命令,cmd-待寫入命令值 */ void LcdWriteCmd(unsigned char cmd) { LcdWaitReady(); LCD1602_RS = 0; LCD1602_RW = 0; LCD1602_DB = cmd; LCD1602_E = 1; LCD1602_E = 0; } /* 向LCD1602液晶寫入一字節(jié)數(shù)據(jù),dat-待寫入數(shù)據(jù)值 */ void LcdWriteDat(unsigned char dat) { LcdWaitReady(); LCD1602_RS = 1; LCD1602_RW = 0; LCD1602_DB = dat; LCD1602_E = 1; LCD1602_E = 0; } /* 設置顯示RAM起始地址,亦即光標位置,(x,y)-對應屏幕上的字符坐標 */ void LcdSetCursor(unsigned char x, unsigned char y) { unsigned char addr; if (y == 0) //由輸入的屏幕坐標計算顯示RAM的地址 addr = 0x00 + x; //第一行字符地址從0x00起始 else addr = 0x40 + x; //第二行字符地址從0x40起始 LcdWriteCmd(addr | 0x80); //設置RAM地址 } /* 在液晶上顯示字符串,(x,y)-對應屏幕上的起始坐標,str-字符串指針 */ void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str) { LcdSetCursor(x, y); //設置起始地址 while (*str != '\0') //連續(xù)寫入字符串數(shù)據(jù),直到檢測到結束符 { LcdWriteDat(*str++); //先取str指向的數(shù)據(jù),然后str自加1 } } /* 初始化1602液晶 */ void InitLcd1602() { LcdWriteCmd(0x38); //16*2顯示,5*7點陣,8位數(shù)據(jù)接口 LcdWriteCmd(0x0C); //顯示器開,光標關閉 LcdWriteCmd(0x06); //文字不動,地址自動+1 LcdWriteCmd(0x01); //清屏 } void main() { InitLcd1602(); initserial(); EA=1; while(1) { i=0; while(i<8) { SBUF=sendbuf[i]; while(!TI); delay_10us(50); TI=0; i++; } delay_ms(1000); if(resvend) { resvend=0; displayout(); } } } |
為么我的程序,LCD不顯示 #include"reg51.h" #include"address.h" #include"intrins.h" #include"crc.h" #define LCD1602_DB P0 sbit LCD1602_RS = P1^0; sbit LCD1602_RW = P1^1; sbit LCD1602_E = P1^5; void InitLcd1602(); void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str); #define uint unsigned int #define uchar unsigned char uchar code sendbuf[]={0x01,0x03,0x02,0x00,0x00,0x03,0x04,0x73}; //0x01 從站地址,0x03功能碼,0x20寄存器地址高位,0x00寄存器地址低位,0x00數(shù)據(jù)個數(shù)高位,0x03數(shù)據(jù)個數(shù)低位,0x04CRC校驗碼高位,0x73CRC校驗碼低位 uchar code tab[]={'0','1','2','3','4','5','6','7','8','9'}; uchar code error[]={"error!"}; uchar tem[5],tem1[8]; uchar resvbuf[10]; int i,j; uchar resvend,temp2; uint crctemp,temp,temp1; void convert10(uint dat) { uchar i; tem1[0]='U'; tem1[1]='='; tem1[7]='V'; tem[0]=dat/10000; dat=dat%10000; tem[1]=dat/1000; dat=dat%1000; tem[2]=dat/100; dat=dat%100; tem[3]=dat/10; tem[4]=dat%10; for (i=0;i<5;i++) { tem1[i+2]=tab[tem[i]]; } } void serial_int() interrupt 4 using 1 { if(RI) { RI=0; //temp2=SBUF; resvbuf[j++]=SBUF; if(j==7) { j=0; resvend=1; } } } void initserial () { resvend=0; TMOD=0x20; PCON=0x00; SCON=0xd8; TL1=0xfd; TH1=0xfd; TR1=1; ES=1; } void displayout() { crctemp=crccheck(resvbuf,9); temp=resvbuf[9]; temp=temp << 8 | resvbuf[10]; if(temp==crctemp) { temp1=0; temp1 |=resvbuf[3]; temp1= temp1<<8 | resvbuf[4]; convert10(temp1); LcdShowStr(0, 1, tem1); //printf(tem1,8); } else { LcdShowStr(0, 1,error ); //printf(error,16); } } void delay_10us(uchar n) { do { _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); }while(--n); } void delay_ms(uint n) { do { delay_10us(131); }while(--n); } /* 等待液晶準備好 */ void LcdWaitReady() { unsigned char sta; LCD1602_DB = 0xFF; LCD1602_RS = 0; LCD1602_RW = 1; do { LCD1602_E = 1; sta = LCD1602_DB; //讀取狀態(tài)字 LCD1602_E = 0; } while (sta & 0x80); //bit7等于1表示液晶正忙,重復檢測直到其等于0為止 } /* 向LCD1602液晶寫入一字節(jié)命令,cmd-待寫入命令值 */ void LcdWriteCmd(unsigned char cmd) { LcdWaitReady(); LCD1602_RS = 0; LCD1602_RW = 0; LCD1602_DB = cmd; LCD1602_E = 1; LCD1602_E = 0; } /* 向LCD1602液晶寫入一字節(jié)數(shù)據(jù),dat-待寫入數(shù)據(jù)值 */ void LcdWriteDat(unsigned char dat) { LcdWaitReady(); LCD1602_RS = 1; LCD1602_RW = 0; LCD1602_DB = dat; LCD1602_E = 1; LCD1602_E = 0; } /* 設置顯示RAM起始地址,亦即光標位置,(x,y)-對應屏幕上的字符坐標 */ void LcdSetCursor(unsigned char x, unsigned char y) { unsigned char addr; if (y == 0) //由輸入的屏幕坐標計算顯示RAM的地址 addr = 0x00 + x; //第一行字符地址從0x00起始 else addr = 0x40 + x; //第二行字符地址從0x40起始 LcdWriteCmd(addr | 0x80); //設置RAM地址 } /* 在液晶上顯示字符串,(x,y)-對應屏幕上的起始坐標,str-字符串指針 */ void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str) { LcdSetCursor(x, y); //設置起始地址 while (*str != '\0') //連續(xù)寫入字符串數(shù)據(jù),直到檢測到結束符 { LcdWriteDat(*str++); //先取str指向的數(shù)據(jù),然后str自加1 } } /* 初始化1602液晶 */ void InitLcd1602() { LcdWriteCmd(0x38); //16*2顯示,5*7點陣,8位數(shù)據(jù)接口 LcdWriteCmd(0x0C); //顯示器開,光標關閉 LcdWriteCmd(0x06); //文字不動,地址自動+1 LcdWriteCmd(0x01); //清屏 } void main() { InitLcd1602(); initserial(); EA=1; while(1) { i=0; while(i<8) { SBUF=sendbuf[i]; while(!TI); delay_10us(50); TI=0; i++; } delay_ms(1000); if(resvend) { resvend=0; displayout(); } } } |
大鍋,拷貝你得程序,LCD根本不顯示 |
用在嚴謹場合不形,MODBUS最基本的一串數(shù)據(jù)接收完成的時間間隔判斷都沒有 |
簡單,明了,可惜的是各種判斷都省略了,如果用在嚴謹?shù)牡膱龊希@然是不適用的。 |
實物測試通過了嗎 |
Powered by 單片機教程網(wǎng)