这个程序是我用了几天的课外时间编写成功的,程序有的复杂,但只要你思路清楚,就算我没有作注解的相信你也看得懂,可能你的想法比我的还好,我的程序不是编写温控程序的最好的,我只是来和有兴趣的人学习的。
这个程序有几个关键点,一是要看懂DS18B20的时序,程序采用现在主流的C语言编写,汇编语言很复杂,但是汇编语言有它的好处,这里就不说了,程序最小精度是0.1摄氏度!
以后是程序
/****************ds18b20数字温度控制程序*******朱可瑀于实验室**************************/
/***************2011.6.8***************************************/
#include <at89x51.h>
#define uint unsigned int
#define uchar unsigned char
uchar tplsb,tpmsb;
sbit DQ = P3^6;
uchar code LEDData[12]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xbf,0xff};//0~9,-,no
uchar code point[16]={0,1,1,2,2,3,4,4,5,6,6,7,7,8,9,9};
uchar temp_d[4]={0,0,0,0};
void delay(uint t)//延时t ms
{
uint i;
while(t--)
{
for(i=0;i<125;i++);
}
}
void delay1(int n)
{
while(n--);
}
void TxReset(void)//产生复位脉冲初始化ds18b20
{
uint i;
DQ = 0;
//拉低900us
i=100;
while(i>0) i--;
DQ = 1;
i=4;
while(i>0)i--;
}
void RxWait(void)//等待应答信号
{
uint i;
while(DQ);
while(~DQ);
i=4;
while(i>0) i--;
}
uchar RdByte(void)//读取数据的一个字节
{
uchar i = 0;
uchar b = 0;
for (i=8;i>0;i--)
{
DQ = 0; // 给脉冲信号
b>>=1;
DQ = 1; // 给脉冲信号
if(DQ)
b|=0x80;
delay1(4);
}
return b;
}
void WrByte(uchar b)//写数据的一个字节
{
uint i;
uchar j;
bit btmp;
for(j=1;j<=8;j++)
{
btmp = b&0x01;
b=b>>1;
if(btmp) //write 1
{
DQ=0;
i++;i++; //15us
DQ=1;
i=8;
while(i>0) i--; //>60us
}
else
{
DQ=0;
i=8;
while(i>0) i--;//60us~120us
DQ=1;
i++;i++;
}
}
}
void convert(void)//启动温度转换
{
TxReset();
RxWait();
delay(1);
WrByte(0xcc);
WrByte(0x44);
}
uint RdTemp(void)//读取温度值
{
uint wendu;
TxReset();
RxWait();
delay(1);
WrByte(0xcc);
WrByte(0xbe);
tplsb = RdByte( );
tpmsb = RdByte( );
wendu=tpmsb;
wendu<<=8;
wendu+=tplsb;
return wendu;
}
void zhuanhuan(uint temprature)
{
uchar zs,xs;
uint fs;
if(temprature<0x07ff)//>=0
{
zs=(uchar)(temprature>>4);
xs=(uchar)(temprature&0x000f);
if(zs<100)
{
temp_d[0]=11;
temp_d[1]=zs/10;
if(temp_d[1]==0)
{
temp_d[1]=11;
temp_d[2]=zs%10;
temp_d[3]=point[xs];
}
temp_d[2]=zs%10;
temp_d[3]=point[xs];
}
else
{
temp_d[0]=zs/100;
temp_d[1]=zs/10%10;
temp_d[2]=zs%10;
temp_d[3]=point[xs];
}
}
else //<0
{
fs=~temprature+1;
zs=(uchar)(fs>>4);
xs=(uchar)(fs&0x000f);
if(zs<100)
{
temp_d[0]=10;
temp_d[1]=zs/10;
if(temp_d[1]==0)
{
temp_d[1]=11;
temp_d[2]=zs%10;
temp_d[3]=point[xs];
}
temp_d[2]=zs%10;
temp_d[3]=point[xs];
}
else
{
temp_d[0]=zs/100;
temp_d[1]=zs/10%10;
temp_d[2]=zs%10;
temp_d[3]=point[xs];
}
}
}
void display( ) //温度显示
{
P2=0x01;
delay1(3);
P0=LEDData[temp_d[0]];
delay(3);
P2=0X02;
delay1(3);
P0=LEDData[temp_d[1]];
delay(3);
P2=0X04;
delay1(3);
P0=LEDData[temp_d[2]]&0x7f;
delay(3);
P2=0X08;
P0=LEDData[temp_d[3]];
delay1(3);
delay(3);
}
void main( )
{
uint wendu;
while(1)
{
TxReset( );
RxWait( );
convert( );
wendu=RdTemp( );
zhuanhuan( wendu );
display( );
}
}