DS18B20单片机C语言温度数据转换

DS18B20单片机C语言温度数据转换,第1张

//温度小数部分对照表

code

uchar

table_tempfh[]={0,1,1,2,3,3,4,4,5,6,6,7,8,8,9,9}

//读取DS18B20当前温度

void

read_temp(void)

{

uchar

a=0

uchar

b=0

//DS18B20默认为12位精度

ds18b20_init()

ds18b20w_byte(0xCC)

//

跳过读序号列号的 *** 作

ds18b20w_byte(0x44)

//

启动温度转换

delayus(100)

//

等待足够长时间以读取温度值

ds18b20_init()

ds18b20w_byte(0xCC)

ds18b20w_byte(0xBE)

//读取温度寄存器等(共可读9个寄存器)

前两个就是温度

delayus(100)

a=ds18b20r_byte()

//读取温度值低位

b=ds18b20r_byte()

//读取温度值高位

tempvalue=b<<4

//转化成字节温度

tempvalue+=(a&0xf0)>>4

//整数部分

tempvalue_fh=table_tempfh[a&0x0f]

//小数部分(查表对照,获取小数位)

}

上面的程序采用12位精度,查阅18B20手册,LSB的最低四位代表小数,MSB的最高5位为符号位,其余的7位为整数部分,其分辨率为0.0625°,根据此规律,整数就是两字节凑在一起,而小数部分则是最低四位的值,乘以0.0625,看你取几位小数,再取整即可。上述的对照表是取1位小数的结果,取四舍五入。比如现在LSB的最低四位是0111,那么小数部分就是0.0625*7=0.4375,如果取1位小数,就是“4”,两位小数就是“44”..依次类推。

/*

必要 *** 作:连接传感器DS18B20到U6

*/

#pragma db code

#include<AT89X52.H>

#include "INTRINS.H"

#define BUSY1(DQ1==0) //定义busy信号

sbit LED_0=P1^0 //定义数码管控制脚为P1口的0-3脚

sbit LED_1=P1^1

sbit LED_2=P1^2

sbit LED_3=P1^3

sbit DQ1=P3^5 //定义18B20单总线引脚

void display(unsigned char d1,unsigned char d2,unsigned char d3,unsigned char d4)//声明显示函数

void ds_reset_1(void) //声明18B20复位函数

void wr_ds18_1(char dat) //声明18B20写入函数

void time_delay(unsigned char time)//声明延时函数

int get_temp_1(void) //声明18B20读入温度函数

void delay(unsigned int x) //声明延时函数

void read_ROM(void) //声明18B20读ROM函数

int get_temp_d(void) //声明获取温度函数

void ds_init(void) //声明18B20初始化函数

void ds_getT(void) //声明18B20获得温度显示值函数

/*定义数码管段码=====0-9=====A-G=====*/

unsigned char a[16]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,

0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e}

//共阳极数码管的段码0 1 2 3 4 5 6 7 8 9 A B C D E F

/****************以下定义各种变量********************/

unsigned char ResultSignal

int ResultTemperatureLH,ResultTemperatureLL,ResultTemperatureH

unsigned char ROM[8]

unsigned char idata TMP

unsigned char idata TMP_d

unsigned char f

unsigned char rd_ds18_1()

unsigned int TemH,TemL //温度的整数部分和小数部分

unsigned int count //定义小数计算部分

void main()

{

ds_init() //18B20初始化

while(1)

{

ds_getT() //使用该函数获得温度,整数部分存储到TemH,小数部分存储到count的低8位

display((TemH/10)%10,TemH%10,((count/10)%10),(count%10))

//温度发送到数码管显示

}

}

/***************18B20初始化函数***********************/

void ds_init(void)

{

unsigned int k=0

ds_reset_1()

ds_reset_1() //reset

wr_ds18_1(0xcc) //skip rom

_nop_()

wr_ds18_1(0x7f)

ds_reset_1()

wr_ds18_1(0xcc)

_nop_()

wr_ds18_1(0x44)

for(k=0k<11000k++)

time_delay(255)

ds_reset_1()

}

void ds_getT(void)

{

wr_ds18_1(0xcc)

wr_ds18_1(0xbe)

TemH=get_temp_1()

TemL=get_temp_d()

TemH&=0x00ff

TemL&=0x00ff

count=(TemH*256+TemL)*6.25

}

/***************延时程序,单位us,大于10us*************/

void time_delay(unsigned char time)

