`本设计所介绍的数字温度计与传统的温度计相比,具有读数方便,测温范围广,测温准确,其输出温度采用数字显示,主要用于对测温比较准确的场所,或科研实验室使用,该设计控制器使用单片机AT89S51,测温传感器使用DS18B20,用3位共阳极LED数码管以串口传送数据,实现温度显示,能准确达到以上要求。
- #include
- #include
- #include
- code unsigned char seg7code[11]=
- { 0xc0,0xf9,0xa4,0xb0,0x99,0x92,
- 0x82,0xf8,0x80,0x90,0x40}; //显示段码
-
- ***it TMDAT =P3^1; //DS18B20 的数据输入/输出脚DQ,根据情况设定
-
- ***it jia=P2^1;
- ***it jian=P2^0;
- ***it hong=P1^0;//红色警告灯
- ***it sheng=P1^1;//蜂鸣器
- ***it lan=P1^2;//兰色灯
- bit write=0; //写24C08 的标志;
-
- j=30;
- unsigned int sdata;//测量到的温度的整数部分
- unsigned char xiaoshu1;//小数第一位
- unsigned char xiaoshu2;//小数第二位
- unsigned char xiaoshu;//两位小数
-
- bit fg=1; //温度正负标志
-
- ////////24C08 读写驱动程序////////////////////
- ***it scl=P3^4; // 24c08 SCL
- ***it sda=P3^5; // 24c08 SDA
- void delay1(unsigned char x)
- { unsigned int i;
- for(i=0;i
- ;}
- void flash()
- { ; ; }
- void x24c08_init() //24c08 初始化子程序
- {scl=1; flash(); sda=1; flash();}
- void start() //启动(I方C)总线
- {sda=1; flash(); scl=1; flash(); sda=0; flash(); scl=0; flash();}
- void stop() //停止(I方C)总线
- {sda=0; flash(); scl=1; flash(); sda=1; flash();}
- void writex(unsigned char j) //写一个字节
- { unsigned char i,temp;
- temp=j;
- for (i=0;i<8;i++)
- {temp=temp<<1; scl=0; flash(); sda=CY; flash(); scl=1; flash();}
- scl=0; flash(); sda=1; flash();
- }
- unsigned char readx() //读一个字节
- {
- unsigned char i,j,k=0;
- scl=0; flash(); sda=1;
- for (i=0;i<8;i++)
- {
- flash(); scl=1; flash();
- if (sda==1) j=1;
- else j=0;
- k=(k<<1)|j;
- scl=0;}
- flash(); return(k);
- }
- void clock() //(I方C)线时钟
- {
- unsigned char i=0;
- scl=1; flash();
- while ((sda==1)&&(i<255))i++;
- scl=0; flash();
- }
- //从24c02 的地址address 中读取一个字
- unsigned char x24c08_read(unsigned char address)
- {
- unsigned char i;
- start(); writex(0xa0);
- clock(); writex(address);
- clock(); start();
- writex(0xa1); clock();
- i=readx(); stop();
- delay1(10);
- return(i);
- }
- //向24c02 的address 地址中写入一字节数据info
- void x24c08_write(unsigned char address,
- unsigned char info)
- {
- EA=0;
- start(); writex(0xa0);
- clock(); writex(address);
- clock(); writex(info);
- clock(); stop();
- EA=1;
- delay1(50);
- }
- /*////////////24C08 读写驱动程序完/////////////////////
- void Delay2(unsigned int tc) //延时程序
- {
- while( tc != 0 )
- {unsigned int i;
- for(i=0; i<100; i++);
- tc--;}
- }
- */
- //////////*显示延时程序*///////////////
- void Delay(unsigned int tc)
- {while( tc != 0 )
- {unsigned int i;
- for(i=0; i<80; i++);
- tc--;}
- }
-
- ////////////延时部分///////////////
- void yanshi (unsigned int count)
- {
- unsigned char i;
- while(count--)
- {for(i=0;i<115;i++);}
- }
-
- /////////////发送复位///////////////
- void fashong (void)
- {
- unsigned char i;
- TMDAT = 0; for(i=0;i<103;i++);
- TMDAT = 1; for(i=0;i<4;i++);
- }
-
- bit tmrbit (void) //读一位//
- {
- unsigned int i;
- bit dat;
- TMDAT = 0;
- i++;
- TMDAT = 1;
- i++; i++; //微量延时 //
- dat = TMDAT;
- for(i=0;i<8;i++);
- return (dat);
- }
-
- unsigned char tmrbyte (void) //读一个字节
- {
- unsigned char i,j,dat;
- dat = 0;
- for (i=1;i<=8;i++)
- { j = tmrbit(); dat = (j << 7) | (dat >> 1); }
- return (dat);
- }
- //写一个字节
- void tmwbyte (unsigned char dat)
- {
- unsigned char j,i;
- bit testb;
- for (j=1;j<=8;j++)
- { testb = dat & 0x01;
- dat = dat >> 1;
- if (testb)
- { TMDAT = 0; //写0
- i++; i++;
- TMDAT = 1;
- for(i=0;i<8;i++); }
- else
- { TMDAT = 0; //写0
- for(i=0;i<8;i++);
- TMDAT = 1;
- i++; i++;}
- }
- }
- void tmstart (void) //发送ds1820 开始转换
- {
- fashong(); //复位
- yanshi(1); //延时
- tmwbyte(0xcc); //跳过序列号命令
- tmwbyte(0x44); //发转换命令 44H,
- }
- void tmrtemp (void) //读取温度
- {
- unsigned char a,b;
- fashong (); //复位
- yanshi (1); //延时
- tmwbyte (0xcc); //跳过序列号命令
- tmwbyte (0xbe); //发送读取命令
- a = tmrbyte (); //读取低位温度
- b = tmrbyte (); //读取高位温度
- if(b>0x7f) //最高位为1 时温度是负
- {a=~a; b=~b+1; //补码转换,取反加一
- fg=0; //读取温度为负时fg=0
- }
- sdata = a/16+b*16; //整数部分
- xiaoshu1 = (a&0x0f)*10/16; //小数第一位
- xiaoshu2 = (a&0x0f)*100/16%10;//小数
- xiaoshu=xiaoshu1*10+xiaoshu2; //小数
- }
- void DS18B20PRO(void)
- {
- tmstart();
- //yanshi(5); //如果是不断地读取的话可以不延
- tmrtemp(); //读取温度,执行完毕温度将存于
- }
- void Led()
- {
- if(fg==1) //温度为正时显示的数据
- {
- P2=P2&0xef;
- P0=seg7code[sdata/10]; //输
- Delay(2); P2=P2|0xf0; P2=P2&0xdf;
- P0=seg7code[sdata%10]|0x80; //输出个
- Delay(2); P2=P2|0xf0; P2=P2&0xbf;
- P0=seg7code[xiaoshu1]; //输出小数点
- Delay(2); P2=P2|0xf0; P2=P2&0x7f;
- P0=seg7code[xiaoshu2]; //输出小
- Delay(1); P2=P2|0xf0;
- Delay(2); P2=P2|0xf0;P2=P2&0xf7;
- P0=seg7code[j/10]; //输出十位
- Delay(2); P2=P2|0x0f; P2=P2&0xfb;
- P0=seg7code[j%10]|0x80; //输出个位
- Delay(1); P2=P2|0x0f;
-
- if(sdata<=j)
- {
- lan=0;
- hong=1;
- sheng=1;
- };
- if(sdata>=j)
- {
- lan=1;
- hong=0;
- sheng=0;
- };
- }
- if(fg==0) //温度为负时显示的数据
- { P2=P2&0xef;
- P0=seg7code[11]; //负号
- Delay(8); P2=P2|0xf0; P2=P2&0xdf;
- P0=seg7code[sdata/10]|0x80; //输出十位
- Delay(8); P2=P2|0xf0; P2=P2&0xbf;
- P0=seg7code[sdata%10]; //输出个位
- Delay(8); P2=P2|0xf0; P2=P2&0x7f;
- P0=seg7code[xiaoshu1]; //输出小
- Delay(4); P2=P2|0xf0;
- }
- }
- main()
- {fg=1;
- x24c08_init(); //初始化24C08
- j=x24c08_read(2);//读出保存的数据
- while(1)
- {
- DS18B20PRO();
- Led();
- if(jia==0)
- {Delay(200);j++;}
- if(jian==0)
- {Delay(200);j--;}
- x24c08_write(2,j);
- }
- }
复制代码
`
|