|
- /*********************************************
- 功 能:讀取序列號并匹配序列號,并讀溫度值
- 多功能試驗板顯示多路溫度采集
- 正常顯示2個DS18B20溫度
- 正常讀取DS18B20序列號
- 單片機:STC12C5A60S2
- 晶 振:11.0592M
- 作 者:蘇義江改編自網絡
- 時 間:2016-8-25
- ************************************************/
- #include <reg52.h>
- #include <intrins.h>
- #define uchar unsigned char
- #define uint unsigned int
- sbit RS=P2^7;
- sbit RW=P2^6;
- sbit EN=P2^5;
- sbit DQ=P3^4; //傳感器引腳
- sbit key=P3^7;
- sbit d1=P1^3;//指示燈
- sbit d2=P1^4;
- bit st=1;
- uchar code table0[]={"DuoLuWenDuXS:U "};
- uchar code table2[]={"SD: "}; //濕度
- uchar code table1[]={"0123456789ABCDEF"};
- //現有的2個DS18B20傳感器的序列號ROM1,ROM2
- uchar DSrom[4][8]={//4個器件每個64位序列號
- {0x28,0xff,0x2a,0x0A,0x22,0x04,0x00,0xf6},//ROM1
- {0x28,0xFF,0x0b,0x0d,0x20,0x04,0x00,0x0a},//ROM2
- {0x28,0x0C,0xBA,0xBA,0x02,0x00,0x00,0x54},//ROM3
- {0x28,0xff,0x91,0x14,0x22,0x04,0x00,0xe4}//ROM4
- };
- int f[4]; //溫度數組
- int tvalue; //溫度值變量
- float ftvalue; //溫度值變量
- uchar fCode[8];//序列號數組
- uint warnl=300; //設定溫度值高
- uint warnh=992;//設定溫度值低
- void ds1820wr(uchar dat);//寫數據
- void ds1820rst();//ds1820復位
- uchar ds1820rd();//讀數據
- void DispCode();//讀取序列號
- uchar tflag;//溫度正負標志
- //////////lcd1602程序////////////
- void delay1ms(uint ms)//延時1毫秒(不夠精確的)
- {
- uint i,j;
- for(i=0;i<ms;i++)
- for(j=0;j<620;j++);
- }
- void wr_com(uchar com)//寫指令//
- {
- delay1ms(1);
- RS=0;
- RW=0;
- EN=0;
- P0=com;
- delay1ms(1);
- EN=1;
- delay1ms(1);
- EN=0;
- }
- void wr_dat(uchar dat)//寫數據//
- {
- delay1ms(1);;
- RS=1;
- RW=0;
- EN=0;
- P0=dat;
- delay1ms(1);
- EN=1;
- delay1ms(1);
- EN=0;
- }
- void lcd_init()//1602初始化設置//
- {
- delay1ms(15);
- wr_com(0x38);
- delay1ms(5);
- wr_com(0x08);delay1ms(5);
- wr_com(0x01);delay1ms(5);
- wr_com(0x06);delay1ms(5);
- wr_com(0x0c);delay1ms(5);
- }
- void display(uchar *p)//顯示字符串
- {
- while(*p!='\0')
- {
- wr_dat(*p);
- p++;
- delay1ms(1);
- }
- }
- void displayinit()//初始化顯示
- {
- lcd_init();
- wr_com(0x80);
- display(table0);
- wr_com(0xC6);
- wr_dat(0xdf);
- wr_com(0xC7);
- wr_dat('C');
- wr_com(0xCf);
- wr_dat(0x25);
- wr_com(0XC9);
- display(table2);
- }
- void tmstart()//初始化ds18b20
- {
- DQ=1;
- d1=1;
- d2=1;
- ds1820rst();
- delay1ms(1);
- ds1820wr(0xcc);
- ds1820wr(0x44);
- }
- void read_dealtemp()//讀取并處理溫度
- {
- uchar i,j,t;
- uchar a,b;
- for(j=0;j<5;j++) //掛載4個設備
- {
- ds1820rst(); //復位
- delay1ms(1);
- ds1820wr(0x55); //匹配EOM指令
- for(i=0;i<8;i++)
- {
- ds1820wr(DSrom[j][i]);//發送64位序列號
- }
- ds1820wr(0xbe);//溫度轉換
- a=ds1820rd(); //讀高位
- b=ds1820rd(); //讀低位
- tvalue=b;
- tvalue<<=8;
- tvalue=tvalue|a;
- if(tvalue<0) //判斷正負溫度
- {
- d1=1;
- tvalue=~tvalue+1;
- wr_com(0xc0); //第二行第一列
- wr_dat(0x2d); //負溫度符號"-"
- if(tvalue<warnl) //溫度高于設定值warnl=300;
- {
- d2=0; //報警
- DQ=0;
- }
- else
- {
- d2=1;
- DQ=1;
- }
- }
- else
- {
- d2=1;
- wr_com(0xc0);
- wr_dat(' ');
- if(tvalue>warnh) //溫度高于設定值warnh=992;
- {
- d1=0; //報警
- DQ=0;
- }
- else
- {
- d1=1;
- DQ=1;
- }
- }
- if(j==0)
- {
- wr_com(0x8f);
- wr_dat('1');
- }
- if(j==1)
- {
- wr_com(0x8f);
- wr_dat('2');
- }
- if(j==2)
- {
- wr_com(0x8f);
- wr_dat('3');
- }
- if(j==3)
- {
- wr_com(0x8f);
- wr_dat('4');
- }
- if(j==4)
- {
- wr_com(0x8f);
- wr_dat('5');
- }
- ftvalue=tvalue*0.0625;
- tvalue=ftvalue*10+0.5;
- ftvalue=ftvalue+0.05; //溫度補償
- f[j]=tvalue;//溫度擴大十倍,精確到一位小數
- tvalue=f[j];
- t=tvalue/1000;
- wr_com(0x80+0x41);
- wr_dat(table1[t]);//顯示百位
- t=tvalue%1000/100;
- wr_dat(table1[t]);//顯示十位
- t=tvalue%100/10;
- wr_dat(table1[t]);//顯示個位
- wr_dat(0x2e); //顯示小數點兒
- t=tvalue%10/1;
- wr_dat(table1[t]);//顯示小數位
- delay1ms(5000);
- }
- }
- void keyscan()//按鍵
- {
- if(key==0)
- {
- delay1ms(30);
- if(key==0)
- {
- st=~st;
- }
- while(!key);
- }
- }
- void main()
- {
- d1=1;
- d2=1;
- DQ=1;
- displayinit();//初始化顯示
- while(1)
- {
- keyscan();//按住按鍵等4個器件循環完畢顯示序列號
- if(st==1)
- {
- wr_com(0x01);
- displayinit();//初始化顯示
- tmstart();//初始化
- read_dealtemp();//讀取溫度
- }
- else
- {
- wr_com(0x01);
- keyscan();//按住按鍵等4個器件循環完畢顯示序列號
- DispCode();//讀取序列號
- delay1ms(1000);
- }
- }
- }
- ////////DS18B20函數///////////////
- void delay_b20(uint n)//STC12C5A單片機定時1us
- {
- while(n--)
- {
- _nop_();
- }
- }
- void ds1820rst()/*ds1820復位*/
- {
- uchar x=0;
- DQ = 1; //DQ復位
- delay_b20(1); //延時
- DQ = 0; //DQ拉低
- delay_b20(500); //精確延時大于480us
- DQ = 1; //拉高
- delay_b20(80);
- }
- uchar ds1820rd()/*讀數據*/
- {
- uchar i=0;
- uchar dat = 0;
- for (i=0;i<8;i++)
- {
- DQ = 1; //給脈沖信號
- delay_b20(1);
- DQ = 0; //給脈沖信號
- delay_b20(1);
- dat>>=1;
- DQ = 1; //給脈沖信號
- if(DQ)
- dat|=0x80;
- delay_b20(60);
- }
- return(dat);
- }
- void ds1820wr(uchar dat)/*寫數據*/
- {
- uchar i=0;
- for (i=0; i<8; i++)
- {
- DQ = 1;
- delay_b20(1);
- DQ = 0;
- DQ = dat&0x01;
- delay_b20(60);
- DQ = 1;
- delay_b20(60);
- dat>>=1;
- }
- delay_b20(1);
- }
- ///////////讀取序列號//////////
- void DispCode()//讀取序列號
- {
- uchar i,temp;
- ds1820rst();
- ds1820wr(0x33);
- for (i=0;i<8;i++)
- {
- fCode[i]=ds1820rd();
- }
- wr_com(0x80+0x40);
- for (i=0;i<8;i++)
- {
- temp = fCode[i]>>4; //顯示高四位
- if (temp<10)
- wr_dat(temp + 0x30); // 顯示數字
- else
- wr_dat(temp + 0x37); //否則大于數字9顯示字母
- temp = fCode[i]&0x0f;//顯示低四位
- if (temp<10)
- wr_dat(temp+ 0x30);
- else
- wr_dat(temp + 0x37);
- }
- }
復制代碼
STC12C5A60S2多路測溫1602顯示并顯示DS18B20序列號 |
|