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--)
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)