日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當前位置:首頁 > 單片機 > 單片機
[導讀]本文介紹了利用PIC16F877A驅(qū)動DS18B20溫度采集芯片。

本文介紹了利用PIC16F877A驅(qū)動DS18B20溫度采集芯片。

 DS18B20的內(nèi)部結(jié)構(gòu)

DS18B20內(nèi)部結(jié)構(gòu)主要由四部分組成:64位光刻ROM、溫度傳感器、非揮發(fā)的溫度報警觸發(fā)器TH和TL、配置寄存器。DS18B20的管腳排列如下:

DQ為數(shù)字信號輸入/輸出端;GND為電源地;VDD為外接供電電源輸入端(在寄生電源接線方式時接地)。

光刻ROM中的64位序列號是出廠前被光刻好的,它可以看作是該DS18B20的地址序列碼。64位光刻ROM的排列是:開始8位(28H)是產(chǎn)品類型標號,接著的48位是該DS18B20自身的序列號,最后8位是前面56位的循環(huán)冗余校驗碼(CRC=X8+X5+X4+1)。光刻ROM的作用是使每一個DS18B20都各不相同,這樣就可以實現(xiàn)一根總線上掛接多個DS18B20的目的。

DS18B20中的溫度傳感器可完成對溫度的測量,以12位轉(zhuǎn)化為例:用16位符號擴展的二進制補碼讀數(shù)形式提供,以0.0625℃/LSB形式表達,其中S為符號位。

這是12位轉(zhuǎn)化后得到的12位數(shù)據(jù),存儲在18B20的兩個8比特的RAM中,二進制中的前面5位是符號位,如果測得的溫度大于0,這5位為0,只要將測到的數(shù)值乘于0.0625即可得到實際溫度;如果溫度小于0,這5位為1,測到的數(shù)值需要取反加1再乘于0.0625即可得到實際溫度。

例如+125℃的數(shù)字輸出為07D0H,+25.0625℃的數(shù)字輸出為0191H,-25.0625℃的數(shù)字輸出為FF6FH,-55℃的數(shù)字輸出為FC90H。

DS18B20溫度傳感器的存儲器

DS18B20溫度傳感器的內(nèi)部存儲器包括一個高速暫存RAM和一個非易失性的可電擦除的E2RAM,后者存放高溫度和低溫度觸發(fā)器TH、TL和結(jié)構(gòu)寄存器。

暫存存儲器包含了8個連續(xù)字節(jié),前兩個字節(jié)是測得的溫度信息,第一個字節(jié)的內(nèi)容是溫度的低八位,第二個字節(jié)是溫度的高八位。第三個和第四個字節(jié)是TH、TL的易失性拷貝,第五個字節(jié)是結(jié)構(gòu)寄存器的易失性拷貝,這三個字節(jié)的內(nèi)容在每一次上電復位時被刷新。第六、七、八個字節(jié)用于內(nèi)部計算。第九個字節(jié)是冗余檢驗字節(jié)。

該字節(jié)各位的意義如下:

TM R1 R0 1 1 1 1 1

低五位一直都是1 ,TM是測試模式位,用于設置DS18B20在工作模式還是在測試模式。在DS18B20出廠時該位被設置為0,用戶不要去改動。R1和R0用來設置分辨率,如下表所示:(DS18B20出廠時被設置為12位)

分辨率設置表:

根據(jù)DS18B20的通訊協(xié)議,主機控制DS18B20完成溫度轉(zhuǎn)換必須經(jīng)過三個步驟:每一次讀寫之前都要對DS18B20進行復位,復位成功后發(fā)送一條ROM指令,最后發(fā)送RAM指令,這樣才能對DS18B20進行預定的操作。復位要求主CPU將數(shù)據(jù)線下拉500微秒,然后釋放,DS18B20收到信號后等待16~60微秒左右,后發(fā)出60~240微秒的存在低脈沖,主CPU收到此信號表示復位成功。

DS1820使用中注意事項

DS1820雖然具有測溫系統(tǒng)簡單、測溫精度高、連接方便、占用口線少等優(yōu)點,但在實際應用中也應注意以下幾方面的問題:

