这是我在16F877,18F1320,18F1220上通过的18B20程序,18B20主要是延时问题,这个解决了,什么都可以通过。
[原作者没有提供所使用的编译器,由于是C程序,所以大同小异,建议使用时,确认是否与你的编译器兼容]
#include <pic18f1220.h> #define uch unsigned char #define unint unsigned int #define DQ RB3//定义18B20数据端口 #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_OUTPUT void 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); //返回应答信号 } //*************** 读一位函数******************// 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); } //*********************写一位函数****************// void write_bit(uch bitval) { DQ_LOW(); delay(1); if (bitval == 1) { DQ_HIGH(); } delay(3); DQ_HIGH(); } //************** 从18B20中读一个字节**************// uch read_byte(void) { uch i; uch j; uch value = 0; for (i = 0; i < 8; i++) { j = read_bit(); //调读位函数 if (j) { //如果是 1 置1 value |= (0x01 << i); //先读低位,再读高位 asm("nop"); asm("nop"); asm("nop"); } }//否则置 0 return (value); } //*********************向18B20中 写一个字节**************// void write_byte(uch val) { uch i; uch temp; for (i = 0; i < 8; i++) { temp = val >> i; temp &= 0x01; write_bit(temp);//调写位函数 } 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);//发送温度转化命令 delay(25000);//延时100-300us do { ; } while (reset()); //再次复位,等待从机应答 write_byte(0XCC);//忽略ROM匹配 write_byte(0XBE);//发送读温度命令 teml = read_byte(); //读出温度低8 temh = read_byte(); //读出温度高8位 DQ_HIGH();//释放总线 }