?? 18b20.c
字號:
#include<regx51.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit rs=P2^1 ;
sbit rw= P2^2 ;
sbit e=P2^3 ;
sbit DO=P1^0;
uchar temp_l = 0; //溫度值存儲低位字節
uchar temp_h = 0; //溫度值存儲高位字節
uchar tempsign = 0; //溫度值符號位
uchar temp_integer[4]; //溫度整數存儲數組
uchar temp_dicimal[5]; //溫度小數存儲數組
void delay(uint ms)
{
uint i;
uchar j;
for(i=0;i<ms;i++)
for(j=0;j<250;j++)
{
_nop_();
_nop_();
_nop_();
_nop_();
}
}
void write_com(uchar com)
{
rs=0;
P3=com;
delay(1);
e=1;
delay(1);
e=0;
}
void write_data(uchar date)
{
rs=1;
P3=date;
delay(1);
e=1;
delay(1);
e=0;
}
void gotoxy(uchar x,uchar y) //光標指針移動到x行y列
{
if(x==0)
{
write_com(0x80+y);
}
else
{
write_com(0x80+0x40+y);
}
}
/* ##########################################################################
初始化:設置顯示模式 ---- 0x38 --設置16x2 顯示,5x7點陣,8位數據接口
顯示開/關及光標設置 -- 0x08 --關顯示
-- 0x0b --開顯示
0x0e --顯示光標,不閃爍
0x0c --不顯示光標,不閃爍
0x0d --光標閃爍,不顯示
0x0f --光標顯示+閃爍
------ 0x06 --讀或寫一個字符后地址指針加一,且光標加一,整屏不移動
------ 0x01 --顯示清屏:數據指針清零,所有顯示清零
0x02 --顯示回車:數據指針清零
######################################################################### */
void init()
{
rw=0; //開寫狀態
// write_com(0x01);
write_com(0x38);
write_com(0x0f);
write_com(0x06);
write_com(0x0c);
}
void print(uchar *p) //顯示字符串 //void display_string(uchar *str,uchar len)
{ // {
while(*p) // uchar i;
{ // for(i=0;i<len;i++)
write_data(*p); // {
p++; // write_data(str【i】);
} // }
} //
void display_number(uchar number) // }
{
write_data(0x30+number); //轉化為ASCII碼
}
/*us級延時,延時時間約4+2*i*/
void Delayus(uchar i)
{
while(--i);
}
/*產生復位脈沖,等待應答信號*/
bit Resetpaulse()
{
DO = 0; //拉低約600us
Delayus(150);
Delayus(150);
DO = 1;//產生上升沿,延時約15~60us
Delayus(30);
return(~DO); //等待應答信號
}
/*讀取數據一位*/
bit Readbit()
{
uint i = 0;
bit b = 0;
DO = 0; //產生讀時隙
i++; //維持低電平至少1us
DO = 1; //1us以上后拉高
Delayus(2); //延時8us,DO下降沿15內ds18b20輸出的數據才有效
b = DO; //讀取數據
Delayus(40); //每個讀時隙至少持續60us
return(b);
}
/*讀取一個字節*/
uchar Readbyte()
{
uchar byte_read = 0;
uchar i, j;
for(i=0; i<8; i++)
{
j = Readbit();
byte_read = (j<<i) | byte_read; //低位讀起
}
return(byte_read);
}
/*寫一個字節*/
void Writebyte(uchar byte_to_write)
{
uchar i = 0;
uchar j = 0;
bit write_bit = 0;
for(j=0; j<8; j++)
{
write_bit = (byte_to_write & 0x01);
if(write_bit == 1) //寫1
{
DO = 0; //產生寫時隙
Delayus(3); //延時15us
DO = 1; //寫1
Delayus(40); //延時,寫時隙不得低于60us
}
else
{
DO = 0; //產生寫時隙
Delayus(50); //延時,保持低約60us~120us
DO = 1;
i++;
}
byte_to_write = byte_to_write >> 1;
}
}
/*啟動溫度轉換*/
void StartConvert()
{
Resetpaulse(); // 發出復位脈沖,每次操作都從復位開始
delay(1);
Writebyte(0xcc); //skip room命令,跳過序列號命令字
Writebyte(0x44); //啟動溫度轉換命令
}
/*讀取溫度值*/
void ReadTempreture()
{
Resetpaulse(); // 發出復位脈沖,每次操作都從復位開始
delay(1);
Writebyte(0xcc); //skip room命令
Writebyte(0xbe); //讀取暫存器命令
temp_l = Readbyte(); //存儲溫度低字節值 (整數部分低四位和小數部分)
temp_h = Readbyte(); //存儲溫度高字節值 (其中高五位為符號位)
}
/*數據處理程序*/
void Digital_process()
{
uchar total = 0;
uchar low = 0;
uint dicimal = 0;
tempsign = (temp_h >> 7) & 0x01; //得出符號位
total = ((temp_h << 4)&0xf0) | ((temp_l >> 4)&0x0f); //取整數位
low = temp_l & 0x0f; //取小數位
if(tempsign == 0)
{
temp_integer[0] = total / 100 + '0'; //計算百、十、個位
temp_integer[1] = (total%100)/10 + '0';
temp_integer[2] = (total%100)%10 + '0';
temp_integer[3] = '\0';
/* if(temp_integer[0] == '0')
{
if(temp_integer[1] != '0')
{
temp_integer[0] = '\0'; //百位零消隱
}
else if(temp_integer[1] == '0')
{
temp_integer[0] = '\0'; //百位,十位零都消隱
temp_integer[1] = '\0';
}
} */
dicimal = low * 625; //計算小數
temp_dicimal[0] = dicimal / 1000 + '0'; //十分位
temp_dicimal[1] = dicimal % 1000 /100 + '0'; //百分位
temp_dicimal[2] = dicimal % 100 / 10 + '0'; //千分位
temp_dicimal[3] = dicimal % 10 + '0'; //萬分位
temp_dicimal[4] = '\0'; //數組加一個空字符(好像系統也會自動加上的)
}
else if(tempsign == 1) //負數處理
{
if(low == 0x00) //負數要取反加一再乘以0.0625就是實際溫度值了,我這里沒有設那么多int型變量,
{
total = ~total + 1; //所以就用了這么一個計算方法
low &= 0x0f;
} /*具體一點講,小數低四位為全零時取反加一要有進位,此時只要整數位取反加一即可,
小數位不用理會,其余情況整數位取反,小數位取反加一*/
else
{
total = ~total ;
low = (~low) + 1;
low &= 0x0f; //注意高四位要變成零
}
temp_integer[1] = (total%100)/10 + '0'; //計算十、個位
temp_integer[2] = (total%100)%10 + '0';
temp_integer[3] = '\0';
// if(temp_integer[1] == '0')
// {
// temp_integer[1] = '\0';
// }
dicimal = low * 625;
temp_dicimal[0] = dicimal / 1000 + '0';
temp_dicimal[1] = dicimal % 1000 /100 + '0';
temp_dicimal[2] = dicimal % 100 / 10 + '0';
temp_dicimal[3] = dicimal % 10 + '0';
temp_dicimal[4] = '\0';
}
}
void main()
{
bit palse = 0;
init();
gotoxy(0,2);
print("CHECKING...");
delay(300);
palse = Resetpaulse(); //檢測DS18B20是否響應
if(palse)
{
init();
gotoxy(0,3);
print("DS18B20 OK");
}
else
{
init();
gotoxy(0,3);
print("DS18B20 ERROR");
while(1);
}
while(1)
{
delay(1);
StartConvert();
delay(200);
ReadTempreture();
Digital_process();
if(tempsign == 0) //顯示正值溫度
{
gotoxy(1,0);
print("TEMP:");
print("+");
print(temp_integer);
print(".");
print(temp_dicimal);
}
else //顯示負值溫度
{
gotoxy(1,0);
print("TEMP:");
print("-");
print(temp_integer + 1);
print(".");
print(temp_dicimal);
}
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -