51單片機做的一個ds18b20多點溫度控制程序源碼和proteus仿真
0.png (40.44 KB, 下載次數(shù): 82)
下載附件
2016-11-1 11:15 上傳
0.png (75.69 KB, 下載次數(shù): 89)
下載附件
2016-11-1 11:16 上傳
仿真工程文件和源碼打包下載:
單片機多點溫度控制系統(tǒng).zip
(92.29 KB, 下載次數(shù): 50)
2016-11-1 08:01 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
單片機源程序:
- //采用12MHz晶振
- #include<AT89X51.h>
- #define uchar unsigned char
- #define FALSE 0;
- #define TRUE 1;
- sbit DQ =P3^0;//B20選擇
- sbit button1=P1^0;//定義通信端口
- sbit button2=P1^1;//顯示選擇按鈕
- sbit button3=P1^2;//位選端
- sbit button4=P1^3;//加1
- unsigned char ROM[8];//ROM位 最前面是lsb
- unsigned char FoundROM[3][8];//ROM代碼表
- unsigned char lastDiscrep=0; //上次差值
- unsigned char doneFlag=0; //完成標志
- unsigned int numROMs; //DS18B20個數(shù)
- unsigned char dowcrc; //crc校驗值
- unsigned char DS_key=0;
- uchar code LED[] ={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00};//0123456789
- uchar code LED1[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef,0x00};//0-9的帶小數(shù)點的段選碼
- uchar code tab[] ={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//P2選通數(shù)組
- int temperature[2][11]={0x00,0x00,0x00,0x06,0x05,0x04,0x03,0x02,0x01,0x0a,0x00,
- //十分 個 十 高溫 低溫
- 0x00,0x00,0x00,0x05,0x05,0x04,0x02,0x02,0x01,0x0a,0x00
- }; //溫度緩存數(shù)組
- uchar data con=0x00,conk1=0x00;conk2=0x00,cont0=0x00,cont1=0x00;
- //crc校驗表
- uchar code dscrc_table[]={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
- };
- void delay(unsigned int i);
- unsigned char Init_DS18B20(void);
- unsigned char Read_One_bit(void);
- unsigned char Read_One_byte(void);
- void Write_One_bit(char bitval);
- void Write_One_byte(unsigned char dat);
- unsigned char ow_crc(unsigned char x);
- //void Read_Rom_Code(void);
- unsigned char Next(void);
- unsigned char First(void);
- void Find_Devices(void);
- unsigned char Send_Match_Rom(unsigned char DS_number);
- void Read_Temperature(unsigned char number);
- void Key_scan(void);
- void DS_Key_scan(void);
- void Show_Temp(void);
- void Compare(void);
- //延時函數(shù)
- void delay(unsigned int i)//9us延遲,調用此程序4us
- {
- while(i--);
- }
- //初始化函數(shù)
- unsigned char Init_DS18B20(void)
- {
- unsigned char presence;
- DQ=1; //DQ復位
- delay(8); //稍做延時
- DQ=0; //單片機將DQ拉低
- delay(80); //精確延時 大于 480us
- DQ=1; //拉高總線
- delay(5);
- presence=DQ; //稍做延時后 如果x=0則初始化成功 x=1則初始化失敗
- delay(15);
- return(presence);
- }
- //讀一個位
- unsigned char Read_One_bit(void)
- {
- uchar i;
- DQ=0;
- DQ=1;
- for(i=0;i<3;i++); //延遲15微妙
- return(DQ);
- }
- //讀一個字節(jié)
- unsigned char Read_One_byte(void)
- {
- unsigned char i=0;
- unsigned char dat = 0;
- for (i=0;i<8;i++)
- {
- if(Read_One_bit())
- dat|=0x01<<i;
- delay(9);
- }
- return(dat);
- }
- //寫一個位
- void Write_One_bit(char bitval)
- {
- DQ=0;
- if(bitval==1)
- DQ=1;
- delay(5);
- DQ=1;
- }
- //寫一個字節(jié)
- void Write_One_byte(unsigned char dat)
- {
- unsigned char i;
- unsigned char temp;
- for (i=0; i<8; i++)
- {
- temp=dat>>i;
- temp&=0x01;
- Write_One_bit(temp);
- }
- delay(9);
- }
- //crc校驗函數(shù)
- unsigned char ow_crc(unsigned char x)
- {
- dowcrc=dscrc_table[dowcrc^x];
- return dowcrc;
- }
- /*
- //讀取單總線上的單個DS18B20的ROM,對于多個器件采用搜索ROM
- void Read_Rom_Code(void)
- {
- int n;
-
- if(!Init_DS18B20())
- {
- delay(20);
- Write_One_byte(0x33);
- for(n=0;n<8;n++)
- {
- ROM[n]=Read_One_byte();
- }
- }
- }
- */
- //搜索單總線上的下一個器件,如果沒有則返回假
- unsigned char Next(void)
- {
- unsigned char m=1;
- unsigned char n=0;
- unsigned char k=1;
- unsigned char x=0;
- unsigned char discrepMaker=0; //搜索定位到一個B20的標志位
- unsigned char g;
- unsigned char nxt;
- int flag;
- nxt=FALSE;
- dowcrc=0;
- flag=Init_DS18B20();
- if(flag||doneFlag) //無器件,返回假值
- {
- lastDiscrep=0;
- return FALSE;
- }
- Write_One_byte(0xf0);
- do
- {
- x=0;
- if(Read_One_bit()==1) x=2; //10 都為1
- delay(10); //01 都為0
- if(Read_One_bit()==1) x|=1; //00 存在兩個以上,第一位不相等
- delay(10); //11 沒有器件
- if(x==3) break;
- else
- {
- if(x>0) g=x>>1; //x=1或x=2
- else
- { //x=0
- if(m<lastDiscrep) g=((ROM[n]&k)>0);
- else g=(m==lastDiscrep);
- if(g==0) discrepMaker=m;
- }
- if(g==1) ROM[n]|=k; //寫1
- else ROM[n]&=~k; //寫0
- Write_One_bit(g);
- delay(10);
- m++;
- k=k<<1; //k循環(huán)右移1位,
- if(k==0)
- {
- ow_crc(ROM[n]);
- n++;k++;
- }
- }
- }while(n<8);
- if(m<65||dowcrc) lastDiscrep=0; //搜索未成功
- else
- { //搜索成功,置各個標志位,返回還有其他器件,
- lastDiscrep=discrepMaker;
- doneFlag=(lastDiscrep==0); //完成置1
- nxt=TRUE;
- }
- return(nxt);
- }
- //復位當前ROM搜索狀態(tài)并調用Next函數(shù)搜索單總線的第一個器件
- unsigned char First(void)
- {
- lastDiscrep=0;
- doneFlag=FALSE;
- return Next();
- }
- //復位單總線以確定是否存在任何器件,如果存在將其喚醒,然后調用First函數(shù)跟蹤沖突位
- //并返回Next函數(shù),Next函數(shù)完成鑒別單總線上的每個器件唯一ROM代碼的大部分工作
- void Find_Devices(void)
- {
- unsigned char m;
- if(!Init_DS18B20())
- {
- if(First())
- {
- numROMs=0;
- do{
- for(m=0;m<8;m++)
- {
- FoundROM[numROMs][m]=ROM[m];
- }
- numROMs++;
- }while(Next()&&(numROMs<4)); //兩個B20
- }
- }
- }
- //匹配單個DS18B20
- unsigned char Send_Match_Rom(unsigned char DS_number)
- {
- unsigned char i;
- if(Init_DS18B20())
- return FALSE;
- // delay(20);
- Write_One_byte(0x55);
- for(i=0;i<8;i++)
- {
- Write_One_byte(FoundROM[DS_number][i]);
- }
- return TRUE;
- }
- //讀取溫度
- void Read_Temperature(unsigned char number)
- {
- unsigned char fu;
- float m;
- unsigned char temp_lsb=0;
- unsigned char temp_msb=0;
- unsigned int temp_value=0;
- int show,n;
- Init_DS18B20(); //初始化函數(shù)DS18B20
- Send_Match_Rom(number);//匹配ROM
- // Write_One_byte(0xCC); // 跳過讀序號列號的操作
- Write_One_byte(0x44); // 啟動溫度轉換
- Init_DS18B20();
- Send_Match_Rom(number);//匹配ROM
- // Write_One_byte(0xCC); //跳過讀序號列號的操作
- Write_One_byte(0xBE); //讀取溫度寄存器等(共可讀9個寄存器) 前兩個就是溫度
- temp_lsb=Read_One_byte(); //溫度lsb
- temp_msb=Read_One_byte(); //溫度msb
- temp_value=temp_msb;
- temp_value<<=8; //左移8位
- temp_value=temp_value|temp_lsb;
- fu=temp_msb;
- fu=fu&0x08;
- if(fu!=0) //判斷正負
- {temp_value=~temp_value+1;}
- m=temp_value*0.0625; //將十進制m向左移動4個小數(shù)點
- show=m;
- temperature[number][2]=show/10;//十位
- temperature[number][1]=show%10;//個位
- n=((m-show)*100+0.5);
- temperature[number][0]=n/10;//十分位
- }
- //按鈕掃描
- void DS_Key_scan(void)
- {
- EA=0;
- if(conk2==0)
- {
- if(button2==0) //按鍵1
- {
- delay(1000); //延遲9毫秒,消抖延遲
- while(button2==0);
- // TR1=0;ET1=0;TH1=0x3c;TL1=0xB0;
- // TR1=1;ET1=1;
- con=con+3;
- if(con==9)
- con=0;
- }
- }
-
- if(con!=0) //按鍵2
- {
- if(con==3||con==6)
- {
- if(button3==0)
- {
- delay(1000); //消抖延遲
- while(button3==0);
- if(temperature[DS_key][con+conk1]==0x0a)
- {
- temperature[DS_key][10]=temperature[DS_key][con+conk1];
- temperature[DS_key][con+conk1]=temperature[DS_key][9];
- temperature[DS_key][9]=temperature[DS_key][10];
- }
-
- TR0=1;ET0=1;
- // TR1=0;ET1=0;TH1=0x3c;TL1=0xB0;
- // TR1=1;ET1=1;
- conk1++;
- conk2++;
- if(conk1==3)
- conk1=0;
- if(conk2==4)
- {
- conk2=0;
- con=0;
- TR0=0;ET0=0;
- conk1=0;
- }
- }
- }
- }
-
- if(con!=0&&conk2!=0) //按鍵3
- {
- if(con==3||con==6)
- {
- if(button4==0)
- {
- delay(1000); //消抖延遲
- while(button4==0);
- if(temperature[DS_key][con+conk1]==10)
- {
- temperature[DS_key][10]=temperature[DS_key][con+conk1];
- temperature[DS_key][con+conk1]=temperature[DS_key][9];
- temperature[DS_key][9]=temperature[DS_key][10];
- }
- // TR1=0;ET1=0;TH1=0x3c;TL1=0xB0;
- // TR1=1;ET1=1;
- temperature[DS_key][con+conk1]++;
- if(temperature[DS_key][con+conk1]>=10)
- {
- temperature[DS_key][con+conk1]=0;
- }
- temperature[DS_key][9]=0x0a;
- }
- }
- }
- EA=1;
- }
- //DS18B20選擇
- void Key_scan(void)
- {
- if(button1==0) //按鍵4
- {
- delay(1000); //延遲9毫秒,消抖延遲
- while(button1==0);
-
- DS_key++;
- if(DS_key==2)
- DS_key=0;
- }
- DS_Key_scan();
-
- }
- //定時器0中斷0.4秒
- void time_int0(void) interrupt 1
- {
- EA=0;TR0=0;TH0=0x3c;TL0=0xB0;TR0=1;
- cont0++;
- if(cont0==6)
- {
- cont0=0x00;
- temperature[DS_key][10]=temperature[DS_key][con+conk1];
- temperature[DS_key][con+conk1]=temperature[DS_key][9];
- temperature[DS_key][9]=temperature[DS_key][10];
- }
- ET0=1;
- }
- //定時器1中斷
- /*void time_int1(void) interrupt 3
- {
- EA=0,TR1=0;TH1=0x3c;TL1=0xB0;TR1=1;
- cont1++;
- if(cont1==100) //延遲5秒,5秒后恢復到顯示18B20值
- {
- if(temperature[con+conk1]==0x0a)
- {
- temperature[10]=temperature[con+conk1];
- temperature[con+conk1]=temperature[9];
- temperature[9]=temperature[10];
- }
-
- cont1=0x00;
- con=0;
- conk1=0;
- conk2=0;
- TR1=0;ET1=0;
- TR0=0;ET0=0;
- }
-
- ET1=1;
- }
- */
- //輸出顯示函數(shù)
- void Show_Temp(void)
- {
- int i,j,m,n;
- for(i=0;i<3;i++)
- {
- if(DS_key==0)
- {
- j=con+i;
- n=i;
- }
- else
- {
- j=i;
- n=con+i;
- }
- m=i+3;
- P2=tab[i];
- if(i==1)
- P0=LED1[temperature[0][j]];
- else
- P0=LED[temperature[0][j]];
- delay(150);
- P2=tab[m];
- if(m==4)
- P0=LED1[temperature[1][n]];
- else
- P0=LED[temperature[1][n]];
-
- delay(150);
- }
- P2=tab[7];
- P0=LED[DS_key+1];
- delay(150);
- P2=0xff;
- }
- //比較函數(shù)
- void Compare(void)
- {
- unsigned int test1,high1,low1;
- unsigned int test2,high2,low2;
- test1=temperature[0][2]*100+temperature[0][1]*10+temperature[0][0];
- high1=temperature[0][5]*100+temperature[0][4]*10+temperature[0][3];
- low1=temperature[0][8]*100+temperature[0][7]*10+temperature[0][6];
- test2=temperature[1][2]*100+temperature[1][1]*10+temperature[1][0];
- high2=temperature[1][5]*100+temperature[1][4]*10+temperature[1][3];
- low2=temperature[1][8]*100+temperature[1][7]*10+temperature[1][6];
- P1_4=1;
- P1_5=1;
- P1_6=1;
- P1_7=1;
- if(test1>high1)
- {
- P1_7=0;
- }
- if(test2>high2)
- {
- P1_5=0;
- }
- if(test1<low1)
- {
- P1_6=0;
- }
- if(test2<low2)
- {
- P1_4=0;
- }
- }
- void main()
- {
- //int num=0;
- TH0=0x3C;TL0=0xB0; //50毫秒延遲
- TH1=0x3C;TL1=0xB0; //50毫秒延遲
- TMOD=0x11;ET0=0;TR0=0;ET1=0;TR1=0;
- EA=0;
- Init_DS18B20();
- // Read_Rom_Code();
- // First();
- Find_Devices();
- while(1)
- {
- Show_Temp();
- Read_Temperature(0);
- // delay(20);
- Show_Temp();
- Read_Temperature(1);
- Key_scan();
- // DS_Key_scan(0);
- Compare();
-
- }
- }
復制代碼
|