DS18B20是一種很常用的數(shù)字溫度傳感器,溫度檢測(cè)范圍是-55~+125度,手冊(cè) 說(shuō)明在-10~+85度范圍內(nèi)檢測(cè)誤差為±0.5度,作者在自己的產(chǎn)品中隨機(jī)抽樣驗(yàn)證 了幾只傳感器,在-25度誤差0.1度,+25度與+50度誤差小于0.1度,可見這種傳感 器實(shí)際精度是很高的,傳感器引腳如圖19-1所示,工作電壓范圍是3.0~5.5V,通 常使用+5V,電源接反或接錯(cuò)一般是不會(huì)損壞傳感器的,對(duì)于單只DS18B20的使用,我們按圖19-2連接即可。 

電路和介紹詳見:http://www.torrancerestoration.com/bbs/dpj-47286-1.html(在這貼附件中可下載ds18b20無(wú)線多點(diǎn)測(cè)溫的完整源碼壓縮包)
單片機(jī)下位機(jī)主程序如下(部分預(yù)覽):
- /****************《51單片機(jī)輕松入門-基于STC15W4K系列》配套例程 *************
- ★★★★★★★★★★★★★★★★★★★★★★★★
- 《51單片機(jī)輕松入門-基于STC15W4K系列》 一書已經(jīng)由北航出版社正式出版發(fā)行。
- 作者親手創(chuàng)作的與教材配套的51雙核實(shí)驗(yàn)板(2個(gè)MCU)對(duì)程序下載、調(diào)試、仿真方便,不需要外部
- 仿真器與編程器,這種設(shè)計(jì)方式徹底解決了系統(tǒng)中多個(gè)最高優(yōu)先級(jí)誰(shuí)也不能讓誰(shuí)的中斷競(jìng)爭(zhēng)問(wèn)題。
- QQ群:STC51-STM32(3) :515624099 或 STC51-STM32(2):99794374。
- 驗(yàn)證信息:STC15單片機(jī)
- 郵箱:xgliyouquan@126.com
- ★★★★★★★★★★★★★★★★★★★★★★★★*/
- //18B20多點(diǎn)測(cè)溫程序,11.0592M晶振
- #include "STC15W4K.H"
- #include "usart.h"
- #include "ds18b20.h"
- #define CONVERT 0x44 // 收主機(jī)轉(zhuǎn)換溫度命令
- #define GETTEMP 0xaa // 收主機(jī)讀溫度命令
- #define GETHOUSE 0xcc // 收主機(jī)讀倉(cāng)庫(kù)濕度命令
- #define GETAREA 0xd6 // 收主機(jī)讀庫(kù)區(qū)濕度命令
- #define GETSTATE 0x11 // 收主機(jī)通信檢測(cè)命令
- #define SENDAREA 0xdd // 向主機(jī)發(fā)庫(kù)區(qū)濕度
- #define SENDHOUSE 0xce // 向主機(jī)發(fā)倉(cāng)庫(kù)濕度
- #define CVTOK 0x88 // 向主機(jī)發(fā)轉(zhuǎn)換溫度完畢命令
- #define CPUOK 0x22 // 向主機(jī)發(fā)通信正常命令
- #define TEMPDATA 0xbb // 向主機(jī)發(fā)溫度命令
- unsigned char Port,Pin,count=0; //單片機(jī)端口P0、P1、P2、P3,端口具體引腳(1-8),接收計(jì)數(shù)器
-
- unsigned char send_buff[14]; // 發(fā)送緩沖區(qū)14字節(jié),加幀頭幀尾共16字節(jié)每幀
- unsigned char ReceivdID_buff[8]; // 存儲(chǔ)主機(jī)發(fā)來(lái)的rom ID為8字節(jié)
- unsigned char receivedcmd[16]; // 存放接收到的命令 1:幀頭,2發(fā)送機(jī)號(hào),3本機(jī)ID,4命令,5port,6pin,7-14ID,15CRC,16幀尾
- unsigned char temp_buff[9]; // 存儲(chǔ)讀取的溫度字節(jié),讀溫度為9字節(jié),讀rom ID為8字節(jié)
- unsigned char code CrcTable [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};
- //反序CRC查表校驗(yàn)
- unsigned char crc8_f_table (unsigned char *ptr, unsigned char len)
- {
- unsigned char i;
- unsigned char crc =0;
- for(i=0;i<len;i++) // 查表校驗(yàn)
- {
- crc= CrcTable[crc^ptr[i]]; // ^是按位異或運(yùn)算符
- }
- return(crc);
- }
- void port_mode() // 端口模式
- {
- P0M1=0x00; P0M0=0x00;P1M1=0x00; P1M0=0x00;P2M1=0x00; P2M0=0x00;P3M1=0x00; P3M0=0x00;
- P4M1=0x00; P4M0=0x00;P5M1=0x00; P5M0=0x00;P6M1=0x00; P6M0=0x00;P7M1=0x00; P7M0=0x00;
- }
- void main()
- {
- unsigned char i;
- unsigned char crccount; // crc校驗(yàn)次數(shù)
- unsigned char crc_data; // crc校驗(yàn)結(jié)果
- port_mode(); // 所有IO口設(shè)為準(zhǔn)雙向弱上拉方式。
- com_init(); // 串口初始化
- while(1)
- {
- if(count==16) //count是全局變量,表示串口已收到的字節(jié)數(shù)
- {
- count=0;
-
- for(i=0;i<14;i++)
- {
- send_buff[i]=receivedcmd[i+1]; //取出接收幀2——15字節(jié)(舍棄幀頭幀尾),準(zhǔn)備CRC校驗(yàn)
- }
- crc_data=crc8_f_table(send_buff,14); //發(fā)送緩沖區(qū)14字節(jié)全部參與CRC校驗(yàn)
- if(crc_data==0&&receivedcmd[15]==FMEND)//如果CRC正確且?guī)灿行?br />
- {
- switch(send_buff[2])
- {
- case CONVERT: // 溫度轉(zhuǎn)換命令 0x44
- {
- REN=0; // 禁止串口接收
- ES=0; // 關(guān)串口中斷
- TempConvertAll();
- ES=1; //開串口中斷
- REN=1;
- send_buff[0]=MYID; // 本分機(jī)ID
- send_buff[1]=MAINID; // 主機(jī)ID=0x00
- send_buff[2]=CVTOK; // 溫度轉(zhuǎn)換完畢命令0x88
- crc_data=crc8_f_table(send_buff,13);
- send_buff[13]=crc_data;
- sendcombytes(); // 發(fā)送一幀完整數(shù)據(jù)
- break;
- }
- case GETTEMP: // 讀取溫度命令 0xaa
- {
- Port=send_buff[3]; // 確定端口(P0、P1、P2、P3)
- Pin=send_buff[4]; // 確定端口具體引腳(數(shù)據(jù)0x80、0x40、0x20、0x010、0x08、0x04、0x02、0x01)
- for(i=0;i<8;i++)
- {
- ReceivdID_buff[i]=send_buff[i+5]; // 匹配ROM命令必須用ReceivdID_buff[i]
- }
- REN=0; // 禁止串口接收
- ES=0; // 關(guān)串口中斷
- crccount=0;
- do //同一ID傳感器允許讀4次溫度,4次失敗則退出。
- {
- GetTemp();
- crc_data=crc8_f_table(temp_buff,9); //要使用校驗(yàn)碼,讀溫度必然是連續(xù)9字節(jié)
- crccount++;
- }while(!(crccount>4||crc_data==0)); //校驗(yàn)次數(shù)>4或校驗(yàn)正確立即退出循環(huán)
- ES=1; // 開串口中斷
- REN=1; // 允許串口接收
- send_buff[0]=MYID;
- send_buff[1]=MAINID;
- send_buff[2]=TEMPDATA; // 向主機(jī)發(fā)溫度命令 0xbb
- if(crc_data==0)
- {
- send_buff[3]=temp_buff[0]; // 原始溫度低字節(jié)
- send_buff[4]=temp_buff[1]; // 原始溫度高字節(jié)
- }
- else
- {
- send_buff[3]=0xff;
- send_buff[4]=0xff;
- }
- for(i=0;i<8;i++)
- {
- send_buff[i+5]=ReceivdID_buff[i];
- }
- crc_data=crc8_f_table(send_buff,13);
- send_buff[13]=crc_data;
- sendcombytes();
- break;
- }
- case GETSTATE: // 主機(jī)通信檢測(cè)命令0x11,確認(rèn)主機(jī)與分機(jī)通信是否正常
- {
- send_buff[0]=MYID;
- send_buff[1]=MAINID;
- send_buff[2]=CPUOK; // CPUOK 0x22
- for(i=0;i<10;i++)
- {
- send_buff[i+3]=0x55;
- }
- crc_data=crc8_f_table(send_buff,13);
- send_buff[13]=crc_data;
- sendcombytes();
- break;
- }
- case GETHOUSE: //倉(cāng)庫(kù)濕度命令 0xce
- {
- ;
- }
- case GETAREA: // 庫(kù)區(qū)濕度命令 0xd6
- {
- ;
- }
- default:break;
- }
- }
- }
- }
- }
復(fù)制代碼
usart.c文件:
|