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
轉載于:https://www.cnblogs.com/wises/p/9539445.html