2010年11月2日
花了幾個小時,完成“時鐘溫度計” 的程序,在此感謝“康哥”的支持!
功能:時鐘顯示,溫度顯示,可調時間,按鍵發聲。
說明:
1 功能選擇鍵:按下功能選擇鍵,時間停止,秒鐘指示燈長滅,選擇千位,百位,十位,個位,相對應的每位數碼管的小數點亮。
2 “加”:按一下“加”按鍵,對應的數字會加一。
3 “減”:按一下“減”按鍵,對應的數字會減一。
4 繼續按功能選擇鍵到第五次,退出時間設置,秒鐘指示燈閃爍,時鐘繼續運行。
5 初始化時間為早上6點30分,時間為24小時制。
6 其他功能:添加指示燈。正常運行時,綠色指示燈亮,當進入調整時間時,紅色指示燈亮。
限于篇幅以下是部分源代碼,完整版本請到http://www.velo-sur-mesure.com/f/shiz5.rar 去下載
#include"reg51.h" #define uchar unsigned char #define uint unsigned int /****溫度 端口定義******/ sbit wx5=P2^5; sbit wx6=P2^6; sbit wx7=P2^7; sbit DQ=P2^0; uint temp, temp1,temp2, xs; uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99, 0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6}; /******延時程序*******/ void delay1(unsigned int m) { unsigned int i,j; for(i=m;i>0;i--) for(j=110;j>0;j--); } void delay(unsigned int m) { while(m--); } void Init_DS18B20() { unsigned char x=0; DQ = 1; //DQ復位 ds18b20通信端口 delay(8); //稍做延時 DQ = 0; //單片機將DQ拉低 delay(80); //精確延時 大于 480us DQ = 1; //拉高總線 delay(4); x=DQ; //稍做延時后 如果x=0則初始化成功 x=1則初始化失敗 delay(20); } /***********ds18b20讀一個字節**************/ uchar ReadOneChar() { unsigned char i=0; unsigned char dat = 0; for (i=8;i>0;i--) { DQ = 0; // 高電平拉成低電平時讀周期開始 dat>>=1; DQ = 1; // 給脈沖信號 if(DQ) dat|=0x80; // delay(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(5); //60us到120us延時 DQ = 1; dat>>=1; //從最低位到最高位傳入 } } /**************讀取ds18b20當前溫度************/ void ReadTemperature() { unsigned char a=0; unsigned b=0; unsigned t=0; Init_DS18B20(); WriteOneChar(0xCC); // 跳過讀序號列號的操作 WriteOneChar(0x44); // 啟動溫度轉換 delay(10); // this message is wery important Init_DS18B20(); WriteOneChar(0xCC); //跳過讀序號列號的操作 WriteOneChar(0xBE); //讀取溫度寄存器等(共可讀9個寄存器) 前兩個就是溫度 delay(10); 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 } ////////////////////////////////////////////////////////////////////////////// /***********溫度顯示********************/ void wenduxianshi() //溫度顯示 { wx5=1; P0=table[temp/10]; delay1(3); wx5=0; wx6=1; P0=table[temp%10]; delay1(3); wx6=0; wx7=1; P0=table[12]; delay1(3); wx7=0; } //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// /****時鐘 端口定義******/ sbit wx1=P2^1; sbit wx2=P2^2; sbit wx3=P2^3; sbit wx4=P2^4; uchar qian,bai,shi,ge,miao1,miao2,count; sbit LED1=P3^3; //////////////////////////////////////////// /***************按鍵調時程序***************/ sbit K1=P3^0; sbit K2=P3^1; sbit K3=P3^2; sbit LVSE =P3^4; //綠色運行燈 sbit HONGSE =P3^5; //紅色停止燈 sbit HUANGSE=P3^6; //黃色調鬧鐘燈 sbit BEEP=P3^7; //// 定義蜂鳴器口 uchar K1num,K2num; ////////////////////////////////////////// /**********報警聲音**************/ bi(uint t) { int c,n; for(c=0;c<t;c++) { for(n=0;n<50;n++); BEEP=~BEEP; //按位取反BEEP } return(t); } /////////////////////////////////////////////// /********定時器初始化*************/ void init() { 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=50; TL0=50; count++; if( count==20 ) { count=0; LED1=~LED1; miao1++; if( miao1==10 ) { miao1=0; miao2++; } if( miao2== 6 ) { miao2=0; ge++; } if( ge==10 ) { ge=0; shi++; } if( shi== 6 ) { shi=0; bai++; } if( bai==10 ) { bai=0; qian++; } if( qian== 3 ) { qian=0; } if(qian==2&&bai==4){qian=0;bai=0; } } } ////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////// /**********時間顯示***************/ void shijianxianshi() //時間顯示 { if( K1num==0 ) //復位 { TR0=1;LVSE=0; HONGSE=1;HUANGSE=1; wx1=1; P0=table[qian]; delay1(3); wx1=0; wx2=1; P0=table[bai]; delay1(3); wx2=0; wx3=1; P0=table[shi]; delay1(3); wx3=0; wx4=1; P0=table[ge]; delay1(3); wx4=0; } /**************************************/ if( K1num==1 ) //選擇千位 { TR0=0;LED1=1;LVSE=1; HONGSE=0; HUANGSE=1; wx1=1; P0=table[qian]+0x80; delay1(3); wx1=0; wx2=1; P0=table[bai]; delay1(3); wx2=0; wx3=1; P0=table[shi]; delay1(3); wx3=0; wx4=1; P0=table[ge]; delay1(3); wx4=0; } /**************************************/ if( K1num==2 ) //選擇百位 { wx1=1; P0=table[qian]; delay1(3); wx1=0; wx2=1; P0=table[bai]+0x80; delay1(3); wx2=0; wx3=1; P0=table[shi]; delay1(3); wx3=0; wx4=1; P0=table[ge]; delay1(3); wx4=0; } /**************************************/ if( K1num==3 ) //選擇十位 { wx1=1; P0=table[qian]; delay1(3); wx1=0; wx2=1; P0=table[bai]; delay1(3); wx2=0; wx3=1; P0=table[shi]+0x80; delay1(3); wx3=0; wx4=1; P0=table[ge]; delay1(3); wx4=0; } /**************************************/ if( K1num==4 ) //選擇個位 { wx1=1; P0=table[qian]; delay1(3); wx1=0; wx2=1; P0=table[bai]; delay1(3); wx2=0; wx3=1; P0=table[shi]; delay1(3); wx3=0; wx4=1; P0=table[ge]+0x80; delay1(3); wx4=0; } } //////////////////////////////////////////////////////////////////////////////////// ///////////////////按鍵功能設置///////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////// void keycan() { ///////////////////時鐘功能設置//////////////////////// /**********調時間功能選擇**********/ if( K1==0 ) { K1num++; delay(5); if( K1==0 ) { while(!K1); bi(200); if(K1num==5 ) { K1num=0;TR0=1;} } } /////////////////////////////////////////////////// /*********功能加*********/ if( K1num!=0 ) { if( K2==0 ) { delay(5); if( K2==0 ) { while(!K2);bi(200); if( K1num==1 ) { qian++; if(qian==3 ) qian=0; } if( K1num==2 ) { bai++; if( bai==10) bai=0; } if( K1num==3 ) { shi++; if( shi==6 ) shi=0; } if( K1num==4 ) { ge++; if( ge==10) ge=0; } } } } ////////////////////////////////////////////////////////// /**********功能減************/ if( K1num!=0 ) { if( K3==0 ) { delay(5); if( K3==0 ) { while(!K3);bi(200); if( K1num==1 ) { qian--; if(qian==-1) qian=2; } if( K1num==2 ) { bai--; if( bai==-1) bai=9; } if( K1num==3 ) { shi--; if( shi==-1) shi=5; } if( K1num==4 ) { ge--; if( ge==-1) ge=9; } } } } } ///////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////// /***********主函數********************/ //////////////////////////////////////////////////////////// void main() { init(); qian=0;bai=6;shi=3;ge=0;miao2=0;miao1=0; while(1) { ReadTemperature(); wenduxianshi(); keycan(); shijianxianshi(); } }