仿真線路確定沒問題,是我的代碼問題,目前的問題是,其他顯示都可以實現,比如顯示數組table[],table1[],table2[],開始仿真都顯示正常,就是不顯示溫度,謝謝各位大佬指教了
51hei圖片_20191227174932.png (58.59 KB, 下載次數: 44)
下載附件
2019-12-27 17:53 上傳
/************************************************************/
#include<reg51.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define delayNop(); {_nop_();_nop_();_nop_();_nop_();};
uchar code table[]=" ERROR!!! ";
uchar code table1[]="xianzaiwendu ";
uchar code table2[]="Temp= . Cent";
uchar code table3[10]="0123456789";
sbit lcd_rs=P1^0;
//sbit lcd_rw=P1^1;
sbit lcd_en=P2^5;
sbit DQ=P2^3;
uchar num,time;
void delay(uint t)
{
unsigned char n;
while(t--)
{
for(n = 0; n<250; n++)
{
_nop_();
_nop_();
_nop_();
_nop_();
}
}
}
void write_com(uchar com) //寫命令
{
////lcd_rw=0;
//delay(5);
lcd_rs=0;
lcd_en=0;
_nop_();
_nop_();
P0=com;
delayNop();
lcd_en=1;
delay(1);
lcd_en=0;
}
void write_date(uchar date) //寫數據
{
//lcd_rw=0;
// delay(5);
lcd_rs=1;
lcd_en=0;
_nop_();
_nop_();
P0=date;
delayNop();
lcd_en=1;
delay(1);
lcd_en=0;
}
void init() //初始化函數
{
// dula=0;
// wela=0;
lcd_en=0; //可以試試不加這一句看結果怎樣
write_com(0x38);
write_com(0x0c);
write_com(0x06);
write_com(0x01);
}
uchar init_DS18bB20()
{
bit flag;
DQ=1; //人為拉高
for(time=0;time<2;time++); //稍微延時6US;
DQ=0; //認為拉低
for(time=0;time<200;time++); //延時600US給單片機檢測
DQ=1; //被上拉電阻拉高 (仿真里面沒有上拉,有沒有都需要人為拉高)
for(time=0;time<20;time++); // 延時60US檢測
flag=DQ; //這時又被DS18B20拉低,
for(time=0;time<200;time++); //延時600US檢測時間
return flag; //返回0表示存在
}
void Write_Byte(uchar dat) //寫一個字節,單片機向DS18B20寫命令,確定DS18B20的工作方法之類的
{
unsigned char i=0;
for (i=0; i<8; i++)
{
DQ =1; // 先將數據線拉高
_nop_(); //等待一個機器周期
DQ=0; //將數據線從高拉低時即啟動寫時序
DQ=dat&0x01; //利用與運算取出要寫的某位二進制數據,
//并將其送到數據線上等待DS18B20采樣
for(time=0;time<10;time++)
;//延時約30us,DS18B20在拉低后的約15~60us期間從數據線上采樣
DQ=1; //釋放數據線
for(time=0;time<1;time++)
;//延時3us,兩個寫時序間至少需要1us的恢復期
dat>>=1; //將dat中的各二進制位數據右移1位
}
for(time=0;time<4;time++)
; //稍作延時,給硬件一點反應時間
}
uchar Read_Byte()
{
uchar i=0;
uchar dat;//用來儲存讀出的一個字節,默認為0
for(i=0;i<8;i++)
{
DQ=1;
_nop_();
DQ=0; //讀命令一定得是低電平
dat>>=1; //讀取數據是從高位開始讀,dat默認是0,也就是0000 0000,
// 這是下標是指向最高位的,所以得先右移一位讓出一個位置
_nop_(); //需要>1US;
DQ=1; //又被上拉電阻拉高
for(time=0;time<2;time++);
if(DQ==1) //由DQ發送的信號來決定,發送的是高電平還是低電平
dat|=0x80; //高電平就或0x80,1000 0000
else
dat|=0x00; //低電平就或,0x00
for(time=0;time<5;time++);//延時10US左右,因為需要在15US內完成讀取
}
return dat;
}
void Readyread()//做好讀溫度準備。。。。可以加在主函數里面,但是分出來比較清晰明了
{
init_DS18bB20();
Write_Byte(0xcc); //跳過讀序號
Write_Byte(0x44); //啟動溫度轉換
for(time=0;time<100;time++);
init_DS18bB20(); //再初始化一下
Write_Byte(0xcc); //跳過讀序號
Write_Byte(0xbe); //都溫度寄存器,前兩個分別是溫度的,低,高位
}
void display() //顯示第一行說明
{
write_com(0x80);
for(num=0;num<16;num++)
{
write_date(table[num]);
// delay(1);
}
while(1);
}
void display1() //顯示第二行說明
{
write_com(0x80);
for(num=0;num<16;num++)
{
write_date(table1[num]);
// delay(1);
}
}
void display2()
{
write_com(0x80+0x40);
for(num=0;num<16;num++)
{
write_date(table2[num]);
//delay(1);
}
}
void display_temp(uchar x) //顯示溫度整數部分
{
uchar bai,shi,ge;
bai=x/100;
shi=(x%100)/10;
ge=x%10;
write_com(0x46);
write_date(table3[bai]);
write_date(table3[shi]);
write_date(table3[ge]);
}
void display1_temp(uchar x) //顯示溫度小數部分
{
write_com(0x4a);
write_date(table3[x]);
}
void main()
{
uchar TL;//儲存暫存器的溫度最高位
uchar TH;//儲存暫存器的溫度最低位
uchar TN; //儲存溫度整數部分
uchar TD; //儲存溫度小數部分
init();
if(init_DS18bB20()==1)
display();
display1();
// display2();
while(1)
{
Readyread();
TL=Read_Byte();
TH=Read_Byte();
TN=TH*16+TL/16; //實際溫度值=(TH*256+TL)/16,即:TH*16+TL/16
//這樣得出的是溫度的整數部分,小數部分被丟棄了
TD=(TL%16)*10/16; //計算溫度的小數部分,將余數乘以10再除以16取整,
//這樣得到的是溫度小數部分的第一位數字(保留1位小數)
display_temp(TN);
display1_temp(TD);
_nop_(); _nop_();
}
}
|