这次学习到了DS18B20温度传感器
由于蓝桥杯比赛时给出了DS18B20的驱动程序onewire.c, 所以我们不再叙述DS18B20的时序图.
直接上DS18B20的ROM指令表:
由于开发板只有一个温度传感器, 所以上表中我们只有CCH,44H,BEH指令我们用的到.
控制思路是:先初始化DS18B20, 然后写入指令CCH,和44H,等待温度转化完成, 这时候传感器所采集到的温度值储存在了9字节的ROM中. 所以我们要再写入指令CCH和BEH来获取12位的温度值.
其中比较重要的点就是关于12位数据的温度值转换问题: 12位数据中,高8位是整数数据,低4位是小数部分,精度为2的-4次方,即0.0625.
因为这次学的比较简单, 所以我们直接贴 main.c 的代码:
//在数码管实时显示DS18B20读取到的温度数值
#include <reg52.h>
#include "onewire.h"
typedef unsigned char uchar;
typedef unsigned int uint;
sbit BUZZ=P0^6;
sbit RELAY=P0^4;
uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
uchar disbuff[8]={10,10,10,10,10,10,10,10};
uchar DisplayData[]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
uchar discom,n;
void CloseBUZZ();
void Display();
void CloseLED();
void TempPros();
//自己写读取温度程序
unsigned int DS18B20ReadTemp();
void main()
{
TMOD|=0x02;
TH0=0x06;
TL0=0x06;
EA=1;
TR0=1;
ET0=1;
CloseBUZZ();
CloseLED();
while (1)
{
TempPros();
}
}
void CloseBUZZ()
{
BUZZ=0;
RELAY=0;
P2=(P2&0x1f)|0xa0;
P2&=0x1f;
}
void CloseLED()
{
P0=0xff;
P2=(P2&0x1f)|0x80;
P2&=0x1f;
}
void timeoint() interrupt 1
{
n++;
if (n==10)
{
n=0;
Display();
}
}
//自己写读取温度程序
unsigned int DS18B20ReadTemp()
{
unsigned int temp;
unsigned char low,high;
Init_DS18B20();
Write_DS18B20(0xcc);
Write_DS18B20(0x44);
Delay_OneWire(20);
Init_DS18B20();
Write_DS18B20(0xcc);
Write_DS18B20(0xbe);
low=Read_DS18B20();
high=Read_DS18B20();
temp = (high*256+low)*25; //高八位二进制转十进制,
return (temp>>2); //乘25再右移两位,整体效果为乘以6.25
//直接乘6.25也可以,但是浮点数的计算速度不快
}
void TempPros()
{
unsigned int temp;
temp=DS18B20ReadTemp();
DisplayData[4]=table[temp%10000/1000];
DisplayData[5]=table[temp%1000/100]&0x7f;
DisplayData[6]=table[temp%100/10];
DisplayData[7]=table[temp%10];
}
void Display()
{
P0=0xff;
P2=(P2&0x1f)|0xe0;
P2&=0x1f;
P0=(1<<discom);
P2=(P2&0x1f)|0xc0;
P2&=0x1f;
P0=DisplayData[discom];
P2=(P2&0x1f)|0xe0;
P2&=0x1f;
discom++;
if (discom==8)
discom=4;
}
实验效果为在数码管实时显示DS18B20读取到的温度数值.
版权声明:本文为Beking17113原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。