1 //调试过程:单总线对时序的要求真的是相当的精确,调试的时候//要仔细测试延 2 3 时的时间 4 5 //其中包括: 6 7 //1、复位的时序,延时时间为480us~960us之间,若没有应答信号//,那肯定是延 8 9 时不够精确; 10 11 //2、读写时序:45us的延时很是要命啊; 12 13 //3、还要注意初始化后的延时和温度的转换时间。 14 15 16 #define DS18B20_EXT 17 #include "includes.h" 18 19 20 /******************************************************************/ 21 /* 延时函数 */ 22 /******************************************************************/ 23 void delay(unsigned int i)//延时函数 24 { 25 while(i--) 26 { 27 __nop(); 28 } 29 30 } 31 /******************************************************************/ 32 /* 初始化 */ 33 /******************************************************************/ 34 /*void DS18B20Init() 35 { 36 IOCON_PIO2_2 &=0xf0; 37 GPIO2DIR |=0x04; 38 }*/ 39 40 void Init_DS18B20(void) 41 { 42 unsigned char VAR = 250,VARIABLE1=0,VARIABLE2,err; 43 GPIO2DIR_out(); 44 //while(VAR--) 45 //{ 46 DQ1(); //DQ复位 47 delay(2); //稍做延时 48 DQ0(); //单片机将DQ拉低 49 delay(900); //精确延时 大于 480us 此为506us左右 50 DQ1(); //拉高总线 51 delay(2); 52 DQ0(); 53 delay(900); 54 DQ1(); 55 GPIO2DIR_in(); 56 delay(100); 57 while(~DQ); 58 // delay(100); //稍做延时 59 // DQ0(); //单片机将DQ拉低 60 // delay(900); //精确延时 大于 480us 此为520us左右 61 // DQ1(); //拉高总线 62 // delay(100); //稍做延时 63 // DQ0(); //单片机将DQ拉低 64 // delay(900); //精确延时 大于 480us 此为520us左右 65 //} 66 // DQ1(); //拉高总线 67 //GPIO2DIR_in(); 68 //delay(100); 69 // VARIABLE1=DQ ; //稍做延时后 如果x=0则初始化成功 x=1则初始 70 71 化失败 72 //VARIABLE2=VARIABLE1; 73 //DQ1(); 74 /*while(VARIABLE2!=0) 75 { 76 delay(10); 77 err++; 78 if(err==20) 79 { 80 return ; 81 } 82 }*/ 83 /*if(!(GPIO2DATA&0x00000004)) 84 { 85 x=1; 86 } 87 delay(5); */ 88 } 89 /******************************************************************/ 90 /* 读一个字节 */ 91 /******************************************************************/ 92 unsigned char ReadOneChar(void) 93 { 94 unsigned char i=0; 95 unsigned char dat = 0; 96 unsigned char wonder=8; 97 98 for (i=8;i>0;i--) 99 { 100 dat>>=1; 101 GPIO2DIR_out(); 102 DQ0(); // 给脉冲信号 103 delay(2); //10us 104 DQ1(); // 给脉冲信号 105 GPIO2DIR_in(); 106 //delay(1000); 107 if(DQ_BACK_1()) 108 dat|=0x80; 109 //delay(wonder); //16us 110 delay(41); // 45us 111 } 112 //delay(1000); 113 return(dat); 114 } 115 /******************************************************************/ 116 /* 写一个字节 */ 117 /******************************************************************/ 118 void WriteOneChar(unsigned char dat) 119 { 120 unsigned char i=0; 121 GPIO2DIR_out(); 122 123 for (i=8; i>0; i--) 124 { 125 DQ0(); 126 __nop(); 127 __nop(); 128 if(dat&0x01) 129 DQ1(); 130 else 131 DQ0(); 132 delay(41); // 45us 133 DQ1(); 134 dat>>=1; 135 } 136 //delay(1000); 137 138 } 139 /******************************************************************/ 140 /* 读取温度 */ 141 /******************************************************************/ 142 unsigned int ReadTemperature(void) 143 { 144 unsigned char a=0; 145 unsigned int b=0; 146 unsigned int t=0; 147 Init_DS18B20(); 148 149 __nop();__nop(); 150 //delay(1000); 151 //delay(1000); 152 WriteOneChar(0xCC); // 跳过读序号列号的操作 153 __nop();__nop(); 154 WriteOneChar(0x44); // 启动温度转换 (12位精度的最大 155 156 转化时间为 750ms ) 157 158 delay(500000); //注意要等温度转换完成再读取,要不初始值会出错 159 delay(500000); // 160 Init_DS18B20(); 161 __nop();__nop(); 162 //delay(1000); 163 delay(1000); 164 WriteOneChar(0xCC); //跳过读序号列号的操作 165 __nop();__nop(); 166 WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个 167 168 就是温度 169 __nop();__nop(); 170 a=ReadOneChar(); //低位 171 __nop();__nop(); 172 b=ReadOneChar(); //高位 173 b<<=8; 174 t=a+b; 175 return(t); 176 177 }