ChunJian-YANG

#include <REGX51.H>
#include <INTRINS.h>

#define FOSC 12000000 //--- 宏定义时钟频率 ---

//=================================================================================================
//--- DS18B20定义及函数声明区 ---
sbit DQ = P3^7; //--- DS18B20引脚声明 ---
unsigned char code dotcode[32]=
{
0, 3, 6, 9,12,16,19,22,25,28,31,34,38,41,44,48,50,53,56,59,63,66,69,72,75,78,81,84,88,91,94,97,
};
bit sflag;
unsigned int sCnt = 0;
unsigned char Buffer[2];

bit ResetDS18B20(void) //--- DS18B20复位时序函数 ---
{
unsigned char i;

DQ=0;
for(i=255;i>0;i--);
DQ=1;
for(i=60;i>0;i--);
for(i=255;i>0;i--);
return(DQ);
}

void WriteDS18B20(unsigned char value) //--- 写DS18B20命令函数 ---
{
unsigned char i;
unsigned char j;

for(i=0;i<8;i++)
{
if((value & 0x01) == 0)
{
DQ = 0; //--- DQ引脚拉低 ---
for(j=35;j>0;j--); //--- 延时大约不超过45us ---
DQ = 1; //--- DQ引脚变高 ---
}
else
{
DQ = 0; //--- DQ引脚拉低 ---
_nop_(); //--- 延时不超15us ---
_nop_();
_nop_();
_nop_();
DQ = 1; //--- DQ引脚变高 ---
for(j=35;j>0;j--); //--- 延时大约不超过45us
}
value >>= 1;
}
}
unsigned char ReadDS18B20(void) //--- 读DS18B20存储器里的数据函数 ---
{
unsigned char i;
unsigned char j;
unsigned char temp;

temp = 0;
for(i=0;i<8;i++)
{
temp >>= 1;
DQ = 0; //--- DQ引脚拉低 ---
_nop_(); //--- 不超过10us的简短延时 ---
_nop_();
_nop_();
_nop_();
DQ = 1; //--- DQ引脚变高 ---
for(j=15;j>0;j--); //--- 简短延时 ---
if(DQ == 1) //--- 检测DQ引脚上的电平状态 ---
{
temp=temp | 0x80;
}
else
{
temp=temp | 0x00;
}
for(j=20;j>0;j--); //--- 简短延时 ---
}
return(temp); //--- 返回读到的数据 ---
}

//=================================================================================================
//--- 数码管显示定义专属区 ---
sfr P0M1 = 0x93;
sfr P0M0 = 0x94;
sfr P2M1 = 0x95;
sfr P2M0 = 0x96;
#define TIMER1MS 1000 //--- 宏定义定时1ms,1000us ---
unsigned char code LEDSEG[]= //--- 数码显示0-9,A-F代码表格 ---
{
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00,0x40,0x37,
};
unsigned char code LEDDIG[] = //--- 位选通段代码表 ---
{
0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F,
};
unsigned char LEDBuffer[8]; //--- 定义的显示缓冲区 ---
unsigned char LEDPointer; //--- 定义的动态扫描计数变量 ---

//=================================================================================================
//--- main主程序区 ---
void main(void)
{
// P0M1 = 0x00; //--- 配置P0端口的P0.0~P0.7为推挽输出模式 ---
// P0M0 = 0xFF;
// P2M1 = 0x00; //--- 配置P2端口的P2.0~P2.7为推挽输出模式 ---
// P2M0 = 0xFF;
TMOD = 0x01;
TH0 = (65536 - FOSC / 12 / TIMER1MS) / 256; //--- T0定时1mS的初值装入TH0,TL0 ---
TL0 = (65536 - FOSC / 12 / TIMER1MS) % 256;
// TH0 = (65536 - 50000) / 256; //--- T0定时1mS的初值装入TH0,TL0 ---
// TL0 = (65536 - 50000) % 256;
TR0 = 1; //--- 启动T0定时开始工作 ---
ET0 = 1; //--- 允许T0溢出中断 ---
EA = 1; //--- CPU开中断 ---

while(ResetDS18B20());
WriteDS18B20(0xCC);
WriteDS18B20(0x44);

while(1)
{
}
}

//=================================================================================================
//--- 定时器T0溢出中断服务程序 ---
void T0_ISR(void) interrupt 1 //--- T0定时1mS溢出中断服务程序 ---
{
unsigned char x;
unsigned int result;

TH0 = (65536 - FOSC / 12 / TIMER1MS) / 256; //--- 重新装入初值 ---
TL0 = (65536 - FOSC / 12 / TIMER1MS) % 256;
// TH0 = (65536 - 50000) / 256; //--- 重新装入初值 ---
// TL0 = (65536 - 50000) % 256;

P0 = LEDSEG[LEDBuffer[LEDPointer]]; //--- 数码管扫描程序段,完成动态扫描显示 ---
if(2 == LEDPointer) P0 |= 0x80; //--- 显示小数点 ---
P2 = LEDDIG[LEDPointer];
if((++LEDPointer) == sizeof(LEDBuffer)) LEDPointer = 0;

sCnt ++;
if(1000 == sCnt)
{
sCnt = 0;
while(ResetDS18B20()); //--- 复位DS18B20 ---
WriteDS18B20(0xCC);
WriteDS18B20(0xBE); //--- 向DS18B20发送读命令 ---
Buffer[0] = ReadDS18B20(); //--- 从DS18B20内读数据 ---
Buffer[1] = ReadDS18B20();
for(x=0;x<8;x++) LEDBuffer[x]=16; //--- 清显示缓冲区 ---
sflag = 0;
if((Buffer[1] & 0xf8) != 0x00) //--- 判断是否为负温度 ---
{
sflag = 1; //--- 置是负温度标志 ---
Buffer[1] = ~Buffer[1]; //--- 数据取反加1处理 ---
Buffer[0] = ~Buffer[0];
result = Buffer[0] + 1;
Buffer[0] = result;
if(result > 255) Buffer[1] ++;
}
Buffer[1] <<= 4; //--- 转换为有效的数值 ---
Buffer[1] &= 0x70;
x = Buffer[0];
x >>= 4;
x &= 0x0F;
Buffer[1] |= x;
x = 2;
result = Buffer[1];
while(result / 10) //--- 将有效值送入显示缓冲区域---
{
LEDBuffer[x] = result % 10;
result=result / 10;
x ++;
}
LEDBuffer[x] = result;
if(sflag == 1)LEDBuffer[x + 1] = 17; //--- 若是负温度则在有效值前显示“-”号 ---
x = Buffer[0] & 0x0f;
x <<= 1;
LEDBuffer[0] = (dotcode[x]) % 10; //--- 有效的小数值送显示缓冲区 ---
LEDBuffer[1] = (dotcode[x]) / 10;
while(ResetDS18B20()); //--- 复位DS18B20 ---
WriteDS18B20(0xcc);
WriteDS18B20(0x44); //--- 发送温度转换命令 ---
}
}

分类:

技术点:

相关文章: