1 /* 首先對其先進行頭文件的定義以及端口的定義 2 然后進行函數體的寫,先寫 ds18b20的初始化,然后寫其 寫字節, 編寫讀ds18B20 3 繼續寫溫度轉換函數模塊,因為轉換模塊的結果放在了寄存器中,所以在寫從寄存器中將 4 轉換后的溫度讀出來 要有返回值 並且為兩個字節 所以為 int 類型再讀之前必須先將其讀取寄存器的指令寫入; 先讀低字節,再讀高字節 5 然后在命名一個變量用來將這兩個字節進行組合,temp=tmh; temp|=tml; return temp; 這就將這兩個字節進行組合 6 當得到這個數據之后,然后進行判斷高5位是正溫度還是負溫度,然后還要這個溫度*0.0625才可以的都真正的溫度*/ 7 8 #include"temp.h" 9 /******************************************************************************* 10 * 函 數 名 : Delay1ms 11 * 函數功能 : 延時函數 12 * 輸 入 : 無 13 * 輸 出 : 無 14 *******************************************************************************/ 15 16 void Delay1ms(uint y) 17 { 18 uint x; 19 for( ; y>0; y--) 20 { 21 for(x=110; x>0; x--); 22 } 23 } 24 /******************************************************************************* 25 * 函 數 名 : Ds18b20Init 26 * 函數功能 : 初始化 27 * 輸 入 : 無 28 * 輸 出 : 初始化成功返回1,失敗返回0 29 *******************************************************************************/ 30 31 uchar Ds18b20Init() 32 { 33 uchar i; 34 DSPORT = 0; //將總線拉低480us~960us 35 i = 70; 36 while(i--);//延時642us 37 DSPORT = 1; //然后拉高總線,如果DS18B20做出反應會將在15us~60us后總線拉低 38 i = 0; 39 while(DSPORT) //等待DS18B20拉低總線 40 { 41 Delay1ms(1); //這里的延時必須要大於480uS 42 i++; 43 if(i>5)//等待>5MS 44 { 45 return 0;//初始化失敗 46 } 47 48 } 49 return 1;//初始化成功 50 } 51 52 /******************************************************************************* 53 * 函 數 名 : Ds18b20WriteByte 54 * 函數功能 : 向18B20寫入一個字節 55 * 輸 入 : 無 56 * 輸 出 : 無 57 *******************************************************************************/ 58 59 void Ds18b20WriteByte(uchar dat) 60 { 61 uint i, j; 62 63 for(j=0; j<8; j++) 64 { 65 DSPORT = 0; //每寫入一位數據之前先把總線拉低1us 66 i++; 67 DSPORT = dat & 0x01; //然后寫入一個數據,從最低位開始 68 i=6; 69 while(i--); //延時68us,持續時間最少60us 70 DSPORT = 1; //然后釋放總線,至少1us給總線恢復時間才能接着寫入第二個數值 71 dat >>= 1; 72 } 73 } 74 /******************************************************************************* 75 * 函 數 名 : Ds18b20ReadByte 76 * 函數功能 : 讀取一個字節 77 * 輸 入 : 無 78 * 輸 出 : 無 79 *******************************************************************************/ 80 81 82 uchar Ds18b20ReadByte() 83 { 84 uchar byte, bi; 85 uint i, j; 86 for(j=8; j>0; j--) 87 { 88 DSPORT = 0;//先將總線拉低1us 89 i++; 90 DSPORT = 1;//然后釋放總線 91 i++; 92 i++;//延時6us等待數據穩定 93 bi = DSPORT; //讀取數據,從最低位開始讀取 94 /*將byte左移一位,然后與上右移7位后的bi,注意移動之后移掉那位補0。*/ 95 byte = (byte >> 1) | (bi << 7); //byte首先為0, 若bi=1時, 左移7位 則 1000 0000,和byte=0000 0000相或,則byte為 1000 0000;當DSPORT下一位過來時,假設為1時,則之前byte=1000 0000右移一位之后為byte =0100 0000,bi=1,左移七位,則bi=1000 0000和byte相或為1100 0000依次傳輸完8位 96 i = 4; //讀取完之后等待48us再接着讀取下一個數 97 while(i--); 98 } 99 return byte; 100 } 101 /******************************************************************************* 102 * 函 數 名 : Ds18b20ChangTemp 103 * 函數功能 : 讓18b20開始轉換溫度 104 * 輸 入 : 無 105 * 輸 出 : 無 106 *******************************************************************************/ 107 108 void Ds18b20ChangTemp() 109 { 110 Ds18b20Init(); 111 Delay1ms(1); 112 Ds18b20WriteByte(0xcc); //跳過ROM操作命令 113 Ds18b20WriteByte(0x44); //溫度轉換命令 按理說要加750mS的延時,如果不加就會出現閃爍 114 //Delay1ms(100); //等待轉換成功,而如果你是一直刷着的話,就不用這個延時了 115 116 } 117 /******************************************************************************* 118 * 函 數 名 : Ds18b20ReadTempCom 119 * 函數功能 : 發送讀取溫度命令 120 * 輸 入 : 無 121 * 輸 出 : 無 122 *******************************************************************************/ 123 124 void Ds18b20ReadTempCom() 125 { 126 127 Ds18b20Init(); 128 Delay1ms(1); 129 Ds18b20WriteByte(0xcc); //跳過ROM操作命令 130 Ds18b20WriteByte(0xbe); //發送讀取溫度命令 131 } 132 /******************************************************************************* 133 * 函 數 名 : Ds18b20ReadTemp 134 * 函數功能 : 讀取溫度 135 * 輸 入 : 無 136 * 輸 出 : 無 137 *******************************************************************************/ 138 139 int Ds18b20ReadTemp() 140 { 141 int temp = 0; 142 uchar tmh, tml; 143 Ds18b20ChangTemp(); //先寫入轉換命令 144 Ds18b20ReadTempCom(); //然后等待轉換完后發送讀取溫度命令 145 tml = Ds18b20ReadByte(); //讀取溫度值共16位,先讀低字節 146 tmh = Ds18b20ReadByte(); //再讀高字節 147 temp = tmh; 148 temp <<= 8; 149 temp |= tml; 150 return temp; 151 } 152 153 154 155 /************************************************************************************** 156 * DS18B20溫度傳感器實驗 * 157 實現現象:下載程序后,在溫度傳感器接口處,按照絲印方向插好溫度傳感器,數碼管就會顯示 158 檢測的溫度值, 159 注意事項: 160 ***************************************************************************************/ 161 162 #include "reg52.h" //此文件中定義了單片機的一些特殊功能寄存器 163 #include"temp.h" 164 165 typedef unsigned int u16; //對數據類型進行聲明定義 166 typedef unsigned char u8; 167 168 sbit LSA=P2^2; 169 sbit LSB=P2^3; 170 sbit LSC=P2^4; 171 172 173 char num=0; 174 u8 DisplayData[8]; 175 u8 code smgduan[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; 176 177 /******************************************************************************* 178 * 函 數 名 : delay 179 * 函數功能 : 延時函數,i=1時,大約延時10us 180 *******************************************************************************/ 181 void delay(u16 i) 182 { 183 while(i--); 184 } 185 186 187 /******************************************************************************* 188 * 函 數 名 : datapros() 189 * 函數功能 : 溫度讀取處理轉換函數 190 * 輸 入 : temp 191 * 輸 出 : 無 192 *******************************************************************************/ 193 194 void datapros(int temp) 195 { 196 float tp; 197 if(temp< 0) //當溫度值為負數 198 { 199 DisplayData[0] = 0x40; // - 表示“-”號 200 //因為讀取的溫度是實際溫度的補碼,所以減1,再取反求出原碼 201 temp=temp-1; 202 temp=~temp; 203 tp=temp; 204 temp=tp*0.0625*100+0.5; //*100是為了放大100倍,去掉后面的兩個小數 205 //留兩個小數點就*100,+0.5是四舍五入,因為C語言浮點數轉換為整型的時候把小數點 206 //后面的數自動去掉,不管是否大於0.5,而+0.5之后大於0.5的就是進1了,小於0.5的就 207 //算加上0.5,還是在小數點后面。 208 209 } 210 else 211 { 212 DisplayData[0] = 0x00; 213 tp=temp;//因為數據處理有小數點所以將溫度賦給一個浮點型變量 214 //如果溫度是正的那么,那么正數的原碼就是補碼它本身 215 temp=tp*0.0625*100+0.5; 216 //留兩個小數點就*100,+0.5是四舍五入,因為C語言浮點數轉換為整型的時候把小數點 217 //后面的數自動去掉,不管是否大於0.5,而+0.5之后大於0.5的就是進1了,小於0.5的就 218 //算加上0.5,還是在小數點后面。 219 } 220 DisplayData[1] = smgduan[temp / 10000]; //因為溫度在-50——125之間,這是三位,后面有*100,所以變成了五位了 221 DisplayData[2] = smgduan[temp % 10000 / 1000]; 222 DisplayData[3] = smgduan[temp % 1000 / 100] | 0x80;//為了讓個位數碼管的小數點也亮 223 DisplayData[4] = smgduan[temp % 100 / 10];//小數點倒數第二位 224 DisplayData[5] = smgduan[temp % 10];//小數點最后一位 225 } 226 227 228 /******************************************************************************* 229 * 函數名 :DigDisplay() 230 * 函數功能 :數碼管顯示函數 231 * 輸入 : 無 232 * 輸出 : 無 233 *******************************************************************************/ 234 void DigDisplay() 235 { 236 u8 i; 237 for(i=0;i<6;i++) 238 { 239 switch(i) //位選,選擇點亮的數碼管, 240 { 241 case(0): 242 LSA=0;LSB=0;LSC=0; break;//顯示第0位 243 case(1): 244 LSA=1;LSB=0;LSC=0; break;//顯示第1位 245 case(2): 246 LSA=0;LSB=1;LSC=0; break;//顯示第2位 247 case(3): 248 LSA=1;LSB=1;LSC=0; break;//顯示第3位 249 case(4): 250 LSA=0;LSB=0;LSC=1; break;//顯示第4位 251 case(5): 252 LSA=1;LSB=0;LSC=1; break;//顯示第5位 253 } 254 P0=DisplayData[5-i];//發送數據 255 delay(100); //間隔一段時間掃描 256 P0=0x00;//消隱 257 } 258 } 259 260 /******************************************************************************* 261 * 函 數 名 : main 262 * 函數功能 : 主函數 263 * 輸 入 : 無 264 * 輸 出 : 無 265 *******************************************************************************/ 266 void main() 267 { 268 while(1) 269 { 270 datapros(Ds18b20ReadTemp()); //數據處理函數 271 DigDisplay();//數碼管顯示函數 272 } 273 } 274 275 276 277 #ifndef __TEMP_H_ 278 #define __TEMP_H_ 279 280 #include<reg52.h> 281 //---重定義關鍵詞---// 282 #ifndef uchar 283 #define uchar unsigned char 284 #endif 285 286 #ifndef uint 287 #define uint unsigned int 288 #endif 289 290 //--定義使用的IO口--// 291 sbit DSPORT=P3^7; 292 293 //--聲明全局函數--// 294 void Delay1ms(uint ); 295 uchar Ds18b20Init(); 296 void Ds18b20WriteByte(uchar com); 297 uchar Ds18b20ReadByte(); 298 void Ds18b20ChangTemp(); 299 void Ds18b20ReadTempCom(); 300 int Ds18b20ReadTemp(); 301 302 #endif