(1)較小的硬件開銷需要相對復雜的軟件進行補償,由于DS1820與微處理器間采用串行數(shù)據(jù)傳送,因此,在對DS1820進行讀寫編程時,必須嚴格的保證讀寫時序,否則將無法讀取測溫結(jié)果。在使用PL/M、C等高級語言進行系統(tǒng)程序設計時,對DS1820操作部分最好采用匯編語言實現(xiàn)。

(2)在DS1820的有關資料中均未提及單總線上所掛DS1820數(shù)量問題,容易使人誤認為可以掛任意多個DS1820,在實際應用中并非如此。當單總線上所掛DS1820超過8個時,就需要解決微處理器的總線驅(qū)動問題,這一點在進行多點測溫系統(tǒng)設計時要加以注意。

(3)連接DS1820的總線電纜是有長度限制的。試驗中,當采用普通信號電纜傳輸長度超過50m時,讀取的測溫數(shù)據(jù)將發(fā)生錯誤。當將總線電纜改為雙絞線帶屏蔽電纜時,正常通訊距離可達150m,當采用每米絞合次數(shù)更多的雙絞線帶屏蔽電纜時,正常通訊距離進一步加長。這種情況主要是由總線分布電容使信號波形產(chǎn)生畸變造成的。因此,在用DS1820進行長距離測溫系統(tǒng)設計時要充分考慮總線分布電容和阻抗匹配問題。

(4)在DS1820測溫程序設計中,向DS1820發(fā)出溫度轉(zhuǎn)換命令后,程序總要等待DS1820的返回信號,一旦某個DS1820接觸不好或斷線,當程序讀該DS1820時,將沒有返回信號,程序進入死循環(huán)。這一點在進行DS1820硬件連接和軟件設計時也要給予一定的重視。

經(jīng)過1天半的奮戰(zhàn)終于完成了DS18B20組網(wǎng)的驅(qū)動!不過只是兩點的組網(wǎng),不過多點組網(wǎng)應該也不存在技術上難題!

下面是驅(qū)動程序

頭文件

#ifndef DS18B20_H

#define DS18B20_H

#include "main.h"

//define port and port direction registor

#define Dout RD0

#define DoutDir TRISD0

//define command word

#define ROM_READ 0x33

#define ROM_MATCH 0x55

#define ROM_SKIP 0xCC

#define ROM_SERCH 0xF0

#define ROM_ALARM 0xEC

#define MEM_WRITE 0x4E

#define MEM_READ 0xBE

#define MEM_COPY 0x48

#define MEM_CONVERT 0x44

#define MEM_RECALL 0xB8

#define POWER_READ 0xB4

//define function

void configure_ds18b20(uchar flag) ;//configure the accuration of thermometer

uchar init_ds18b20() ;//初始化ds18b20

uchar read_ds18b20() ;//read a byte from ds18b20

void write_ds18b20(uchar data) ;//write a byte to ds18b20

void get_sequence(uchar *seq) ;//acquire the rom sequence of ds18b20

char get_configure() ;//acquire the configuration of accuration of thermometer

uint get_temp() ;//capture temperature from ds18b20

float process_temp(uint data) ;//process the return value of the get_temp function

void start_convert() ;//start thermometer convert

uint read_temp() ;

void match_rom(uchar data[8]) ;

uint test(const uchar *data) ;//read temperature from ds18b20 specified by data

#endif

子程序

#include "ds18b20.h"

