要求
用单片机实训平台检测温度,在数码管后三位显示,用的存储器扩展。
DS18B20
温度转换与读取流程:
DS18B20的温度转换与读取流程:
1.DS18B20复位
2.写入字节0xCC,跳过ROM指令
3.写入字节0x44,开始温度转换
4.延时700~900ms
5.DS18B20复位
6.写入字节0xCC,跳过ROM指令
7.写入字节0xBE,读取高速暂存器
8.读取暂存器的第0字节,即温度数据的LSB
9.读取暂存器的第1字节,即温度数据的MSB
10.DS18B20复位,表示读取数据结束
11.将LSB和MSB整合成为一个16位数据
12.判断读取结果的符号,进行正负温度的数据处理
数据处理
DS18B20以16位带符号位扩展的二进制补码形式读出。
DS18B20的分辨率为0.0625.读出的数据是正数时,将LSB和MSB整合的16位整数,直接乘以0.0625即可。读出的数据为负数时,则需要将LSB和MSB整合的16位整数取反加1后,再乘以0.0625。
代码
前期准备
需要添加驱动代码 :将onewire.c和onewire.h拷贝到刚刚建立的文件夹中。
将onewire.h文件补充成这样:
必备
数码管
必须记住:共阳数码管从0-9 + 共阳数码管从0.-9.
unsigned char SMGNoDot_CA[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
unsigned char SMGDot_CA[10]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
温度读取
/*============温度读取=========*/
void Read_DS18B20_temp()
{
unsigned char LSB,MSB;
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0x44);
Delay(1000);
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0xbe);
LSB=Read_DS18B20();
MSB=Read_DS18B20();
temp = MSB;
// temp<<8;
temp = temp | LSB;
if((temp & 0xf800) == 0x0000)
{
temp >>= 4;
temp = temp * 10;
temp = temp + (LSB & 0x0f)*0.0625;
}
}
完整代码
#include"reg52.h"
#include"absacc.h"
#include"onewire.h"
unsigned char SMGNoDot_CA[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
unsigned char SMGDot_CA[10]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
unsigned int temp=0;
void DelaySMG(unsigned int t)
{
while(t--);
}
//数码管显示
void DisPlaySMG_Bit(unsigned char pos,unsigned char dat)
{
XBYTE[0xE000] = 0xff; //数码管关闭
XBYTE[0xC000] = 0x01 << pos; //数码管显示的位
XBYTE[0xE000] = dat;
}
//对所有数码管统一操作的函数
void DisPlay_All(unsigned char dat)
{
XBYTE[0xC000] = 0xff; //数码管显示的位
XBYTE[0xE000] = dat;
}
/*======数码管显示温度======*/
void DisPlaySMG_Temp()
{
DisPlaySMG_Bit(7,SMGNoDot_CA[temp%10]);
DelaySMG(100);
DisPlaySMG_Bit(6,SMGDot_CA[(temp%100)/10]);
DelaySMG(100);
DisPlaySMG_Bit(5,SMGNoDot_CA[temp/100]);
DelaySMG(100);
DisPlaySMG_Bit(4,0xff);
DelaySMG(100);
DisPlaySMG_Bit(3,0xff);
DelaySMG(100);
DisPlaySMG_Bit(2,0xff);
DelaySMG(100);
DisPlaySMG_Bit(1,0xff);
DelaySMG(100);
DisPlaySMG_Bit(0,0xff);
DelaySMG(100);
DisPlay_All(0xff); //所有数码管都关闭
}
//==========注意:这个延时函数很重要!在数码管显示中要动态显示
void Delay(unsigned int t)
{
while(t--);
{
DisPlaySMG_Temp();
}
}
/*============温度读取=========*/
void Read_DS18B20_temp()
{
unsigned char LSB,MSB;
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0x44);
Delay(1000);
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0xbe);
LSB=Read_DS18B20();
MSB=Read_DS18B20();
temp = MSB;
// temp<<8;
temp = temp | LSB;
if((temp & 0xf800) == 0x0000)
{
temp >>= 4;
temp = temp * 10;
temp = temp + (LSB & 0x0f)*0.0625;
}
}
void main()
{
XBYTE[0x8000]=0xff;
while(1)
{
Read_DS18B20_temp();
DisPlaySMG_Temp();
}
}
总结
1.要有头文件
2.主函数的写法
//提前声明
unsigned int temp=0;
//主函数
void main()
{
XBYTE[0x8000]=0xff;
while(1)
{
Read_DS18B20_temp();
DisPlaySMG_Temp();
}
}
3.注意数码管显示温度的代码!背!
4.DS18B20温度读取的代码,背
5.特别注意头文件的修改!延时函数放大了10倍!