2010年11月2日
花了几个小时,完成“时钟温度计” 的程序,在此感谢“康哥”的支持!
功能:时钟显示,温度显示,可调时间,按键发声。
说明:
1 功能选择键:按下功能选择键,时间停止,秒钟指示灯长灭,选择千位,百位,十位,个位,相对应的每位数码管的小数点亮。
2 “加”:按一下“加”按键,对应的数字会加一。
3 “减”:按一下“减”按键,对应的数字会减一。
4 继续按功能选择键到第五次,退出时间设置,秒钟指示灯闪烁,时钟继续运行。
5 初始化时间为早上6点30分,时间为24小时制。
6 其他功能:添加指示灯。正常运行时,绿色指示灯亮,当进入调整时间时,红色指示灯亮。
限于篇幅以下是部分源代码,完整版本请到http://www.51hei.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(); } }