const char crc_code[256]={

0, 94, 188, 226, 97, 63, 221, 131, 194, 156, 126, 32, 163, 253, 31, 65,

157, 195, 33, 127, 252, 162, 64, 30, 95, 1, 227, 189, 62, 96, 130, 220,

35, 125, 159, 193, 66, 28, 254, 160, 225, 191, 93, 3, 128, 222, 60, 98,

190, 224, 2, 92, 223, 129, 99, 61, 124, 34, 192, 158, 29, 67, 161, 255,

70, 24, 250, 164, 39, 121, 155, 197, 132, 218, 56, 102, 229, 187, 89, 7,

219, 133, 103, 57, 186, 228, 6, 88, 25, 71, 165, 251, 120, 38, 196, 154,

101, 59, 217, 135, 4, 90, 184, 230, 167, 249, 27, 69, 198, 152, 122, 36,

248, 166, 68, 26, 153, 199, 37, 123, 58, 100, 134, 216, 91, 5, 231, 185,

140, 210, 48, 110, 237, 179, 81, 15, 78, 16, 242, 172, 47, 113, 147, 205,

17, 79, 173, 243, 112, 46, 204, 146, 211, 141, 111, 49, 178, 236, 14, 80,

175, 241, 19, 77, 206, 144, 114, 44, 109, 51, 209, 143, 12, 82, 176, 238,

50, 108, 142, 208, 83, 13, 239, 177, 240, 174, 76, 18, 145, 207, 45, 115,

202, 148, 118, 40, 171, 245, 23, 73, 8, 86, 180, 234, 105, 55, 213, 139,

87, 9, 235, 181, 54, 104, 138, 212, 149, 203, 41, 119, 244, 170, 72, 22,

233, 183, 85, 11, 136, 214, 52, 106, 43, 117, 151, 201, 74, 20, 246, 168,

116, 42, 200, 150, 21, 75, 169, 247, 182, 232, 10, 84, 215, 137, 107, 53

};

uchar init_ds18b20()

{

uchar temp=0 ;

DoutDir=0 ;

Dout=1 ;

DelayUs(1) ;

Dout=0 ;

DelayUs(600) ;

Dout=1 ;

DoutDir=1 ;

while(Dout) ;

while(!Dout) ///這里使用了超時設置

{

DelayUs(24)

if(temp==10)

{

if(Dout)

{

DoutDir=0 ;

return 1 ;

}

else

{

return 0 ;

}

}

temp++ ;

}

DoutDir=0 ;

return 1 ;

}

uchar read_ds18b20()

{

uchar temp,i ;

temp= 0 ;

DoutDir=0 ;

for(i=0;i<8;i++)

{

Dout=1 ;

DelayUs(1) ;

temp=temp>>1 ;

Dout=0 ;

DelayUs(1) ;

Dout=1 ;

DoutDir=1 ;

DelayUs(8) ;

if(Dout)

temp=temp|0x80 ;

DelayUs(60) ;

DoutDir=0 ;

}

Dout=1 ;

return temp ;

}

void write_ds18b20(uchar data)

{

uchar temp ,i ;

DoutDir=0 ;

for(i=0;i<8;i++)

{

temp=data&0x01 ;

if(temp)

{

Dout=0 ;

DelayUs(2) ;

Dout=1 ;

DelayUs(57) ;

}

else

{

Dout=0 ;

DelayUs(57) ;

Dout=1 ;

DelayUs(2) ;

}

data=data>>1 ;

}

Dout=1 ;

}

uint get_temp()

{

uchar th,tl ;

uint temp ;

th=0 ;

tl=0 ;

init_ds18b20() ;

write_ds18b20(ROM_SKIP) ;

write_ds18b20(MEM_CONVERT) ;

init_ds18b20() ;

write_ds18b20(ROM_SKIP) ;

write_ds18b20(MEM_READ) ;

tl=read_ds18b20() ;

th=read_ds18b20() ;

if(!(th&0xf0))

{

th=th&07 ;

temp=th*256+tl ;

return temp ;

}

else

{ th=th&0x07 ;

temp=th*256 +tl ;

return temp ;

}

}

void get_sequence(uchar *seq)

{

uchar i ;

uchar *temp ;

temp=seq ;

init_ds18b20() ;

write_ds18b20(ROM_READ) ;

for(i=0;i<8;i++)

{

*temp++=read_ds18b20() ;

}

return ;

}

char get_configure()

{

char temp,i ;

i=0 ;

init_ds18b20() ;

write_ds18b20(ROM_SKIP) ;

write_ds18b20(MEM_READ) ;

temp=0 ;

while(++i)

{

temp=read_ds18b20() ;

if(i==5)

return temp ;

}

}

float process_temp(uint data)

{

return data*0.0625 ;

}

void configure_ds18b20(uchar flag)