{

time=time-10

time=time/6

while(time!=0)time--

}

/*****************************************************/

/*reset ds18b20 */

/*****************************************************/

void ds_reset_1(void)

{

unsigned char idata count=0

DQ1=0

time_delay(240)

time_delay(240)

DQ1=1

return

}

void check_pre_1(void)

{

while(DQ1)

while(~DQ1)

time_delay(30)

}

void read_ROM(void)

{

int n

ds_reset_1()

check_pre_1()

wr_ds18_1(0x33)

for(n=0n<8n++){ROM[n]=rd_ds18_1()}

}

/*****************************************************/

/* Read a bit from 1820 位读取 */

/*****************************************************/

bit tmrbit_1(void)

{

idata char i=0

bit dat

DQ1=0_nop_()

DQ1=1

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

dat = DQ1

time_delay(50)

return dat

}

/*****************************************************/

/*read a bety from ds18b20 字节读取 */

/*****************************************************/

unsigned char rd_ds18_1()

{

unsigned char idata i,j,dat=0

for(i=1i<=8i++)

{

j=tmrbit_1()

dat=(j<<(i-1))|dat

}

return dat

}

/*****************************************************/

/* write a bety from ds18b20 写字节*/

/****************************************************/

void wr_ds18_1(char dat)

{

signed char idata i=0

unsigned char idata j

bit testb

for(j=1j<=8j++)

{

testb=dat &0x01

dat = dat>>1

if(testb)

{

DQ1=0

_nop_()

_nop_()

DQ1=1

time_delay(60)

}

else

{

DQ1=0

time_delay(50)

DQ1=1

_nop_()

_nop_()

}

}

}

int get_temp_1(void)

{

unsigned char idata a=0,b=0

unsigned char idata i

EA=0

ds_reset_1()

check_pre_1()

wr_ds18_1(0xcc)

wr_ds18_1(0x44)

while(BUSY1)

ds_reset_1()

check_pre_1()

wr_ds18_1(0xcc)

wr_ds18_1(0xbe)

a=rd_ds18_1()

b=rd_ds18_1()

i=b /*若b为1则为负温 */

i=(i>>4)

if(i==0)

{

f=0

TMP=((a>>4)|(b<<4))

a=(a&0x0f)

if (a>8)

{

TMP=(TMP+1)

}

}

else

{

f=1

a=a>>4

b=b<<4

TMP=(a|b)

TMP=~TMP

TMP=(TMP+1)

}

EA=1

return(TMP)

}

int get_temp_d(void)

{

unsigned char idata a=0,b=0

unsigned char idata i,m

EA=0

ds_reset_1()//复位

check_pre_1()

wr_ds18_1(0xcc)

wr_ds18_1(0x44)

while(BUSY1)

ds_reset_1()

check_pre_1()

wr_ds18_1(0xcc)

wr_ds18_1(0xbe)

a=rd_ds18_1()

b=rd_ds18_1()

i=b /*若b为1则为负温 */

i=(i>>4)

if(i==0)

{

f=0

TMP=((a>>4)|(b<<4))

a=(a&0x0f)

TMP_d=a

}

else

{

f=1

a=~a

a=(a+1)

b=~b

b=(b+1)

m=a

a=a>>4

b=b<<4

TMP=(a|b)

m=(m&0x0f)

TMP_d=m

}

EA=1

return(TMP_d)

}void delay(unsigned int x)

{

unsigned int i

for(i=0i<xi++)

}

void display(unsigned char d1,unsigned char d2,unsigned char d3,unsigned char d4)

{

P0=a[d1]

LED_0=0

delay(100)

LED_0=1

P0=a[d2] &0x7f

LED_1=0

delay(100)

LED_1=1

P0=a[d3]

LED_2=0

delay(100)

LED_2=1

P0=a[d4]

LED_3=0

delay(100)

LED_3=1

}

#include <reg52.h>

#include <intrins.h>

#define uchar unsigned char

#define uint unsigned int

sbit DS=P3^3 //定义DS18B20接口

int temp

uchar flag1

void display(unsigned char *lp,unsigned char lc)//数字的显示函数;lp为指向数组的地址,lc为显示的个数

void delay()//延时子函数,5个空指令

code unsigned char table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40,0x08,0x00}

//共阴数码管 0-9 - _ 空 表

unsigned char l_tmpdate[8]={0,0,10,0,0,0,0,0}//定义数组变量,并赋值1,2,3,4,5,6,7,8,就是本程序显示的八个数

int tmp(void)

void tmpchange(void)

void tmpwritebyte(uchar dat)

uchar tmpread(void)

bit tmpreadbit(void)

void dsreset(void)

void delayb(uint count)

void main() //主函数

{

uchar i

int l_tmp

while(1)

{

tmpchange() //温度转换

l_tmp=tmp()

if(l_tmp<0)

l_tmpdate[0]=10//判断温度为负温度,前面加"-"

else

{

l_tmpdate[0]=temp/1000//显示百位,这里用1000,是因为我们之前乖以10位了

if(l_tmpdate[0]==0)

l_tmpdate[0]=12//判断温度为正温度且没有上百,前面不显示

}

l_tmp=temp%1000

l_tmpdate[1]=l_tmp/100//获取十位

l_tmp=l_tmp%100

l_tmpdate[2]=l_tmp/10//获取个位

l_tmpdate[3]=11

l_tmpdate[4]=l_tmp%10//获取小数第一位

for(i=0i<10i++){ //循环输出10次,提高亮度

display(l_tmpdate,5)

}

}

}

void display(unsigned char *lp,unsigned char lc)//显示

{

unsigned char i //定义变量

P2=0//端口2为输出

P1=P1&0xF8 //将P1口的前3位输出0,对应138译门输入脚,全0为第一位数码管

for(i=0i<lci++){ //循环显示

P2=table[lp[i]] //查表法得到要显示数字的数码段

delay() //延时5个空指令

if(i==7)//检测显示完8位否,完成直接退出,不让P1口再加1,否则进位影响到第四位数据

break

P2=0//清0端口,准备显示下位

P1++//下一位数码管

}

}

void delay(void)//空5个指令

{

_nop_()_nop_()_nop_()_nop_()_nop_()

}

void delayb(uint count) //delay

{

uint i

while(count)

{

i=200

while(i>0)

i--

count--

}

}

void dsreset(void) //DS18B20初始化

{

uint i

DS=0

i=103

while(i>0)i--

DS=1

i=4

while(i>0)i--

}

bit tmpreadbit(void) // 读一位

{

uint i

bit dat

DS=0i++ //小延时一下

DS=1i++i++

dat=DS

i=8while(i>0)i--

return (dat)

}

uchar tmpread(void) //读一个字节

{

uchar i,j,dat

dat=0

for(i=1i<=8i++)

{

j=tmpreadbit()

dat=(j<<7)|(dat>>1) //读出的数据最低位在最前面,这样刚好//一个字节在DAT里

}

return(dat)//将一个字节数据返回

}

void tmpwritebyte(uchar dat)

{ //写一个字节到DS18B20里

uint i

uchar j

bit testb

for(j=1j<=8j++)

{

testb=dat&0x01

dat=dat>>1

if(testb) // 写1部分

{

DS=0

i++i++

DS=1

i=8while(i>0)i--

}

else

{

DS=0 //写0部分

i=8while(i>0)i--

DS=1

i++i++

}

}

}

void tmpchange(void) //发送温度转换命令

{

dsreset()//初始化DS18B20

delayb(1)//延时

tmpwritebyte(0xcc) // 跳过序列号命令

tmpwritebyte(0x44) //发送温度转换命令

}

int tmp() //获得温度

{

float tt

uchar a,b

dsreset()

delayb(1)

tmpwritebyte(0xcc)

tmpwritebyte(0xbe) //发送读取数据命令

a=tmpread() //连续读两个字节数据

b=tmpread()

temp=b

temp<<=8

temp=temp|a//两字节合成一个整型变量。

tt=temp*0.0625 //得到真实十进制温度值,因为DS18B20

//可以精确到0.0625度,所以读回数据的最低位代表的是

//0.0625度。

temp=tt*10+0.5 //放大十倍,这样做的目的将小数点后第一位

//也转换为可显示数字,同时进行一个四舍五入 *** 作。

return temp//返回温度值

}

void readrom() //read the serial 读取温度传感器的序列号

{ //本程序中没有用到此函数

uchar sn1,sn2

dsreset()

delayb(1)

tmpwritebyte(0x33)

sn1=tmpread()

sn2=tmpread()

}

void delay10ms()

{

uchar a,b

for(a=10a>0a--)

for(b=60b>0b--)

}


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

原文地址: http://outofmemory.cn/yw/7767652.html

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

发表评论

登录后才能评论

评论列表(0条)

保存