
第二个程序很少看到用,一般是计算时长,在过了相应的时间后直接去读取数据,楼主程序使用循环255次的时间需要根据编译后的汇编代码来计算,请楼主行算一下;感觉楼主的这个程序采用不停检测和循环的做法有些夸张。
楼主要深入了解这个程序,最好还是直接看MAXIM-IC.COM网站上DS18B20的相关资料,重点是时序图和相关的命令流程图,看懂了是很有帮助的。
其实你的程序的注释写的已经很清楚了。首先需要明确的是,ds18B20作为单总线器件,它对时序要求比较高,否则是不能正常工作的。至于你问的程序注释,我说过了,本身写的已经很清楚了,大没有在去解释的必要。估计你有这样的问题,是本身对ds18b20的数据手册还不是很清楚,建议自己看看他的资料和用法,先把时序和一些概念搞清楚就好了。至于你问的while(--delay)这句程序,意思就是只要“--delay”非零(while语句非零即为真),那程序就会停到这里一直执行,执行一次delay减1,直到--delay最后变成0。然后程序才能跳到下一句去执行。本身这个地方很好理解的,看来你的c语言还有待在看看。不过也没事,程序写多了自然这些东西就明白了。最后给你举个例子吧,比如程序前面给delay赋值为5,那么while(--delay)这句程序会执行5次,第一次while(4),第二次while(3),while(2),while(1),最后成了while(0),到了这时候,while(0)为假,程序就不执行了,然后就转到了下面。这样你应该就明白了,就是让程序在while这个地方循环多执行几次,起到一个延时的作用。#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条)