单片机DS18B20温度计C语言程序

单片机DS18B20温度计C语言程序,第1张

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温度采集模块编程思想等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/9297862.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-26
下一篇 2023-04-26

发表评论

登录后才能评论

评论列表(0条)

保存