?? 18b20.c
字號:
/********************************************/
#include"reg51.h"
#include "intrins.h"//預(yù)處理命令
#define uchar unsigned char //
#define uint unsigned int
#define DATA_OUT P0 //定義段碼數(shù)據(jù)輸出口
#define BIT P2 //定義位位碼數(shù)據(jù)輸出口
sbit DQ=P1^7; //定義DS18B20溫度傳感器的數(shù)據(jù)通信端口
unsigned char code seg[]={0xc0,0xf9,0xA4,0xB0,0x99,
0x92,0x82,0x0F8,0x80,0x90,0xFF};//定義數(shù)碼管段碼值(共陽)
unsigned char code bit_data[]={0X00,0X80,0X40,0XC0,
0X20,0XA0,0X60,0XE0};//定義數(shù)碼管位碼數(shù)據(jù)(經(jīng)3-8譯碼器譯碼產(chǎn)生位碼)
unsigned char data_seg[8]; //顯示緩存
/*
void delay2(void)//延時程序
{
unsigned char k,i;
for(i=0;i<5;i++)
for(k=0;k<50;k++);
}
*/
/***********18b20程序**************/
//11us延時函數(shù)//
void delay(uint t)
{for(;t>0;t--);}
//**********DS18B20復(fù)位函數(shù)************//
void ow_reset(void)
{char presence=1;
while(presence)
{
while(presence)
{ DQ=1;_nop_();_nop_();
DQ=0;//產(chǎn)生低電平的復(fù)位脈沖
delay(50);//延時550us
DQ=1; //經(jīng)過延時后,將數(shù)據(jù)線拉至高電平,等待66us
delay(10);//延時等待66us后發(fā)出存在脈沖
presence=DQ;
// delay(3);
}
delay(50);
presence=~DQ;//發(fā)出存在脈沖,是低電平,單片機(jī)檢測到低電平說明復(fù)位成功
}
// delay(20); //低電平持續(xù)220us
DQ=1;
}
//********DS18B20寫命令函數(shù)**********//
//向1-Write 總線上寫一個字節(jié)//
void write_byte(uchar val)
{ uchar i;
for (i=8;i>0;i--)//一個字節(jié)8位
{ DQ=1;_nop_();_nop_();//
DQ=0;_nop_();_nop_();_nop_();_nop_();_nop_();//將數(shù)據(jù)線從高電平拉至低電平,產(chǎn)生寫時序,延時5us,
DQ=val&0x01; //就是對數(shù)據(jù)線進(jìn)行采樣,如果相與后為0,DQ就為0,否則就為1
delay(6);//延時66us
val=val>>1; //右移一位
}
DQ=1;
delay(1);
}
//********DS18B20讀1字節(jié)函數(shù)**********//
uchar read_byte(void)
{ uchar i;
uchar value=0;
for(i=8;i>0;i--)
{ DQ=1;_nop_();_nop_();
value>>=1; //將讀取的溫度值移位
DQ=0; //高電平拉到低電平后至少維持1us
_nop_();_nop_();_nop_();_nop_();//至少維持1us
DQ=1;_nop_();_nop_();_nop_();_nop_();//拉到高電平產(chǎn)生讀時序,讀時序產(chǎn)生后DS18B20馬上就輸出溫度數(shù)據(jù)
if (DQ)value|=0x80;//這時DS18B20輸出數(shù)據(jù),如果輸出數(shù)據(jù)線DQ為1就發(fā)送1,為0就發(fā)送0
delay(6);//讀一位的時序至少維持60us以上然后再釋放總線拉到高電平
}
DQ=1;//讀完一個字節(jié)后就將數(shù)據(jù)線拉到高電平
return(value);//返回讀取的溫度數(shù)據(jù)
}
//*********讀出溫度函數(shù)*********//
void read_temp(void)
{ uchar j;
uint low,high,tempdata;
for(j=1;j<4;j++)
{ ow_reset();//總線復(fù)位
//Matching_ROM(j); //調(diào)用匹配函數(shù)
write_byte(0xcc);//跳過ROM
write_byte(0x44);//發(fā)轉(zhuǎn)換命令
delay(1);
ow_reset();
//Matching_ROM(j); //調(diào)用匹配函數(shù)
write_byte(0xcc);//跳過ROM
write_byte(0xbe); //發(fā)讀命令,就是從暫存器里把溫度數(shù)據(jù)讀出來的命令
low=read_byte();//溫度低8位
high=read_byte();//溫度高8位
high=high<<8;
tempdata=low+high;
tempdata=tempdata>>4;
data_seg[0]=tempdata/100;
data_seg[1]=tempdata%100/10;
data_seg[2]=tempdata%100%10;
/* temp_display[0]=1;
temp_display[2]=2;
temp_display[1]=2;
temp_display[2]=3;
*/
}
}
/**************DS18B20ROM匹配函數(shù)*****************/
/*
void Matching_ROM(unsigned char mux)
{
unsigned char i,*P;
if(mux==1) P=ROM1;
if(mux==2) P=ROM2;
if(mux==3) P=ROM3;
write_byte(0x55);
for(i=0;i<8;i++)
{write_byte(*(P+i));}
}*/
void main(void)
{
unsigned char m;
while(1)
{
for(m=0;m<3;m++) //
{
DATA_OUT=seg[data_seg[m]]; //將顯示緩存數(shù)據(jù)轉(zhuǎn)換成數(shù)碼管段碼數(shù)據(jù)輸出
BIT =bit_data[m]; //位碼輸出
read_temp();
DATA_OUT=0XFF; //去消隱
}
}
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -