/*
建立时间: 2013年5月2日;
前言: 我用软件仿真,测算延时时间,效果不错,但是根据教程,复位时,先释放总线
(wd高电平),然后主机拉低wd,持续时间为400--960微妙.后主机拉高wd,持续15-
60微妙,后 从机,会拉低电平持续时间是60--240微妙(此时表示复位成功),如果
从机没有将总线拉低,则复位失败.然后,主机拉高电平60--240微妙.复位结束;
可,实验证明,在,从机,拉低总线电平后,持续一定时间,从机还会将总线拉高!这
是教程中的一个重大错误!
temperature sensor reset module finishing time: 23:08:00
( 温度 传感器 复位 模块 完成 时间 )
temperature sensor 操作过程:
1. reset DS18B20;
2. 发出Skip ROM 命令(CCH); (跳跃ROM命令)
3. 发出Convert T命令(44H); (温度转换命令)
4. reset DS18B20;
5. 发出Skip ROM命令(CCH);(跳跃ROM命令)
6. 发出读取命令(BEH);
7. 读出两个字节的温度;
8. 温度格式转换;
2013年5月8日22:56:44
DS18B20 Temperature sensor read data module accomplish;
( 温度 传感器 读 数据 模块 完成 )
现在还有温度显示模块没有完成,硬件是1602液晶屏......
2013年5月9日19:32:31
今天,温度传感器的程序主体结构全部完成!!!!!
不容易啊,值得庆祝一下!!!!!!
一共写了7天程序!{陆陆续续};
喝个 品酸乳果汁.......
*/
#include
typedef unsigned char uint8 ;
typedef unsigned int uint16;
sbit wd = P3^2; //定义数据单总线;
sbit e =P1^5; // 定义1602液晶显示器数据使能端口;
sbit rs=P1^0; // 定义数据/指令选择端口;
sbit rw=P1^1; // 定义 读/写 选择端口;
sbit BF=P0^7; // 定义繁忙位;
bit w=0; //定义一个全局一位变量;
//===========1602液晶显示器模块;===============
busy() //液晶屏繁忙检测函数;
{ e=0;
rs=0;
rw=0;
P0=0xff;
do
{ e=0; //使能位清零;
rs=0; //指令;
rw=1; //读;
e=1; //数据传输启动;
}while(BF); //如果BF==0;则液晶处于空闲状态;
e=0;
}
play_data(uint8 wr) //液晶写入数据;
{
busy(); //繁忙检测;
P0=wr; //装载数据;
rs=1; //数据;
rw=0; //写入;
e=1; //传输开始;
e=0; //传输结束;
}
play_cmd(uint8 cmd) //液晶写入指令;
{
busy(); //繁忙检测;
P0=cmd; //装载数据;
rs=0; //指令;
rw=0; //写入;
e=1; //传输开始;
e=0; //传输结束;
}
reset_1602() //1602液晶显示器初始化函数;
{
play_cmd(0x38);
play_cmd(0x0c);
play_cmd(0x06);
play_cmd(0x01);
}
//=========温度传感器延时模块============================
// sbit led= P1^0;
delay(uint8 num ) //如果unm等于1;延时16.28微妙;
{
while(num--); //如果num大于一,则16.28+(num-1)*6.51.
}
delay2() //此函数延时3.26微秒;
{
uint8 j=0;
j=9;
}
delay3()
{
uint16 s=60000;
while(s--);
}[page]
reset_1820() //========复位温度传感器; ========
{
while(wd)
{
wd=1;
delay(140); //拉高总线,延时大概921微妙左右;(延时值自定);
wd=0; //总线由单片机拉低,下为延时函数,大概800微秒左右;
delay(61); //1个此函数会延时400微妙左右;
delay(61); //两个是800微妙左右;
wd=1; //主机拉高总线,68微秒左右;
delay(9); //延时68微妙左右
if(wd==0) //如果wd是0就终止复位;(代表复位成功);
{
while(wd==0); //总线一旦为低,那么就等待从机再将总线拉高.
break; //终止while循环;(reset function end)
}
else
{
wd=1;
delay(20); //延时140微妙;
}
}
delay(30); //此时总线为高电平并延时205微妙,复位成功!;
// if(wd)led=0;//此语句为检验是否复位成功;P1^0外接9012三极管接led小灯;
}
write_byte(uint8 dat)
{
uint8 i=0;
for(i=0;i<8;i++)
{
wd=0; //A点;
delay2(); //延时
wd=dat & 0x01;
dat>>=1;
delay(6); //A点到此处用时65.11微秒;
wd=1; //总线释放;
delay2(); //延时3.26微秒;
}
} //========此函数执行完成之后总线为高电平;
uint8 read_byte() //=====读8位数据;===================
{
uint8 j=0, dat =0;
for(j=0;j<8;j++)
{
dat>>=1;
wd=0; // A点 mcu拉低电平3.26微秒;
delay2(); // 延时3.26微秒;
wd=1;
if(wd)
{
dat|=0x80;
} //读完数据后A点到此处是11.93微秒,保持在15微秒之内;
delay(9); // A点到此处80.29微秒; 理想时间范围是60--120微秒;
wd=1; //释放总线;
delay2(); //延时3.26微秒;
}
return dat;
}
start_sensor() //启动传感器;
{
reset_1820();
write_byte(0xcc); //跳跃命令;
write_byte(0x44); //转换temperature(温度)命令;
}
uint8 read_temp() //从温度传感器度温度数据过程;
{
uint8 ak[2];
uint16 dat=0 , j=0;
reset_1820(); //复位温度传感器
write_byte(0xcc); //跳跃rom命令;
write_byte(0xbe) ; // 发出读数据命令;
ak[0]=read_byte(); //读取第一个字节数据;
ak[1]=read_byte(); //读取第二个字节数据;
dat=ak[1]; //要把两个八位数据载入1个16位变量里;
dat<<=8;
dat|=ak[0];
j= dat;
//==========以下是把温度传感器内部数据编译成16进制编码;
if((j>>11)==0x1f) //此语句是负温度进入.0x1f是二进制5个全1;
{
dat=(~dat)+1; //负温度要取反加一操作;
dat/=16; //传感器给的温度系数要除以16后,得到的数才是常规温度系数;
w=0; //此语句是在主函数中用来判断是正温度还是负温度;
return dat; //向主函数返回数据,并终止函数;
}
j=dat;
if((j>>11)==0) //如果是零则是正温度;
{
dat/=16; //数据直接除以16,就得到了常规温度系数;
w=1; //1代表正;
return dat; //向主函数返回数据,并终止函数;
}
return 130; //向主函数返回数据,并终止函数;
}
delay_ms() //延时1秒;
{
uint8 i=250;
uint16 j=608;
while(j--)
{ while(i--);
i=250;
}
}
error() //测温出错;
{
uint8 i=5, j=0 ,ak[]="Error!";
while(i--)
{
play_cmd(0x82);
while(ak[j]!='