|
利用51單片機(jī)DS18B20和1602做的溫度計(jì),可以實(shí)現(xiàn)溫度上限報(bào)警,進(jìn)行華氏和攝氏度的轉(zhuǎn)換,利用三個(gè)按鍵實(shí)現(xiàn)這些功能。
單片機(jī)源程序如下:
- /*作者:王先生
- 51單片機(jī):清華電子的板
- #include<reg52.h>
- #include<intrins.h>
- #include<math.h>
- typedef unsigned char uchar;
- typedef unsigned int uint;
- sbit DS = P2^2;//DS18B20接口
- sbit BP = P2^3;//蜂鳴器
- sbit DU = P2^6;//數(shù)碼管段選碼
- sbit WE = P2^7;//數(shù)碼管位選碼
- sbit key_s1 = P3^0;
- sbit key_s2 = P3^1;
- sbit key_s3 = P3^2;
- sbit EN = P3^4;//LCD使能端
- sbit RS = P3^5;//LCD數(shù)據(jù)命令選擇端
- sbit RW = P3^6;//LCD讀寫(xiě)選擇端
- uint FF;
- uint DD,LL;
- uint K=0;
- uint M=0;
- uint s=0;
- void delayus(uchar us)
- {
- while(us--);//us--要6.5us,進(jìn)入一次函數(shù)11.95us;
- } //微秒延時(shí)
- void LCD_READ_BUSY() //忙不忙
- {
- uchar busy;
- P0 = 0XFF;
- RS = 0;
- RW = 1;
- do
- {
- EN = 1;
- busy = P0;
- EN = 0;
- }while(busy&0X80);
- EN = 1;
- }
- void LCD_WRITE_CMD(uchar cmd)//寫(xiě)一個(gè)字節(jié)命令流程
- {
- LCD_READ_BUSY();//判斷忙不忙
- RS = 0;
- RW = 0;
- P0 = cmd;
- EN = 1;
- EN = 0;
- }
- void LCD_WRITE_DATE(uchar dat)//寫(xiě)一個(gè)字節(jié)數(shù)據(jù)
- {
- LCD_READ_BUSY();
- RS = 1;
- RW = 0;
- P0 = dat;
- EN = 1;
- EN = 0;
- }
- void LCD_OneChar(uchar x, uchar y,uchar dat)//指定位置顯示字符
- {
- if(y)
- x |= 0x40;//位選或
- x |= 0x80;
- LCD_WRITE_CMD(x);
- LCD_WRITE_DATE(dat);
- }
- void LCD_Str(uchar x, uchar y, uchar *str)//指定位置顯示字符串
- {
- if(y)
- x |= 0x40;
- x |= 0x80;
- LCD_WRITE_CMD(x);
- while(*str != '\0')
- {
- LCD_WRITE_DATE(*str++);
- }
- }
- void LCD_Init() // 初始化
- {
- LCD_WRITE_CMD(0x38); // 設(shè)置16*2顯示,5*7點(diǎn)陣,8位數(shù)據(jù)接口
- LCD_WRITE_CMD(0x0c); //開(kāi)顯示
- LCD_WRITE_CMD(0x06); //讀寫(xiě)一字節(jié)后地址指針加1
- LCD_WRITE_CMD(0x01); //清除顯示
- }
- bit ds_init()//單總線初始化程序
- {
- bit i;
- DS = 1;
- _nop_();
- DS = 0;
- delayus(75);//拉低總線;保持480us以上,75*6.5+11.95=499.45ms
- DS = 1;//釋放總線
- delayus(1);//1*6.5+11.95=18.45us等待發(fā)回信號(hào)(15-60us)
- i = DS;
- delayus(20);//讀取存在信號(hào)的時(shí)間20*6.5+11.95=141.95us
- DS = 1; //釋放總線
- _nop_();
- return(i);//i=0代表DS18B20已經(jīng)準(zhǔn)備好了
- }
- void displayN(int c)//溫度正常顯示
- {
- uint i;
- uchar M1,M2,M3,M4;
- uchar TestStr[] = {"Tem:"};
- uchar TestStr1[] = {"DB:WYX"};
- /*if(c<0)
- {m = 2;}
- else if(c>=0)
- {m = 0;}*/
- i = abs(c);
- M1 = i/1000;//千位
- M2 = i%1000/100;//百位
- M3 = i%1000%100/10;//十位
- M4 = i%10; //個(gè)位
-
- DU = 0;
- WE = 0;//關(guān)閉數(shù)碼管顯示
- LCD_Init();//1602初始化
- LCD_Str(0, 0, &TestStr[0]); //顯示字符串
- LCD_Str(0, 1, &TestStr1[0]); //顯示字符串
- LCD_OneChar(6 , 0, 43+s);//正負(fù)號(hào)
- LCD_OneChar(7, 0, M1+48); //顯示溫度
- LCD_OneChar(8, 0, M2+48);
- LCD_OneChar(9 , 0, M3+48);//正負(fù)號(hào)
- LCD_OneChar(10, 0, 46);
- LCD_OneChar(11, 0, M4+48);
- LCD_OneChar(12, 0, 39);
- LCD_OneChar(13, 0, 67);
- LCD_OneChar(15, 0, 78+DD*10); //顯示蜂鳴器開(kāi)關(guān)
- LCD_OneChar(15, 1, 78+LL*10); //顯示指示燈開(kāi)關(guān)
- }
- void displayM(int c)
- {
- uchar M1,M2,M3,M4;
- int i,m;
- uchar TestStr[] = {"Tem:"};
- uchar TestStr1[] = {"High"};
- if(c<0)
- {m = 2;}
- else if(c>=0)
- {m = 0;}
- i = abs(c);
- M1 = i/1000;//千位
- M2 = i%1000/100;//百位
- M3 = i%1000%100/10;//十位
- M4 = i%10; //個(gè)位
-
- DU = 0;
- WE = 0;//關(guān)閉數(shù)碼管顯示
- LCD_Init();//1602初始化
- LCD_Str(0, 0, &TestStr[0]); //顯示字符串
- LCD_Str(7, 1, &TestStr1[0]); //顯示字符串
- LCD_OneChar(6 , 0, 43+m);//正負(fù)號(hào)
- LCD_OneChar(7, 0, M1+48); //顯示溫度
- LCD_OneChar(8, 0, M2+48);
- LCD_OneChar(9 , 0, M3+48);//正負(fù)號(hào)
- LCD_OneChar(10, 0, 46);
- LCD_OneChar(11, 0, M4+48);
- LCD_OneChar(12, 0, 39);
- LCD_OneChar(13, 0, 67);
- LCD_OneChar(15, 0, 78+DD*10); //顯示蜂鳴器開(kāi)關(guān)
- LCD_OneChar(15, 1, 78+LL*10); //顯示指示燈開(kāi)關(guān)
- }
- void displayL(int c)
- {
- uchar M1,M2,M3,M4;
- int i,m;
- uchar TestStr[] = {"Tem:"};
- uchar TestStr1[] = {"Low"};
- if(c<0)
- {m = 2;}
- else if(c>=0)
- {m = 0;}
- i = abs(c);
- M1 = i/1000;//千位
- M2 = i%1000/100;//百位
- M3 = i%1000%100/10;//十位
- M4 = i%10; //個(gè)位
-
- DU = 0;
- WE = 0;//關(guān)閉數(shù)碼管顯示
- LCD_Init();//1602初始化
- LCD_Str(0, 0, &TestStr[0]); //顯示字符串
- LCD_Str(7, 1, &TestStr1[0]); //顯示字符串
- LCD_OneChar(6 , 0, 43+m);//正負(fù)號(hào)
- LCD_OneChar(7, 0, M1+48); //顯示溫度
- LCD_OneChar(8, 0, M2+48);
- LCD_OneChar(9 , 0, M3+48);//正負(fù)號(hào)
- LCD_OneChar(10, 0, 46);
- LCD_OneChar(11, 0, M4+48);
- LCD_OneChar(12, 0, 39);
- LCD_OneChar(13, 0, 67);
- LCD_OneChar(15, 0, 78+DD*10); //顯示蜂鳴器開(kāi)關(guān)
- LCD_OneChar(15, 1, 78+LL*10); //顯示指示燈開(kāi)關(guān)
- }
- void displayNF(int c)
- {
- uchar M1,M2,M3,M4;
- uchar TestStr[] = {"Tem:"};
- uchar TestStr1[] = {"DB:WYX"};
- uint p,i;
- /*if(c<0)
- {m = 2;}
- else
- {m = 0;}*/
- i = abs(c);
- p = i*9/5+320;
- M1 = p/1000;
- M2 = p%1000/100;//百位
- M3 = p%1000%100/10;//十位
- M4 = p%10; //個(gè)位
-
- DU = 0;
- WE = 0;//關(guān)閉數(shù)碼管顯示
- LCD_Init();//1602初始化
- LCD_Str(0, 0, &TestStr[0]); //顯示字符串
- LCD_Str(0, 1, &TestStr1[0]); //顯示字符串
- LCD_OneChar(6 , 0, 43+s);//顯示正負(fù)
- LCD_OneChar(7, 0, M1+48); //顯示溫度
- LCD_OneChar(8, 0, M2+48);
- LCD_OneChar(9, 0, M3+48);
- LCD_OneChar(10, 0, 46);
- LCD_OneChar(11, 0, M4+48);
- LCD_OneChar(12, 0, 39);
- LCD_OneChar(13, 0, 67+FF);
- LCD_OneChar(15, 0, 78+DD*10); //顯示蜂鳴器開(kāi)關(guān)
- LCD_OneChar(15, 1, 78+LL*10); //顯示指示燈開(kāi)關(guān)
- }
- void displayMF(int c)
- {
- uchar M1,M2,M3,M4;
- uchar TestStr[] = {"Tem:"};
- uchar TestStr1[] = {"High"};
- uint p,m,i;
- if(c<0)
- {m = 2;}
- else
- {m = 0;}
- i = abs(c);
- p = i*9/5+320;
- M1 = p/1000;
- M2 = p%1000/100;//百位
- M3 = p%1000%100/10;//十位
- M4 = p%10; //個(gè)位
-
- DU = 0;
- WE = 0;//關(guān)閉數(shù)碼管顯示
- LCD_Init();//1602初始化
- LCD_Str(0, 0, &TestStr[0]); //顯示字符串
- LCD_Str(7, 1, &TestStr1[0]); //顯示字符串
- LCD_OneChar(6 , 0, 43+m);//顯示正負(fù)
- LCD_OneChar(7, 0, M1+48); //顯示溫度
- LCD_OneChar(8, 0, M2+48);
- LCD_OneChar(9, 0, M3+48);
- LCD_OneChar(10, 0, 46);
- LCD_OneChar(11, 0, M4+48);
- LCD_OneChar(12, 0, 39);
- LCD_OneChar(13, 0, 67+FF);
- LCD_OneChar(15, 0, 78+DD*10); //顯示蜂鳴器開(kāi)關(guān)
- LCD_OneChar(15, 1, 78+LL*10); //顯示指示燈開(kāi)關(guān)
- }
- void displayLF(int c)
- {
- uchar M1,M2,M3,M4;
- uchar TestStr[] = {"Tem:"};
- uchar TestStr1[] = {"Low"};
- uint p,m,i;
- if(c<0)
- {m = 2;}
- else
- {m = 0;}
- i = abs(c);
- p = i*9/5+320;
- M1 = p/1000;
- M2 = p%1000/100;//百位
- M3 = p%1000%100/10;//十位
- M4 = p%10; //個(gè)位
-
- DU = 0;
- WE = 0;//關(guān)閉數(shù)碼管顯示
- LCD_Init();//1602初始化
- LCD_Str(0, 0, &TestStr[0]); //顯示字符串
- LCD_Str(7, 1, &TestStr1[0]); //顯示字符串
- LCD_OneChar(6 , 0, 43+m);//顯示正負(fù)
- LCD_OneChar(7, 0, M1+48); //顯示溫度
- LCD_OneChar(8, 0, M2+48);
- LCD_OneChar(9, 0, M3+48);
- LCD_OneChar(10, 0, 46); //.
- LCD_OneChar(11, 0, M4+48);
- LCD_OneChar(12, 0, 39); //'
- LCD_OneChar(13, 0, 67+FF);//C或F
- LCD_OneChar(15, 0, 78+DD*10);//X或者N
- LCD_OneChar(15, 1, 78+LL*10); //顯示指示燈開(kāi)關(guān)
- }
- void displayLE()
- {
- uchar TestSt1[] = {"Error"};
- uchar TestSt2[] = {"Low#High"};
- LCD_Init();
- LCD_Str(5, 0, &TestSt1[0]);
- LCD_Str(4, 1, &TestSt2[0]);
- LCD_OneChar(15, 0, 78+DD*10); //顯示蜂鳴器開(kāi)關(guān)
- LCD_OneChar(15, 1, 78+LL*10); //顯示指示燈開(kāi)關(guān)
-
- }
- void write_byte(uchar dat)//寫(xiě)一個(gè)字節(jié)
- {
- uchar i;
- for(i=0;i<8;i++)//一次寫(xiě)一位,一個(gè)字節(jié)循環(huán)8次
- {
- DS = 0;
- _nop_();//產(chǎn)生寫(xiě)時(shí)序(15US內(nèi)滿足要求)
- DS = dat&0X01; //與
- delayus(9);//延時(shí)大于60US 9*6.5+11.95=70.45us 同時(shí)滿足寫(xiě)0寫(xiě)1
- DS = 1;//釋放總線
- _nop_();
- dat>>=1;//右移一位
- }
- }
- uchar read_byte()//讀一個(gè)字節(jié)
- {
- uchar i,j,dat;
- for(i=0;i<8;i++)
- {
- DS = 0;
- _nop_();//產(chǎn)生讀時(shí)序
- DS = 1;
- _nop_();//釋放總線
- j = DS;
- delayus(9);//讀取數(shù)據(jù)大于60US 9*6.5+11.95=70.45us
- DS = 1;
- _nop_();
- dat = (j<<7)|(dat>>1);
- }
- return(dat);
- }
- void beep(int m,gao,di)//按鍵與警報(bào)程序
- {
- if(m>=gao)
- {
- if(di<=gao) //判斷最低報(bào)警溫度是否低于最高報(bào)警溫度
- {
- BP = DD;
- P1 = 0XEE+LL*0X11;
- }
- else if(di>gao)
- {
- BP = 1;
- P1 = 0X7E+LL*0X81;
- }
- }
- else if(m<=di)
- {
- if(di<=gao) //判斷最低報(bào)警溫度是否低于最高報(bào)警溫度
- {
- BP = DD;
- P1=0X77+LL*0X88;
- }
- else if(di>gao)
- {
- BP = 1;
- P1 = 0X7E+LL*0X81;
- }
- }
- else
- {
- if(di<=gao) //判斷最低報(bào)警溫度是否低于最高報(bào)警溫度
- {
- BP = 1;
- P1=0XBB+LL*0X44;
- }
- else if(di>gao)
- {
- BP = 1;
- P1 = 0X7E+LL*0X81;
- }
- }
- }
- void main()
- {
- int i,h;
- uint j=0;
- float t;
- int gao=330,di=270;
- uchar L,H;
- while(1)
- {
- ds_init();//初始化函數(shù)
- write_byte(0XCC);//發(fā)送跳躍ROM指令(0xcc)
- write_byte(0X44);//發(fā)送溫度轉(zhuǎn)換指令(0X44)
- ds_init();//初始化DS18B20
- write_byte(0XCC);//發(fā)送跳躍ROM指令(0xcc)
- write_byte(0XBE);//讀取DS18B20暫存器的值(0Xbe)
- L = read_byte(); //溫度低字節(jié)
- H = read_byte();//溫度高字節(jié)
- i = H;
- i <<=8;
- i|=L;//與,把L寫(xiě)到低字節(jié)里
- if(H >= 0x08) //判斷是否為負(fù)數(shù)
- {
- i = ~i + 1;//負(fù)數(shù)是以補(bǔ)碼的形式存放的需要我們需要取反加1
- s = 2; //顯示負(fù)數(shù)符號(hào)
- }
- else s = 0;
- t=i*0.0625;
- i = t*10;//10.125--101.25--101.75--10.2(四舍五入)
-
- if(key_s1 == 0) //第一位選程序
- {
- delayus(10);//防抖
- if(key_s1 == 0)
- {
- j=j+1 ;
- if(j>=3)
- j=0;
- }
- while(!key_s1);
- }
- if(j==1) //調(diào)最高溫度
- {
- h = gao;
- if(key_s2 == 0)//按鍵2增加溫度
- {
- delayus(20);//防抖
- if(key_s2 == 0)
- {
- h=h+1 ;
- }
- while(!key_s2);
- }
- else if(key_s3 == 0)//按鍵3減小溫度
- {
- delayus(20);
- if(key_s3 == 0)
- {
- h=h-1;
- }
- while(!key_s3);
- }
- if(K==0)
- {
- displayM(h);
- }
- else if(K==1)
- {
- // p = h*(5/9)+320;
- displayMF(h);
- }
- gao = h;
- }
- else if(j==2)//調(diào)最低溫度
- {
- h = di;
- if(key_s2 == 0)//按鍵2增加溫度
- {
- delayus(20);//防抖
- if(key_s2 == 0)
- {
- h=h+1 ;
- }
- while(!key_s2);
- }
- else if(key_s3 == 0)//按鍵3減小溫度
- {
- delayus(20);
- if(key_s3 == 0)
- {
- h=h-1;
- }
- while(!key_s3);
- }
- if(K==0)
- {
- displayL(h);
- }
- else if(K==1)
- {
- // p = h*(5/9)+320;
- displayLF(h);
- }
- di = h;
- }
- else if(j==0) //顯示溫度
- {
- if(key_s2 == 0)//溫度轉(zhuǎn)化
- {
- delayus(20);//防抖
- if(key_s2 == 0)
- {
- K=K+1 ;
- if(K>1)
- K=0;
- }
- while(!key_s2);
- }
- if(key_s3 == 0)//蜂鳴器與指示燈開(kāi)關(guān)
- {
- delayus(20);//防抖
- if(key_s3 == 0)
- {
- M=M+1 ;
- if(M>3)
- M=0;
- }
- while(!key_s3);
- }
- if(K==0)
- {
- FF=0; //攝氏度
- }
- else if(K==1)
- {
- FF=3; //華氏
- }
- /****************判斷蜂鳴器與指示燈開(kāi)關(guān)程序*******************/
- if(M==0) //蜂鳴器關(guān)指示燈開(kāi)
- {
- DD=1;
- LL=0; //蜂鳴器關(guān)
- }
- else if(M==1) //蜂鳴器開(kāi)指示燈開(kāi)
- {
- DD=0;
- LL=0;
- }
- else if(M==2) //蜂鳴器開(kāi)指示燈關(guān)
- {
- DD=0;
- LL=1;
- }
- else if(M==3) //蜂鳴器關(guān)指示燈關(guān)
- {
- DD=1;
- LL=1;
- }
- /*****************溫度顯示及判斷程序執(zhí)行*****************/
- if(K==0) //選擇顯示攝氏度
- {
- if(di>gao)
- displayLE();
- else if(di<=gao)
- displayN(i);
- }
- else if(K==1) //選擇顯示華氏
- {
- if(di>gao)
- displayLE();
- else if(di<=gao)
- displayNF(i);
- }
- beep(i,gao,di);//報(bào)警判斷
- }
- }
- }
- //打開(kāi)是85.0,因?yàn)槌跏贾凳?5.
復(fù)制代碼
|
評(píng)分
-
查看全部評(píng)分
|