|
這是我在16F877,18F1320,18F1220上通過的18B20程序,18B20主要是延時問題,這個解決了,什么都可以通過。 [原作者沒有提供所使用的編譯器,由于是C程序,所以大同小異,建議使用時,確認是否與你的編譯器兼容] # include <pic18f1220.h># define uch unsigned char# define unint unsigned int# define DQ RB3//定義18B20數(shù)據(jù)端口 # define DQ_DIR TRISB3//定義18B20D口方向寄存器 # define W1_INPUT 1# define W1_OUTPUT 0# define FALSE 0# define TRUE !FALSE# define DQ_HIGH() DQ_DIR = W1_INPUT# define DQ_LOW() DQ = 0; DQ_DIR = W1_OUTPUTvoid delay(unint x){ unint d; d=x; while(--d) {;}}bit reset(void)//初始化18B20 { static bit presence;//定義一個應答信號 DQ_LOW(); delay(70);//置總線為低電平并保持至少480us DQ_HIGH();//等電阻拉高總線并保持15-60us delay(5); presence=DQ;//接受應答信號 delay(20);//延時60-240us return(presence);//返回應答信號 }//*************** 讀一位函數(shù)******************// bit read_bit(void){ static bit i; DQ_LOW(); DQ_LOW(); DQ_HIGH(); asm("nop"); asm("nop"); asm("nop"); i=DQ; delay(3); return(i);}//*********************寫一位函數(shù)****************// void write_bit(uch bitval){ DQ_LOW(); delay(1); if (bitval==1) { DQ_HIGH(); } delay(3); DQ_HIGH();}//************** 從18B20中讀一個字節(jié)**************// uch read_byte(void){ uch i; uch j; uch value=0; for (i=0;i<8;i++) { j=read_bit();//調(diào)讀位函數(shù) if (j)//如果是 1 置1 { value|=(0x01<<i);//先讀低位,再讀高位 asm("nop"); asm("nop"); asm("nop"); } }//否則置 0 return(value);}//*********************向18B20中 寫一個字節(jié)**************// void write_byte(uch val){ uch i; uch temp; for (i=0;i<8;i++) { temp=val>>i; temp&=0x01; write_bit(temp);//調(diào)寫位函數(shù) } asm("nop"); asm("nop"); asm("nop");}main(){ uch teml,temh; GIE=0; OSCCON=0X6E;//這是18F1320的頻率選擇寄存器 ADCON1=0X7F; do{ ; }while (reset()) ;//復位等待從機應答 write_byte(0XCC);//忽略ROM匹配 write_byte(0X44);//發(fā)送溫度轉(zhuǎn)化命令 delay(25000);//延時100-300us do { ; }while( reset());//再次復位,等待從機應答 write_byte(0XCC);//忽略ROM匹配 write_byte(0XBE);//發(fā)送讀溫度命令 teml =read_byte();//讀出溫度低8 temh=read_byte();//讀出溫度高8位 DQ_HIGH();//釋放總線 } |