|
昨天自己写了一个DS18B20的程序,能正常运行,发到51黑论坛上分享给和我一样的新手朋友们。
通过DS18B20采集环境温度,并在开发板的数码管模块上的左三位显示(带1位小数)。
MCU:AT89S52
源码:
#include <reg52.h>
sbit DS=P2^2;
sbit DU=P2^6;
sbit WE=P2^7;
unsigned char table0[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //无小数点
unsigned char table1[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef}; //有小数点
unsigned int temp;
void Delay(unsigned int x) //延时一定时间
{
unsigned int i;
while(x)
{
i=200;
while(i>0)
{
i--;
}
x--;
}
}
void DS18B20_init() //DS18B20初始化
{
unsigned int i;
DS=0; //MCU拉低电平最少480us,产生复位脉冲,然后释放总线
i=103; //延时480us~960us
while(i>0)
{
i--;
}
DS=1; //释放总线
i=4; //等待15~60us,然后DS18B20拉低电平60~240us表示应答
while(i>0)
{
i--;
}
while(DS);
}
bit Read_bit() //读取1比特的数据;“读”时序最少需要60us
{
unsigned int i;
bit dat;
DS=0;
i++; //拉低电平最少1us,然后再释放总线
DS=1;
i++; //等待一定时间后,再读取电平状态
i++;
dat=DS;
i=8;
while(i>0)
{
i--; //等待最少60us
}
return dat;
}
unsigned char Read_byte() //读取1字节的数据
{
unsigned char i,j;
unsigned char dat=0;
for(i=1;i<=8;i++)
{
j=Read_bit();
dat=(j<<7)|(dat>>1);
}
return dat;
}
void Write_byte(unsigned char dat) //往DS18B20中写入1字节的数据
{
unsigned int i;
unsigned char j;
bit x;
for(j=1;j<=8;j++)
{
x=dat&0x01; //依次将dat的每一位赋值给x
dat=dat>>1;
if(x) //写入“1”
{
DS=0; //拉低电平大于1us,在15us内拉高电平
i++;
i++;
DS=1; //“写”时序起始后的15~60us内,DS18B20处于采样状态,在此期间,若总线为高电平,则表示“1”
i=8;
while(i>0)
{
i--; //等待最少60us
}
}
else //写入“0”;拉低电平60~120us,然后释放总线
{
DS=0;
i=8;
while(i>0) //最少60us
{
i--;
}
DS=1;
}
}
}
void Change(void) //温度转换,即测量温度
{
DS18B20_init();
Delay(1);
Write_byte(0xcc); //“跳过ROM”操作
Write_byte(0x44); //“温度转换”操作
}
unsigned int GET() //获取温度数据
{
float x;
unsigned char a,b;
DS18B20_init();
Delay(1);
Write_byte(0xcc);
Write_byte(0xbe); //读取DS18B20内的RAM的内容
a=Read_byte(); //读取温度值的低8位
b=Read_byte(); //读取温度值的高8位
temp=b;
temp<<=8;
temp=temp|a;
x=temp*0.0625; //DS18B20默认设置为12位分辨率,即表示分辨率为0.0625摄氏度
temp=x*10+0.5;
return temp;
}
void OUTPUT(unsigned int temp) //数码管显示
{
unsigned char x0,x1,y,x2;
x0=temp/100;
y=temp%100;
x1=y/10;
x2=y%10;
DU=0;
P0=table0[x0]; //显示温度值的十位
DU=1;
DU=0;
WE=0;
P0=0xfe;
WE=1;
WE=0;
Delay(1);
DU=0;
P0=table1[x1]; //显示温度值的个位
DU=1;
DU=0;
WE=0;
P0=0xfd;
WE=1;
WE=0;
Delay(1);
P0=table0[x2]; //显示温度值的十分位
DU=1;
DU=0;
P0=0xfb;
WE=1;
WE=0;
Delay(1);
}
void main()
{
while(1)
{
Change();
OUTPUT(GET());
}
}
|
评分
-
查看全部评分
|