此程序是在上一個程序進行修改而來,把年月日刪除,替換為可調溫度上下限。
帶有可調時間星期功能,按鍵發聲功能,手動設定溫度上下限功能,溫度報警功能,適用于AT89S52芯片。芯片內存剩余3.8K。
程序 #include"reg51.h" #define uchar unsigned char #define uint unsigned int sbit BEEP=P3^7; //// 定義蜂鳴器口 unsigned char L,H; //// 定義高低溫度變量 ///////////////////////////////////////////////////////////////////////////////////////////////// /**********報警聲音**************/ void bi(uint t) { int c,n; for(c=0;c<t;c++) { for(n=0;n<50;n++); BEEP=~BEEP; //按位取反BEEP } //return(t); } /////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////// /**********18b20溫度程序**********/ sbit DQ=P3^6; //定義溫度數據口 int xs; //定義小數 unsigned int temp,temp1,temp2; //定義溫度轉換變量 ////////////////////////////////////////////////////////////////////////////////////////////// /*********18B20延時程序************/ void delay_18B20(unsigned int i) { while(i--); } ////////////////////////////////////////////////////////////////////////////////////////////// /*********ds18b20初始化函數*********/ void Init_DS18B20(void) { unsigned char x=0; DQ = 1; //DQ復位 ds18b20通信端口 delay_18B20(8); //稍做延時 DQ = 0; //單片機將DQ拉低 delay_18B20(80); //精確延時 大于 480us DQ = 1; //拉高總線 delay_18B20(4); x=DQ; //稍做延時后 如果x=0則初始化成功 x=1則初始化失敗 delay_18B20(20); } /////////////////////////////////////////////////////////////////////////////////////////// /********ds18b20讀一個字節**********/ unsigned char ReadOneChar(void) { unsigned char i=0,dat = 0; for (i=8;i>0;i--) { DQ = 0; //高電平拉成低電平時讀周期開始 dat>>=1; DQ = 1; //給脈沖信號 if(DQ) dat|=0x80; delay_18B20(4); } return(dat); } ////////////////////////////////////////////////////////////////////////////////////////// /*************ds18b20寫一個字節****************/ void WriteOneChar(unsigned char dat) { unsigned char i=0; for (i=8; i>0; i--) { DQ = 0; //從高電平拉至低電平時,寫周期的開始 DQ = dat&0x01; //數據的最低位先寫入 delay_18B20(5); //60us到120us延時 DQ = 1; dat>>=1; //從最低位到最高位傳入 } } //////////////////////////////////////////////////////////////////////////////////////////// /**************讀取ds18b20當前溫度************/ void ReadTemperature(void) { unsigned char a=0,b=0,t=0; Init_DS18B20 ( ); WriteOneChar ( 0xCC ); // 跳過讀序號列號的操作 WriteOneChar ( 0x44 ); // 啟動溫度轉換 delay_18B20 ( 100 ); // this message is wery important Init_DS18B20 ( ); WriteOneChar ( 0xCC ); //跳過讀序號列號的操作 WriteOneChar ( 0xBE ); //讀取溫度寄存器等(共可讀9個寄存器) 前兩個就是溫度 delay_18B20 ( 100 ); a=ReadOneChar( ); //讀取溫度值低位 b=ReadOneChar( ); //讀取溫度值高位 temp1 = b<<4; //高8位中后三位數的值 temp1+= ( a&0xf0 )>>4; //低8位中的高4位值加上高8位中后三位數的值 temp1室溫整數值 temp2 = a&0x0f; //小數的值 temp = ( ( b*256+a ) >>4 ); //當前采集溫度值除16得 實際溫度值 zhenshu xs=temp2*0.0625*10; //小數位,若為0.5則算為5來顯示 xs小數 xiaoshu } ///////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////// /*********************1602液晶程序********************/ /******定義液晶控制口*******/ sbit lcdrs=P2^5; //定義液晶三個控制口 sbit lcdrw=P2^6; sbit lcden=P2^7; sbit K1=P3^0; //定義三個開關 sbit K2=P3^1; sbit K3=P3^2; ///////////////////////////////////////////////////////////////////////////////////////////////// /******定義變量*******/ uchar count,shi,fen,miao,xq,K1num; //定義時間程序里所需要的變量 ///////////////////////////////////////////////////////////////////////////////////////////////// /******定義數組*******/ uchar code table [ ]= "TH:38 TL:25 XQ:7"; //液晶界面顯示的內容 uchar code table1[ ]= "23:59:55 . C"; ////////////////////////////////////////////////////////////////////////////////////////////////// /******延時程序*******/ void delay(uint m) //液晶延時程序 { uint i,j; for(i=m;i>0;i--) for(j=110;j>0;j--); } /////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// /**********寫指令*************/ void write_com(uchar com) { lcdrs=0; lcdrw=0; lcden=0; P0=com; delay(5); lcden=1; delay(5); lcden=0; } ///////////////////////////////////////////////////////////////////////////////////// /************寫數據*************/ void write_data(uchar date) { lcdrs=1; lcdrw=0; lcden=0; P0=date; delay(5); lcden=1; delay(5); lcden=0; } /////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////// /***************液晶顯示程序***************/ /*********時分秒數的分離**********/ void write_sfm(uchar add,uchar date) { uchar shi,ge; //分離數字,如35,分成3和5 shi=date/10; ge=date%10; write_com ( 0x80+0x40+add ); write_data ( 0x30+shi ); write_data ( 0x30+ge ); } ////////////////////////////////////////////////////////////////// /**********星期***********/ void write_xq(uchar add1,uchar date1) { uchar ge; //星期只需要一個數字顯示 ge=date1%10; write_com ( 0x80+add1 ); write_data ( 0x30+ge ); } //////////////////////////////////////////////////////////////// /************高溫低溫數的分離************/ void write_HL(uchar add2,uchar date2) { uchar shi,ge; shi=date2/10; ge=date2%10; write_com(0x80+add2); write_data(0x30+shi); write_data(0x30+ge); } ///////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////// /***************按鍵調時程序***************/ void keycan() { /**********功能選擇**********/ if( K1==0 ) { K1num++; delay(2); if( K1==0 ) { while(!K1);bi(300); if( K1num==1 ) { TR0=0; write_com ( 0x80+0x40+7 ); write_com(0x0f); } if( K1num==2 ) { write_com ( 0x80+0x40+4 ); } if( K1num==3 ) { write_com ( 0x80+0x40+1 ); } if( K1num==4 ) { write_com ( 0x80+15 ); } if( K1num==5 ) { write_com ( 0x80+10 ); } if( K1num==6 ) { write_com ( 0x80+4 ); } if( K1num==7 ) { K1num=0; write_com(0x0c); TR0=1; } } } ///////////////////////////////////////////////////////////////////////////////////////////////// /*********功能加*********/ if( K1num!=0 ) { if( K2==0 ) { delay(2); if( K2==0 ) { while(!K2);bi(300); if( K1num==1 ) { miao++; if( miao==60 ) miao=0; write_sfm ( 6,miao); write_com ( 0x80+0x40+7 ); } if( K1num==2 ) { fen++; if( fen==60 ) fen=0; write_sfm ( 3,fen ); write_com ( 0x80+0x40+4 ); } if( K1num==3 ) { shi++; if( shi==24 ) shi=0; write_sfm ( 0,shi ); write_com ( 0x80+0x40+1 ); } if( K1num==4 ) { xq++; if( xq==8 ) xq=1; write_xq (15,xq ); write_com ( 0x80+15 ); } if( K1num==5 ) { L++; if( L==100) L=0; write_HL( 9,L ); write_com ( 0x80+10 ); } if( K1num==6 ) { H++; if( H==100) H=0; write_HL( 3,H ); write_com ( 0x80+4 ); } } } } //////////////////////////////////////////////////////////////////////////////////////////////////////////////// /**********功能減************/ if(K1num!=0) { if(K3==0 ) { delay(2); if(K3==0 ) { while(!K3); bi(300); if( K1num==1 ) { miao--; if( miao==-1 ) miao=59; write_sfm ( 6, miao); write_com ( 0x80+0x40+7 ); } if( K1num==2 ) { fen--; if( fen==-1 ) fen =59; write_sfm ( 3, fen ); write_com ( 0x80+0x40+4 ); } if( K1num==3 ) { shi--; if( shi==-1 ) shi =23; write_sfm ( 0, shi ); write_com ( 0x80+0x40+1 ); } if( K1num==4 ) { xq--; if( xq==0 ) xq = 7; write_xq (15, xq ); write_com ( 0x80+15 ); } if( K1num==5 ) { L--; if( L==-1 ) L=99; write_HL ( 9,L ); write_com ( 0x80+10 ); } if( K1num==6 ) { H--; if( H==-1 ) H=99; write_HL ( 3,H ); write_com ( 0x80+4 ); } } } } } //////////////////////////////////////////////////////////////////////////////////////////////////// /*************初始化**************/ void init() { uchar num; //定義一個變量num,用于下面數組的初始化// lcden=0; write_com ( 0x38 ); write_com ( 0x0c ); //不顯示光標 write_com ( 0x06 ); //光標向右邊自動移位 write_com ( 0x01 ); //清屏 shi=23; fen=59; miao=55; xq=7; H=38;L=25; write_com ( 0x80 ); for( num=0; num<16; num++ ) { write_data( table[num] ); delay(10); } write_com ( 0x80+0x40 ); for( num=0; num<16; num++ ) { write_data( table1[num] ); delay(10); } /////////////////////////////////////////////////////////////////////////////////////// /********定時器初始化*************/ TMOD=0x01; //定義定時器0,工作方式1 TH0=(65536-50000)/256; //高8位 TL0=(65536-50000)%256; //低8位 EA=1; //開全局中斷 ET0=1; TR0=1; //打開定時器 } /////////////////////////////////////////////////////////////////////////////////////////////////////// /***********定時器中斷函數************/ void timer0() interrupt 1 { TH0=(65536-50000)/256; TL0=(65536-50000)%256; count++; if( count==20 ) { count=0; miao++; if( miao==60 ) { miao=0; fen++; } if( fen==60 ) { fen=0; shi++; } if( shi==24 ) { shi=0; xq++; if( xq==8 ) { xq=1; } } } } /////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////// /*****************************************/ uchar code mytab[8]={0x0C,0x12,0x12,0x0C,0x00,0x00,0x00,0x00}; /* 設定顯示位置 /**************************************/ void lcd_pos(uchar pos) { write_com(pos | 0x80) ; //數據指針=80+地址變量 } ///////////////////////////////////////////////////////////////////////////// /*自定義字符寫入CGRAM /*********************************/ void writetab() { unsigned char i ; write_com(0x40) ; //寫CGRAM for (i = 0 ; i< 8 ; i++) write_data(mytab[ i ]) ; } ///////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// void wendu() /////溫度顯示程序///// { writetab( ) ; //自定義字符寫入CGRAM delay ( 5 ) ; lcd_pos ( 0x4e ) ; //顯示圈圈 write_data( 0x00 ) ; //顯示自定義字符 write_com ( 0x0c ); ReadTemperature(); write_com ( 0x80+0x40+10 ); write_data ( 0x30+temp/10 ); write_com ( 0x80+0x40+11 ); write_data ( 0x30+temp%10 ); write_com ( 0x80+0x40+13 ); write_data ( 0x30+xs%10 ); /////時間顯示地址///// write_sfm( 6,miao ); write_sfm( 3,fen ); write_xq (15,xq ); write_sfm( 0,shi ); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// //////溫度報警程序////// void baojing() { if(H==temp) { bi(500); } if(L==temp) { bi(500); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /***************主函數***************/ void main() { init(); while(1) { keycan(); wendu(); baojing(); } }