|
#include<pic.h>
__CONFIG(0x1832);
//芯片配置字,看門狗關(guān),上電延時開,掉電檢測關(guān),低壓編程關(guān),加密,4M晶體HS振蕩
#define uch unsigned char //給unsigned char起別名 uch
# define DQ RA2 //定義18B20數(shù)據(jù)端口
# define DQ_DIR TRISA2 //定義18B20D口方向寄存器
# define DQ_HIGH() DQ_DIR =1 //設(shè)置數(shù)據(jù)口為輸入
# define DQ_LOW() DQ = 0; DQ_DIR = 0 //設(shè)置數(shù)據(jù)口為輸出
unsigned char TLV=0 ; //采集到的溫度高8位
unsigned char THV=0; //采集到的溫度低8位
unsigned char TZ=0; //轉(zhuǎn)換后的溫度值整數(shù)部分
unsigned char TX=0; //轉(zhuǎn)換后的溫度值小數(shù)部分
unsigned int wd; //轉(zhuǎn)換后的溫度值BCD碼形式
unsigned char shi; //整數(shù)十位
unsigned char ge; //整數(shù)個位
unsigned char shifen; //十分位
unsigned char baifen; //百分位
unsigned char qianfen; //千分位
unsigned char wanfen; //萬分位
unsigned char table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
//0-9的顯示代碼
//------------------------------------------------
//延時函數(shù)
void delay(char x,char y)
{
char z;
do{
z=y;
do{;}while(--z);
}while(--x);
}
//其指令時間為:7+(3*(Y-1)+7)*(X-1)如果再加上函數(shù)調(diào)用的call 指令、頁面設(shè)定、傳遞參數(shù)花掉的7 個指令。
//則是:14+(3*(Y-1)+7)*(X-1)。
//--------------------------------------------------
//結(jié)果顯示函數(shù)
void display()
{
TRISA=0X00; //設(shè)置A口全為輸出
PORTD=table[shi]; //顯示整數(shù)十位
PORTA=0x1f;
delay(10,70);
PORTD=table[ge]&0X7F; //顯示整數(shù)個位,并點亮小數(shù)點
PORTA=0x2f;
delay(10,70);
PORTD=table[shifen]; //顯示小數(shù)十分位
PORTA=0x37;
delay(10,70);
PORTD=table[baifen]; //顯示小數(shù)百分位
PORTA=0x3b;
delay(10,70);
PORTD=table[qianfen]; //顯示小數(shù)千分位
PORTA=0x3d;
delay(10,70);
PORTD=table[wanfen]; //顯示小數(shù)萬分位
PORTA=0x3e;
delay(10,70);
}
//------------------------------------------------
//系統(tǒng)初始化函數(shù)
void init()
{
ADCON1=0X07; //設(shè)置A口為普通數(shù)字口
TRISA=0X00; //設(shè)置A口方向為輸出
TRISD=0X00; //設(shè)置D口方向為輸出
}
//-----------------------------------------------
//復位DS18B20函數(shù)
reset(void)
{
char presence=1;
while(presence)
{
DQ_LOW() ; //主機拉至低電平
delay(2,70); //延時503us
DQ_HIGH(); //釋放總線等電阻拉高總線,并保持15~60us
delay(2,8); //延時70us
if(DQ==1) presence=1; //沒有接收到應答信號,繼續(xù)復位
else presence=0; //接收到應答信號
delay(2,60); //延時430us
}
}
//-----------------------------------------------
//寫18b20寫字節(jié)函數(shù)
void write_byte(uch val)
{
uch i;
uch temp;
for(i=8;i>0;i--)
{
temp=val&0x01; //最低位移出
DQ_LOW();
NOP();
NOP();
NOP();
NOP();
NOP(); //從高拉至低電平,產(chǎn)生寫時間隙
if(temp==1) DQ_HIGH(); //如果寫1,拉高電平
delay(2,7); //延時63us
DQ_HIGH();
NOP();
NOP();
val=val>>1; //右移一位
}
}
//------------------------------------------------
//18b20讀字節(jié)函數(shù)
uch read_byte(void)
{
uch i;
uch value=0; //讀出溫度
static bit j;
for(i=8;i>0;i--)
{
value>>=1;
DQ_LOW();
NOP();
NOP();
NOP();
NOP();
NOP();
NOP(); //6us
DQ_HIGH(); //拉至高電平
NOP();
NOP();
NOP();
NOP();
NOP(); //4us
j=DQ;
if(j) value|=0x80;
delay(2,7); //63us
}
return(value);
}
//-------------------------------------------------
//啟動溫度轉(zhuǎn)換函數(shù)
void get_temp()
{
int i;
DQ_HIGH();
reset(); //復位等待從機應答
write_byte(0XCC); //忽略ROM匹配
write_byte(0X44); //發(fā)送溫度轉(zhuǎn)化命令
for(i=20;i>0;i--)
{
display(); //調(diào)用多次顯示函數(shù),確保溫度轉(zhuǎn)換完成所需要的時間
}
reset(); //再次復位,等待從機應答
write_byte(0XCC); //忽略ROM匹配
write_byte(0XBE); //發(fā)送讀溫度命令
TLV=read_byte(); //讀出溫度低8
THV=read_byte(); //讀出溫度高8位
DQ_HIGH(); //釋放總線
TZ=(TLV>>4)|(THV<<4)&0X3f; //溫度整數(shù)部分
TX=TLV<<4; //溫度小數(shù)部分
if(TZ>100) TZ/100; //不顯示百位
ge=TZ%10;//個位 //整數(shù)部分個位
shi=TZ/10;//十位 //整數(shù)十位
wd=0;
if (TX & 0x80) wd=wd+5000;
if (TX & 0x40) wd=wd+2500;
if (TX & 0x20) wd=wd+1250;
if (TX & 0x10) wd=wd+625; //以上4條指令把小數(shù)部分轉(zhuǎn)換為BCD碼形式
shifen=wd/1000; //十分位
baifen=(wd%1000)/100; //百分位
qianfen=(wd%100)/10; //千分位
wanfen=wd%10; //萬分位
NOP();
}
//--------------------------------------------------
//豬函數(shù)
void main()
{
init(); //調(diào)用系統(tǒng)初始化函數(shù)
while(1)
{
get_temp(); //調(diào)用溫度轉(zhuǎn)換函數(shù)
display(); //調(diào)用結(jié)果顯示函數(shù)
}
}
|
|