//Program function: Test the current ambient temperature through DS18B20, and display the current temperature value through the digital tube
#include "reg52.h"
#include
#include
#define uchar unsigned char
#define uint unsigned int
sbit we=P2^7;//Nigital tube bit selection
sbit du=P2^6; //Nigital tube segment selection
sbit dio=P2^5;
sbit ds=P2^2;
int tempValue1;
unsigned int temp;
uchar code th0=(65535-3000)/256;
uchar code tl0=(65535-3000)%256;
uchar dispbuf[6];
uchar code disptab[]={0x3f,0x6,0x5b,0x4f,0x66,
0x6d,0x7d,0x27,0x7f,0x6f,0x77,0x7c,0x39,0x5e,
0x79,0x71,0x0};
uchar code disptabwithdot[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0xa7,0xff,0xef,0xf7,
0xfc,0xb9,0xf9,0xf1};
uchar code dispbit[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf};
//Delay function, for 11.0592MHz clock, for example i=10, the delay is about 10ms.
void delay(unsigned int i)
{
unsigned int j;
p>
while(i--)
{
for(j = 0; j < 125; j++);
}
}
void dsInit()
{
//For 11.0592MHz clock, unsigned int type i, the time to perform an i++ operation Greater than ?us
unsigned int i;
ds = 0;
i = 100; //Pull down about 800us, more than 480us in line with the protocol requirements< /p>
while(i>0) i--;
ds = 1; //Generate a rising edge and enter the waiting response state
i = 4;< /p>
while(i>0) i--;
}
void dsWait()
{
unsigned int i;
while(ds);
while(~ds); //Response pulse detected
i = 4;
while(i > 0) i--;
}
//Read one bit of data from DS18B20
//Read one bit, Let DS18B20 be at low level for a short period, and then be at high level for two small periods,
//After that, DS18B20 will output one bit of data for a period of time
bit readBit()< /p>
{
unsigned int i;
bit b;
ds = 0;
i++; // The delay is about 8us, and the delay is at least 1us if it meets the protocol requirements
ds = 1;
i++; i++; //The delay is about 16us, and the delay is at least 15us if it meets the protocol requirements< /p>
b = ds;
i = 8;
while(i>0) i--; //The delay is about 64us, which is consistent with the read time slot. Less than 60us requirement
return b;
}
//Read one byte of data, achieved by calling readBit()
< p>unsigned char readByte(){
unsigned int i;
unsigned char j, dat;
dat = 0;
for(i=0; i<8; i++)
{
j = readBit();
//most The lowest bit of data is read out first
dat = (j << 7) | (dat >> 1);
}
return dat;< /p>
}
//Write one byte of data to DS18B20
void writeByte(unsigned char dat)
{
unsigned int i;
unsigned char j;
bit b;
for(j = 0; j < 8; j++)
{
b = dat & 0x01;
dat >>= 1;
//Write "1", pull DQ low for 15us After that, pull DQ high within 15us~60us to complete writing 1
if(b)
{
ds = 0;
i++; i++; // Pull down about 16us, the symbol must be within 15~60us
ds = 1;
i = 8; while(i>0) i- -; //The delay is about 64us, which meets the requirement of writing time slot not less than 60us
}
else //Write "0", pull DQ low for 60us~120us
p>ds = 0;
i = 8; while(i>0) i--; // Pull down about 64us, symbol requirements
ds = 1;
i++; i++; //The entire process of writing a 0 time slot has exceeded 60us, so there is no need to delay another 64us like writing a 1
}
}
//Send temperature conversion command to DS18B20
void sendChangeCmd()
{
dsInit(); //Initialization DS18B20, no matter what command, initialization must be initiated first
dsWait(); //Wait for DS18B20 response
delay(1); //Delay 1ms, because DS18B20 will pull low DQ 60~240us as response signal
writeByte(0xcc); //Write skip sequence number command word Skip Rom
writeByte(0x44); //Write temperature conversion command Word Convert T
}
//Send read data command to DS18B20
void sendReadCmd()
{ EA=0; //Turn off interrupts because entering the display interrupt will affect the read and write timing of DS18B20
dsInit();
dsWait();
delay(1) ;
writeByte(0xcc); //Write skip sequence number command word Skip Rom
writeByte(0xbe); //Write read data command word Read Scratchpad p>
EA=1;
}
//Get the current temperature value
int getTmpValue()
{< /p>
unsigned int tmpvalue;
int value; //Storage temperature value
float t;
unsigned char low, high; p>
EA=0;
sendReadCmd();
//Continuously read two bytes of data
low = readByte();
high = readByte();
//Combine the high and low bytes into an integer variable
//Computers use complement codes to calculate negative numbers. Represented
//If it is a negative value, the read value is expressed in complement and can be directly assigned to an int value
tmpvalue = high;
tmpvalue <<= 8;
tmpvalue |= low;
value = tmpvalue;
//Use the default resolution of DS18B20, 12 bits, The accuracy is 0.0625 degrees, that is, the lowest bit of the read back data represents 0.0625 degrees
t = value * 0.0625;
//Enlarge it 100 times so that the decimal point can be displayed during display The last two digits, and round the third decimal point by 4 or 5
//For example, t=11.0625, after counting, we get value = 1106, which is 11.06 degrees
// For example, t=-11.0625, after counting, we get value = -1106, which is -11.06 degrees
value = t * 100 + (value > 0 ? 0.5 : -0.5); //If it is greater than 0, add 0.5 , less than 0 minus 0.5
return value;
EA=1;
}
void Init_timer0()
< p>{TMOD=0x01;
TH0=th0;
TL0=tl0;
EA=1;
ET0=1;
TR0=1;
}
void timer0() interrupt 1
{ uchar tmp ;
uchar tmp1;
static uchar count;
P0|=0x3f;
we=1;
< p> tmp=dispbit[count];tmp1=tmp;
P0&=tmp;
we=0;
du =1;
tmp=dispbuf[count];
if(tmp1==0xfb)
{
tmp=disptabwithdot[ tmp];
}
else
{
tmp=disptab[tmp];
}< /p>
P0=tmp;
du=0;
count++;
if(count==6)
{
count=0;
}
//unsigned int temp = abs(tempValue);
dispbuf[0] = temp/ 10000;
dispbuf[1] = temp % 10000 / 1000;
dispbuf[2] =temp % 1000 / 100;
dispbuf[ 3] = temp % 100 / 10;
dispbuf[4] = temp % 10;
TH0=th0;
TL0=tl0;
}
void main()
{ dio=0;
Init_timer0();
/*dispbuf[ 5]=0xf;
dispbuf[4]=0xf;
dispbuf[3]=0xf;
dispbuf[2]=0;
dispbuf[1]=0;
dispbuf[0]=0;*/
while(1)
{
//Start temperature conversion
sendChangeCmd();
tempValue1 = getTmpValue();
temp = abs(tempValue1);
// temp=getTmpValue();
}
}