{

uchar tmp1,tmp2 ;

init_ds18b20() ;

write_ds18b20(ROM_SKIP) ;

write_ds18b20(MEM_READ) ;

tmp1=read_ds18b20() ;

tmp2=read_ds18b20() ;

tmp1=read_ds18b20() ;//get TH

tmp2=read_ds18b20() ;//get Tl

init_ds18b20() ;// reset bus

write_ds18b20(ROM_SKIP) ;//skip rom

write_ds18b20(MEM_WRITE) ;//write command

write_ds18b20(tmp1) ;//

write_ds18b20(tmp2) ;//

switch(flag)

{

case 0 :

write_ds18b20(0x1F) ;

break ;

case 1 :

write_ds18b20(0x3F) ;

break ;

case 2 :

write_ds18b20(0x5F) ;

break ;

case 3 :

write_ds18b20(0x7F) ;

break ;

default :

write_ds18b20(0x1F) ;

break ;

}

init_ds18b20() ;//reset bus

write_ds18b20(ROM_SKIP) ;//skip rom

write_ds18b20(MEM_COPY) ;//copy ram to eeprom

write_ds18b20(MEM_RECALL) ;//recopy eeprom to ram

}

uchar crc_check(uchar *data)

{

uchar temp ,i;

uchar *p=data ;

//complement ;

temp=0 ;

for(i=0;i<7;i++)

{

temp=crc_code[temp^*p] ;

p++ ;

}

if(temp==data[7])

return 1 ;

else

return 0 ;

}

void start_convert()

{

init_ds18b20() ;

write_ds18b20(ROM_SKIP) ;

write_ds18b20(MEM_CONVERT) ;

}

uint read_temp()

{

uchar tl,th ;

uint temp ;

tl=0 ;

th=0 ;

// init_ds18b20() ;

// write_ds18b20(0xcc) ;//note that don't skip rom command here ;

write_ds18b20(MEM_READ) ;

tl=read_ds18b20() ;

th=read_ds18b20() ;

if(!(th&0xf0))

{

th=th&07 ;

temp=th*256+tl ;

return temp ;

}

else

{ th=th&0x07 ;

temp=th*256 +tl ;

return temp ;

}

}

void match_rom(uchar data[8])

{

//uchar *temp=data ;

uchar i ;

init_ds18b20() ;

write_ds18b20(ROM_MATCH) ;

for(i=0;i<8;i++)

write_ds18b20(data[i]) ;

}

uint test(const uchar *data)//注意這里一定要用const關鍵字

{

uint temp ;

uchar t,tl,th;

tl=0 ;

th=0 ;

// start_convert() ;

init_ds18b20() ;

write_ds18b20(ROM_MATCH) ;

for(t=0;t<8;t++)

{

write_ds18b20(*data++) ;

}

write_ds18b20(MEM_READ) ;

tl=read_ds18b20() ;

th=read_ds18b20() ;

if(!(th&0xf0))

{

th=th&07 ;

temp=th*256+tl ;

return temp ;

}

else

{ th=th&0x07 ;

temp=th*256 +tl ;

return temp ;

}

}

主程序

#include

#include

#include "main.h"

#include "t232.h"

#include "ds18b20.h"

const uchar rom1[8]={0x28,0x94,0xB8,0x1A,0x02,0x00,0x00,0x6E} ;

const uchar rom2[8]={0x28,0x4B,0xE6,0x1A,0x02,0x00,0x00,0xB9} ;

void init_all()

{

asm("clrwdt");

init_232() ;

}

void main()

{

const char str[]="hello world!" ;

uchar dat[16],td;

uint data[2] ;

init_all() ;

//get ID of DS18b20

// init_ds18b20() ;

// write_ds18b20(0x33) ;

//for(t=0;t<8;t++)

//{

// td=read_ds18b20() ;

// put_char(td) ;

//}

//configure_ds18b20(3) ;//configure the accuration of thermometer

//td=get_configure() ;

//put_char(td) ;

while(1)

{

start_convert() ;

data[0]=test(rom1) ;

data[1]=test(rom2) ;

DelayMs(70) ;

sprintf(dat,"temp1 %d temp2 %d",data[0],data[1]) ;

send_str(dat) ;

}

}

