溫度傳感器程序編寫


  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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM