標題: 單線多路DS18B20測溫+讀序列號 單片機仿真教程與程序 [打印本頁]
作者: 2646402530 時間: 2017-8-8 08:55
標題: 單線多路DS18B20測溫+讀序列號 單片機仿真教程與程序
單線多路DS18B20測溫,附加讀取DS18B20序列號
第一次發帖寫教程,有問題請多提意見
文件在附件中
基于89C51單片機的單線多路DS18B20多點測溫
Keil文檔 + Protuse仿真
這是寫的第一篇文檔,可能有些地方有點啰嗦,請多多交流。
關于DS18B20的詳細介紹我就不啰嗦了
本人所使用軟件為ISIS,keil4
1.001.jpg (3.64 KB, 下載次數: 89)
下載附件
2017-8-8 17:50 上傳
1.002.jpg (3.56 KB, 下載次數: 95)
下載附件
2017-8-8 17:50 上傳
先看Protuse仿真
1.003.jpg (44.21 KB, 下載次數: 131)
下載附件
2017-8-8 17:50 上傳
圖中使用了1個89c51單片機,兩個DS18B20 ,1個74HC573寄存器,一排8個共陽數碼管,以及按鍵
按鍵1,2用于兩個溫度之間切換
按鍵一按下顯示第一個DS18B20溫度以及其上下限
1.004.jpg (45.26 KB, 下載次數: 96)
下載附件
2017-8-8 17:50 上傳
按鍵二按下顯示第二個DS18B20溫度以及其上下限
1.005.jpg (49.78 KB, 下載次數: 103)
下載附件
2017-8-8 17:50 上傳
其余四個按鍵用于調控溫度上下限設置使用;
附加 讀取DS18B20 的序列號功能(使用不同的顯示函數)
首先要在Protuse中設置DS18B20的序列號
右鍵點擊DS18B20
0.png (219.3 KB, 下載次數: 106)
下載附件
2017-8-8 17:48 上傳
0.png (144.67 KB, 下載次數: 102)
下載附件
2017-8-8 17:48 上傳
B8C534其中的序列號 4以更改
更改后可以用軟件CRC計算器 其對應序列號
計算方式如圖所示
28 為其家族序列號 固定使用
在HEX中輸入 編碼 點擊Calculate 記得到數值 52
0.png (57.89 KB, 下載次數: 128)
下載附件
2017-8-8 17:49 上傳
所以其完整序列號為:ROM1[] = {0x28,0x34,0xC5,0xB8,0x00,0x00,0x00,0x52};
更改protuse中ds18B20的末位數字即可得到不同的序列號
在使用Protuse仿真之前應先設置DS18B20de序列號
單片機源程序如下:
- /**********************************************/
- DS18B20驅動程序如下
- //******DS18B20子函數***********
- #define uint unsigned int
- #define uchar unsigned char
- code unsigned char ROM1[] = {0x28,0x34,0xC5,0xB8,0x00,0x00,0x00,0x52};
- code unsigned char ROM2[] = {0x28,0x31,0xC5,0xB8,0x00,0x00,0x00,0xB9}; //
- sbit DQ = P3^1; //單片機的P3.1 與ds18b20數據端口連接在一起
- void delay(uint x)
- {
- while(x--);
- }
- void Init_DS18B20(void)
- {
- unsigned char x = 255;
- DQ = 1; //先讓DQ = 1;
- DQ = 0; //單片機將DQ拉低
- delay(80); //延時480~960s
- DQ = 1; //釋放總線
- while(DQ && x--); //等待返回的低電平響應,如果沒有響應,
- delay(20); //則做適量延時自動往下執行
- }
- //讀取溫度
- unsigned char Read_OneChar(void)
- {
- uchar i = 0;
- uchar dat = 0;
- for(i = 0;i < 8;i++)
- {
- DQ = 0; //發送啟動信號
- dat =dat >> 1;
- DQ = 1;
- if(DQ) //判斷總線是否為高電平
- dat =dat | 0x80; //如果是高電平則把 j 的最高位置1,如果不是置0;
- delay(10);
- }
- return(dat);
- }
- //向DS18b20中寫入一個字節
- void Write_OneChar(unsigned char dat)
- {
- uchar i = 0;
- for(i = 0;i < 8;i++)
- {
- DQ = 0;
- DQ = dat & 0x01; //讀取 X 的最低位
- delay(10);
- DQ = 1;
- dat= dat >> 1;
- }
- delay(8);
- }
- void PP_SZ1()
- {
- uchar i;
- Write_OneChar(0x55);
- for(i=0;i<8;i++) //發送序列號
- {
- Write_OneChar(ROM1[i]);
- }
- }
- void PP_SZ2()
- {
- uchar i;
- Write_OneChar(0x55);
- for(i=0;i<8;i++) //發送序列號
- {
- Write_OneChar(ROM2[i]);
- }
- }
-
- //********保存溫度上下限********
- void write_temprom(uchar temp_up,uchar temp_down) //應用操作函數2
- {
- Init_DS18B20();
- // Write_OneChar(0xcc);
- if((key_flag1 == 1)&&(key_flag2 == 0))PP_SZ1();
- if((key_flag1 == 0)&&(key_flag2 == 1))PP_SZ2(); //跳過讀序號列號的操作
- Write_OneChar(0x4e); //寫準備
- Write_OneChar(temp_up); //向18B20的暫存寫上限
- Write_OneChar(temp_down); //向18B20的暫存寫下限
- // Write_OneChar(0x7f)
- Init_DS18B20();
- // Write_OneChar(0xcc);
- if((key_flag1 == 1)&&(key_flag2 == 0))PP_SZ1();
- if((key_flag1 == 0)&&(key_flag2 == 1))PP_SZ2();
- Write_OneChar(0x48); //向18B20的rom中寫數據
- Init_DS18B20();
- // Write_OneChar(0xcc);
- if((key_flag1 == 1)&&(key_flag2 == 0))PP_SZ1();
- if((key_flag1 == 0)&&(key_flag2 == 1))PP_SZ2();
- Write_OneChar(0xb8);
- }
- //********讀取溫度上下限********
- uchar temp_up,temp_down; //溫度上下限值
- void read_temprom(void) //應用操作函數3
- {
- uchar i;
- Init_DS18B20();
- // Write_OneChar(0xcc); //跳過讀序號列號的操作
- if((key_flag1 == 1)&&(key_flag2 == 0))PP_SZ1();
- if((key_flag1 == 0)&&(key_flag2 == 1))PP_SZ2();
- Write_OneChar(0xbe); //讀取溫度寄存器等(共可讀9個寄存器) 前兩個就是溫度
- i = Read_OneChar(); //讀0地址寄存器,扔掉
- i = Read_OneChar(); //讀1地址寄存器,扔掉
- temp_up = Read_OneChar(); //讀2地址寄存器
- temp_down = Read_OneChar(); //讀3地址寄存器
- }
- unsigned char a,b,c;
- /************讀取溫度程序***********/
- uchar get_temp()
- {
- unsigned char i = 0, t = 0;
- Init_DS18B20();
- //Write_OneChar(0xF0);
- if((key_flag1 == 1)&&(key_flag2 == 0))PP_SZ1();
- if((key_flag1 == 0)&&(key_flag2 == 1))PP_SZ2();
- Write_OneChar(0x44);
- Init_DS18B20();
- if((key_flag1 == 1)&&(key_flag2 == 0))PP_SZ1();
- if((key_flag1 == 0)&&(key_flag2 == 1))PP_SZ2();
- Write_OneChar(0xbe); //讀暫存器
- a = Read_OneChar(); //讀取匹配ds18B20溫度 //a 1001 0111
- b = Read_OneChar();
- c = a & 0x0f;
- a = a >> 4; //a 0000 1001
- b = b << 4; //b 0111 0000
- t = a | b;
- return(t);
- }
- /***********進制轉換***********/
- uchar BCD_DEC_conv(unsigned char x)
- {
- unsigned char dec;
- dec = 0x0f & x;
- x = x >> 4;
- dec = dec + x * 10;
- return(dec);
- }
- /**********讀取DS18B20的ROM值*************/
- uchar ID[10];ID1[10];
- void Read_DS18B20_rom()
- {
- uchar k;
- Init_DS18B20();
- Write_OneChar(0x33);
- for(k = 0;k <= 8;k++)
- {
- ID[k] = Read_OneChar();
- ID1[k] = BCD_DEC_conv(ID[k]);
- }
- }
- /*********************按鍵函數********************/
- sbit key1 = P2^0;
- sbit key2 = P2^3;
- sbit key3 = P2^1;
- sbit key4 = P2^2;
- sbit key5 = P2^4;
- sbit key6 = P2^5;
- sbit LED = P3^2;
- bit key1_s,key2_s,key3_s,key4_s,key5_s,key6_s;
- void key(void)
- {
- if(key1 == 0)
- {
- delay(300);
- if(key1 == 0)
- key1_s = 1;
- if((key1 == 1)&&(key1_s = 1))
- {
- key1_s = 0;
- key_flag1 = 1;
- key_flag2 = 0;
- }
- }
- if(key2 == 0)
- {
- delay(300);
- if(key2 == 0)
- key2_s = 1;
- if((key2 == 1)&&(key2_s = 1))
- {
- key2_s = 0;
- key_flag1 = 0;
- key_flag2 = 1;
- }
- }
- if(key3 == 0)
- {
- delay(300);
- if(key3 == 0)
- key3_s = 1;
- if((key3 == 1)&&(key3_s = 1))
- {
- key3_s = 0;
- temp_up++;
- write_temprom(temp_up,temp_down);
- delay(20);
- if(temp_up >= 99)temp_up = 99;
- }
- }
- if(key4 == 0)
- {
- delay(300);
- if(key4 == 0)
- key4_s = 1;
- if((key4 == 1)&&(key4_s = 1))
- {
- key4_s = 0;
- temp_up--;
- write_temprom(temp_up,temp_down);
- delay(20);
- if(temp_up <= 0)temp_up = 0;
- }
- }
- if(key5 == 0)
- {
- delay(300);
- if(key5 == 0)
- key5_s = 1;
- if((key5 == 1)&&(key5_s = 1))
- {
- key5_s = 0;
- temp_down++;
- write_temprom(temp_up,temp_down);
- delay(20);
- if(temp_down >= 98)temp_down = 98;
- }
- }
- if(key6 == 0)
- {
- delay(300);
- if(key6 == 0)
- key6_s = 1;
- if((key6 == 1)&&(key6_s = 1))
- {
- key6_s = 0;
- temp_down--;
- write_temprom(temp_up,temp_down);
- delay(20);
- if(temp_down <= 0)temp_down = 0;
- }
- }
- }
- /****************display顯示函數*******************/
- sbit P1_0 = P3^0; //用P1_0表示P3^0
- uchar cp2;
- uchar flash;
- uint temp_num,temp_num1,temp_dot,temp;
- code uchar seven_seg[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,
- 0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};//數碼管顯示數組
- void display0(void)
- {
- P0 = 0xff; //消隱
- switch(cp2) //顯示
- {
- case 0: P1_0 = 0;P0 = 0x01;P1_0 = 1;P1_0 = 0;
- P0 = seven_seg[8];break;
- case 1: P1_0 = 0;P0 = 0x02;P1_0 = 1;P1_0 = 0;
- P0 = seven_seg[2];break;
- case 2:P1_0 = 0;P0 = 0x04;P1_0 = 1;P1_0 = 0;
- P0 = 0xbf | flash; ;break;
- case 3: P1_0 = 0;P0 = 0x08;P1_0 = 1;P1_0 = 0;
- P0 = seven_seg[7];break;
- case 4: P1_0 = 0;P0 = 0x10;P1_0 = 1;P1_0 = 0;
- P0 = seven_seg[0];break;
- case 5: P1_0 = 0;P0 = 0x20;P1_0 = 1;P1_0 = 0;
- P0 = 0xbf | flash;break;
- case 6: P1_0 = 0;P0 = 0x40;P1_0 = 1;P1_0 = 0;
- P0 = seven_seg[7];break;
- case 7: P1_0 = 0;P0 = 0x80;P1_0 = 1;P1_0 = 0;
- P0 = seven_seg[1];break;
- }
- cp2++;
- if(cp2 >= 8)cp2 = 0;
- }
- void display1(void)
- {
- P0 = 0xff; //消隱
- switch(cp2) //顯示
- {
- case 0:P1_0 = 0;P0 = 0x01;P1_0 = 1;P1_0 = 0;
- P0 = seven_seg[temp_num1 % 10%10];break;//顯示個位并加上小數點
- case 1:
- {
- if(temp_num < 10)
- {
- P1_0 = 0;P0 = 0x02;P1_0 = 1;P1_0 = 0;
- P0 = seven_seg[0];break; //如果溫度小于10度,且為正值,十位0不顯示
- }
- // if((temp_num > 0x80) && ( temp_num1 < 10))
- // {
- // P1_0 = 0;P0 = 0x02;P1_0 = 1;P1_0 = 0;
- // P0 = 0xbf; break; //如果溫度小于10度,且為負值,十位0不顯示,只顯示"-"
- // }
- P1_0 = 0;P0 = 0x02;P1_0 = 1;P1_0 = 0;
- P0 = seven_seg[temp_num1 / 10 % 10];break; //如果溫度大于10度,10位正常顯示
- }
- case 2: P1_0 = 0;P0 = 0x04;P1_0 = 1;P1_0 = 0;
- P0 = 0xbf|flash;break;
- case 3: P1_0 = 0;P0 = 0x08;P1_0 = 1;P1_0 = 0;
- P0 = seven_seg[temp_down%10];break;
- case 4: P1_0 = 0;P0 = 0x10;P1_0 = 1;P1_0 = 0;
- P0 = seven_seg[temp_down/10];break;
- case 5: P1_0 = 0;P0 = 0x20;P1_0 = 1;P1_0 = 0;
- P0 = 0xbf|flash;break;
- case 6: P1_0 = 0;P0 = 0x40;P1_0 = 1;P1_0 = 0;
- P0 = seven_seg[temp_up%10];break;
- case 7: P1_0 = 0;P0 = 0x80;P1_0 = 1;P1_0 = 0;
- P0 = seven_seg[temp_up/10];break;
- }
- }
- void display2(void)
- {
- P0 = 0xff; //消隱
- switch(cp2) //顯示
- {
- case 0: P1_0 = 0;P0 = 0x01;P1_0 = 1;P1_0 = 0;
- P0 = seven_seg[ID1[7]%10];break;
- case 1: P1_0 = 0;P0 = 0x02;P1_0 = 1;P1_0 = 0;
- P0 = seven_seg[ID1[7]/10];break;
- case 2: P1_0 = 0;P0 = 0x04;P1_0 = 1;P1_0 = 0;
- P0 = seven_seg[ID1[6]%10]; ;break;
- case 3: P1_0 = 0;P0 = 0x08;P1_0 = 1;P1_0 = 0;
- P0 = seven_seg[ID1[6]/10];break;
- case 4: P1_0 = 0;P0 = 0x10;P1_0 = 1;P1_0 = 0;
- P0 = seven_seg[ID1[5]%10];break;
- case 5: P1_0 = 0;P0 = 0x20;P1_0 = 1;P1_0 = 0;
- P0 = seven_seg[ID1[5]/10];break;
- case 6: P1_0 = 0;P0 = 0x40;P1_0 = 1;P1_0 = 0;
- P0 = seven_seg[ID1[4]%10];break;
- case 7: P1_0 = 0;P0 = 0x80;P1_0 = 1;P1_0 = 0;
- P0 = seven_seg[ID1[4]/10];break;
- }
- }
- void display3(void)
- {
- P0 = 0xff; //消隱
- switch(cp2) //顯示
- {
- case 0: P1_0 = 0;P0 = 0x01;P1_0 = 1;P1_0 = 0;
- P0 = seven_seg[ID1[3]%10];break;
- case 1: P1_0 = 0;P0 = 0x02;P1_0 = 1;P1_0 = 0;
- P0 = seven_seg[ID1[3]/10];break;
- case 2: P1_0 = 0;P0 = 0x04;P1_0 = 1;P1_0 = 0;
- P0 = seven_seg[ID1[2]%10]; ;break;
- case 3: P1_0 = 0;P0 = 0x08;P1_0 = 1;P1_0 = 0;
- P0 = seven_seg[ID1[2]/10];break;
- case 4: P1_0 = 0;P0 = 0x10;P1_0 = 1;P1_0 = 0;
- P0 = seven_seg[ID1[1]%10];break;
- case 5: P1_0 = 0;P0 = 0x20;P1_0 = 1;P1_0 = 0;
- P0 = seven_seg[ID1[1]/10];break;
- case 6: P1_0 = 0;P0 = 0x40;P1_0 = 1;P1_0 = 0;
- P0 = seven_seg[ID1[0]%10];break;
- case 7: P1_0 = 0;P0 = 0x80;P1_0 = 1;P1_0 = 0;
- P0 = seven_seg[ID1[0]/10];break;
- }
- }
- /***************主函數******************/
- /***************************/
- #include"reg51.h"
- bit key_flag1 = 0,key_flag2 = 0; //用于打開對應的DS18B20
- #include
- #include
- #include
- uchar cp,cp1,conv;
- /******中斷服務函數***********/
- void timer0_isr(void)interrupt 1
- {
- TH0 = (65535 - 2000) / 255;
- TL0 = (65535 - 2000) % 255;
- cp++;
- if(cp >= 250)
- {
- cp1++;
- cp = 0;
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
所有資料51hei提供下載:
單線多路DS18B20測溫.docx
(858.86 KB, 下載次數: 112)
2017-8-8 08:53 上傳
點擊文件名下載附件
protuse 仿真
下載積分: 黑幣 -5
作者: 天天拜拜 時間: 2018-4-25 20:36
收藏!!!!
作者: 電子電工 時間: 2018-8-21 21:35
大牛,弱弱的問一下,全是自己默寫的嗎?
作者: sza 時間: 2018-9-20 22:10
大神可以弄lcd12864的嗎
作者: GodWorks 時間: 2019-11-28 11:14
先學習一下,謝謝奉獻
作者: 午夜蹦迪丶 時間: 2020-4-18 14:21
C:\Users\Administrator\Desktop\1.png
請問這里是如何轉換過來的呢?
作者: 捫心王老師 時間: 2020-4-25 18:07
受教了,在網上查了半天怎么計算DS18B20的序列號,終于在這篇帖子里找到方法了,謝謝樓主分享!
作者: lemou 時間: 2024-4-28 11:02
謝謝,先學習一下。
歡迎光臨 (http://www.zg4o1577.cn/bbs/) |
Powered by Discuz! X3.1 |
主站蜘蛛池模板:
午夜在线小视频
|
嫩草一区二区三区
|
国产成人在线视频免费观看
|
欧美精品乱码99久久影院
|
亚洲精品在线播放
|
亚洲欧美在线视频
|
久久久久久久一区二区
|
欧美va大片|
久久男人
|
日韩欧美精品一区
|
国产精品日韩在线观看一区二区
|
久久久久国产一区二区三区四区
|
中文字幕人成乱码在线观看
|
嫩草网
|
黄网站在线播放
|
在线视频一区二区三区
|
久久久一区二区三区
|
国产一区二区视频在线
|
国产成人精品久久
|
国产小视频在线观看
|
亚洲综合在线一区二区
|
国产精品高潮呻吟久久
|
99精品免费在线观看
|
欧美一区二区三区久久精品
|
国产日韩一区二区
|
99精品久久
|
欧美在线二区
|
成人欧美一区二区三区在线播放
|
美女张开腿露出尿口
|
色久伊人
|
久久男人
|
亚洲精品视频一区
|
综合久|
www.蜜桃av|
黑人精品
|
亚洲精品在线视频
|
国产精品久久久久久亚洲调教
|
国产在线对白
|
精品国产乱码久久久久久闺蜜
|
国产精品美女久久久久aⅴ国产馆
|
中文字幕二区三区
|