使用DS18B20中容易出現(xiàn)的問題:

1、讀出的溫度值不變,可能是硬件方面的問題,使用寄生電源方式很容易出現(xiàn)這種問題!建議使用獨立電源供電,同時別忘了接4.7K上拉電阻 ;

2、DS18B20讀寫時序很重要,其實驅(qū)動DS18B20只需要寫好三個函數(shù)就可以了,一個初始化函數(shù),一個讀字節(jié)函數(shù),一個寫字節(jié)函數(shù),如果這兩個函數(shù)驗證通過了,你也就成功了一半了,DS18B20的其他功能均是封裝這3個函數(shù)來實現(xiàn)的!只需要按照功能的使用命令即可!

本站聲明: 本文章由作者或相關機構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

8位單片機在嵌入式設計領域已經(jīng)成為半個多世紀以來的主流選擇。盡管嵌入式系統(tǒng)市場日益復雜,8位單片機依然不斷發(fā)展,積極應對新的挑戰(zhàn)和系統(tǒng)需求。如今,Microchip推出的8位PIC?和AVR?單片機系列,配備了先進的獨立...

關鍵字: 單片機 嵌入式 CPU

在嵌入式系統(tǒng)開發(fā)中,程序燒錄是連接軟件設計與硬件實現(xiàn)的關鍵環(huán)節(jié)。當前主流的單片機燒錄技術已形成ICP(在電路編程)、ISP(在系統(tǒng)編程)、IAP(在應用編程)三大技術體系,分別對應開發(fā)調(diào)試、量產(chǎn)燒錄、遠程升級等不同場景。...

關鍵字: 單片機 ISP ICP IAP 嵌入式系統(tǒng)開發(fā)

在嵌入式系統(tǒng)開發(fā)中,看門狗(Watchdog Timer, WDT)是保障系統(tǒng)可靠性的核心組件,其初始化時機的選擇直接影響系統(tǒng)抗干擾能力和穩(wěn)定性。本文從硬件架構(gòu)、軟件流程、安全規(guī)范三個維度,系統(tǒng)分析看門狗初始化的最佳實踐...

關鍵字: 單片機 看門狗 嵌入式系統(tǒng)

本文中,小編將對單片機予以介紹,如果你想對它的詳細情況有所認識,或者想要增進對它的了解程度,不妨請看以下內(nèi)容哦。

關鍵字: 單片機 開發(fā)板 Keil

隨著單片機系統(tǒng)越來越廣泛地應用于消費類電子、醫(yī)療、工業(yè)自動化、智能化儀器儀表、航空航天等各領域,單片機系統(tǒng)面臨著電磁干擾(EMI)日益嚴重的威脅。電磁兼容性(EMC)包含系統(tǒng)的發(fā)射和敏感度兩方面的問題。

關鍵字: 單片機 電磁兼容

以下內(nèi)容中,小編將對單片機的相關內(nèi)容進行著重介紹和闡述,希望本文能幫您增進對單片機的了解,和小編一起來看看吧。

關鍵字: 單片機 復位電路

在這篇文章中,小編將為大家?guī)韱纹瑱C的相關報道。如果你對本文即將要講解的內(nèi)容存在一定興趣,不妨繼續(xù)往下閱讀哦。

關鍵字: 單片機 異常復位

今天,小編將在這篇文章中為大家?guī)韱纹瑱C的有關報道,通過閱讀這篇文章,大家可以對它具備清晰的認識,主要內(nèi)容如下。

關鍵字: 單片機 仿真器

單片機將是下述內(nèi)容的主要介紹對象,通過這篇文章,小編希望大家可以對它的相關情況以及信息有所認識和了解,詳細內(nèi)容如下。

關鍵字: 單片機 中斷 boot

一直以來,單片機都是大家的關注焦點之一。因此針對大家的興趣點所在,小編將為大家?guī)韱纹瑱C的相關介紹,詳細內(nèi)容請看下文。

關鍵字: 單片機 數(shù)字信號 模擬信號
關閉