DS18B20内部结构主要由四部分组成:64位光刻ROM、温度传感器、非挥发的温度报警触发器TH和TL、配置寄存器。光刻ROM中的64位序列号是出厂前被光刻好的,它可以看作是该DS18B20的地址序列码。64位光刻ROM的排列是:开始8位(28H)是产品类型标号,接着的48位是该DS18B20自身的序列号,最后8位是前面56位的循环冗余校验码(CRC=X8+X5+X4+1)。光刻ROM的作用是使每一个DS18B20都各不相同,这样就可以实现一根总线上挂接多个DS18B20的目的,也就是你要做的是配置寄存器。根据DS18B20的通讯协议,主机控制DS18B20完成温度转换必须经过三个步骤:每一次读写之前都要对DS18B20进行复位,复位成功后发送一条ROM指令,最后发送RAM指令,这样才能对DS18B20进行预定的 *** 作。复位要求主CPU将数据线下拉500微秒,然后释放,DS18B20收到信号后等待16~60微秒左右,后发出60~240微秒的存在低脉冲,主CPU收到此信号表示复位成功。
比如
while(t--)
{
_nop_();
}
t在delayus(10)中已经赋值,即t=10,_nop_()是一个空 *** 作NOP(汇编语言中),即一个机器周期,主频12Mhz中就是1um
我这有个现成的C源程序,你参考一下吧!
三通道18B20温度测量数码管显示。-55-+125℃,用1位数码管显示当前通道号,4位数码管显示18B20当前通道温度值(一位小数),负号位与正温度百位1用同一位数码管显示,该位为0不显示,如:0 279、1 1231、2 -356。连接方法:三个18B20均接P37,P0口(JP10)接8位数码管段码口(J12)。
#include <reg52h>
#include <intrinsh>
typedef unsigned char uint8;
typedef unsigned int uint16;
sbit ADDR0 = P2^2;
sbit ADDR1 = P2^3;//定义38译码器地址
sbit ADDR2 = P2^4;
uint8 x,h;//定义通道
uint16 ans,ansb[3],f,g,p; //ans各通道温度值,f符号值,g为小数部分,p为1秒的计数变量
code uint8 number[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x67,0x40,0x00,0x80};//0,1,2,3,4,5,6,7,8,9,-,灭,小数点
sbit DQ = P3^7; //温度DQ一线输入口
#define nops(); {_nop_(); _nop_(); _nop_(); _nop_();} //定义空指令
uint8 romid[3][8]={//romid二维数组存放每个芯片ROM编号
{0x28,0xA2,0xb4,0x0A,0x00,0x00,0x00,0x83},//0通道
{0x28,0xA2,0xb4,0x0A,0x03,0x00,0x00,0x83},//1通道
{0x28,0xA2,0xb4,0x0A,0x05,0x00,0x00,0x83},//2通道
};
// 定时器初始化
void T1_init(void)
{
TMOD = 0x10; //定时器1工作在方式1(显示扫描定时)
TH1 = 0xfc;
TL1 = 0x67;//T1定时1ms初值
TR1 = 1;//启动T1
}
void delay(uint16 n)
{
while (n--);
}
// 18B20复位函数
void DS18b20_reset(void)
{
bit flag=1;
while (flag)
{
while (flag)
{
DQ = 1;
delay(1);
DQ = 0;
delay(50); // 550us
DQ = 1; //给18B20发出复位信号
delay(6); // 66us
flag = DQ; //检测18B20发出的存在脉冲"0",判断复位是否成功
}
delay(45); //延时500us
flag = ~DQ; //18B20存在脉冲过后变"1",取反后仍为"0"
}
DQ=1;
}
//18B20写1个字节函数 向1-WIRE总线上写一个字节
void write_byte(uint8 val)
{
uint8 i;
for (i=0; i<8; i++)
{
DQ = 1;
_nop_();
DQ = 0;
nops(); //4us,110592晶振时每个时钟周期约1us
DQ = val & 0x01; //最低位移出
delay(6); //66us
val >>= 1; //右移一位
}
DQ = 1;
delay(1);
}
//18B20读1个字节函数 从1-WIRE总线上读取一个字节
uint8 read_byte(void)
{
uint8 i, value=0;
for (i=0; i<8; i++)
{
DQ=1;
_nop_();
value >>= 1;
DQ = 0;
nops(); //4us
DQ = 1;
nops(); //4us
if (DQ)
value|=0x80;
delay(6); //66us
}
DQ=1;
return(value);
}
// 启动温度转换
void start_temp_sensor(void)
{
DS18b20_reset();
write_byte(0xCC); // 发Skip ROM命令
write_byte(0x44); // 发转换命令
}
// 读出温度,多点多个18B20测温主程序:
void read_temp() //读取通道x的温度值
{
uint8 i,temp_data[2];//读出温度暂放
uint16 temp;
for(x=0;x<3;x++)
{
DS18b20_reset(); //复位
write_byte(0x55); // 发匹配ROM命令
for(i=0;i<8;i++)
write_byte(romid[x][i]);//写8位器件ID(从左到右),如:28 A2 b4 0A 03 00 00 83。
write_byte(0xBE);//读RAM命令,共9个字节,只取前两温度字节
temp_data[0]=read_byte(); //温度低8位
temp_data[1]=read_byte(); //温度高8位
temp=temp_data[1];//温度高字节
temp=temp<<8;//移到高8位中
temp+=temp_data[0];//温度低字节
ansb[x]=temp;
}
}
// 刷新5位数码管程序
void refresh()
{
static uint8 j = 0,a;//j为数码管位数,a为临时存放红外数据高或低4位
P0 = 0x00;//防止重影
switch(j)
{
case 0: ADDR0 = 1;ADDR1 = 1;ADDR2 = 1;j++;//最右边一位数码管,一位小数
a=g625/1000;//只取小数点后一位,625把16进制换算成对应的10进制
P0 = number[a];break;
case 1: ADDR0 = 0;ADDR1 = 1;ADDR2 = 1;j++;
a = ans%10;//取个位
P0 = number[a];break;
case 2: ADDR0 = 1;ADDR1 = 0;ADDR2 = 1;j++;
a = ans/10%10;//取十位
P0 = number[a];break;
case 3: ADDR0 = 0;ADDR1 = 0;ADDR2 = 1;j++;
a = ans/100%10;//取百位
if (f!=0){a=10;}//若为负显示-号
else if (a!=1){a=11;}//若小于100度该位熄灭
P0 = number[a];break;//为1则正常显示
case 4: ADDR0 = 0;ADDR1 = 1;ADDR2 = 1;j++;
a = 12;//个位显示小数点
P0 = number[a];break;
case 5: ADDR0 = 0;ADDR1 = 1;ADDR2 = 0;j=0; //通道显示
P0 = number[h];break;//显示通道号
default: break;
}
}
main()
{
T1_init();//定时器初始化
while(1)
{
if(TF1==1)
{
TF1 = 0;
TH1 = 0xfc;
TL1 = 0x67;
start_temp_sensor();//启动温度转换
p++;
if(p==1000)// 延时约1秒
{
read_temp();//读各通道温度值
switch(h)
{//切换温度显示通道
case 0: ans=ansb[1];h++;break;//1通道
case 1: ans=ansb[2];h++;break;//2通道
case 2: ans=ansb[0];h=0;break;//0通道
default: break;
}
f=ans&0xF800;//取符号位
g = ans&0x000f;//取小数部分
ans>>=4;//去除小数部分
if (f!=0)
{
ans=~ans+1;
}
p=0;
}
refresh();
}
}
}
以上就是关于单片机DS18B20温度计C语言程序全部的内容,包括:单片机DS18B20温度计C语言程序、求一个ds18b20数字温度测量的C程序、DS18B20温度采集模块编程思想等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)