|
反复调试了很多遍,就是没有发现错误.
估计主要问题 自己用的延时与 开发者使用的延时程序不一致...
请版主指点.
//当主机把数据线从高逻辑电平拉至低逻辑电平时产生写时间片有两种类型的写时间片写
//1 时间片和写0 时间片所有时间片必须有最短为60 微秒的持续期在各写周期之间必须有最短
//为1 微秒的恢复时间
//在I/O 线由高电平变为低电平之后DS1820 在15 s 至60 s 的窗口之间对I/O 线采样如果
//线为高电平写1 就发生如果线为低电平便发生写0
#include <AT89X55.H> //单片机头文件包含文件
#include <absacc.h> //单片机头文件包含文件
#include <intrins.h> //单片机头文件包含文件
#define uchar unsigned char
#define uint unsigned int
uchar flag=1;
//#define ulong unsigned long
sbit DQ =P3^6; //定义通信端口
uchar temp_command; //接受上位机命令
uchar data_convert[4];
//_______________________
void delay(uchar x)
{while(--x); //延时 xus
}
//若参数采用uchar那么调度为2us
//delay(0):延时518us 518-2*256=6
//delay(1):延时7us
//delay(10):延时25us 25-20=5
//delay(20):延时45us 45-40=5
//delay(100):延时205us 205-200=5
//delay(200):延时405us 405-400=5
//_________________________
void init_ds18b20(void)//从高拉低保持至少480us,然后再拉高保持15us-60us;ds18b20发出低电平存在脉冲60-240us
{// uchar x;
DQ=1;
delay(5);//delay for a slight while
DQ=0;
delay(0); //518us
DQ=1;
delay(14);
flag=DQ; // 判定是否初始成flag?=0,则成功
delay(20);
}
uchar read_onechar_ds18b20(void) //读指令,是拉高再拉底至少保持1us,再拉高;实现读
{
uchar tdata=0;
uchar i=0;
// DQ=1;
for(i=8;i>0;i--)
{
DQ=1;
delay(1);
DQ=0;
tdata>>=1;
DQ=1; //再次拉高
if (DQ)
tdata|=0x80; //右移,与高位or,执行8次后,第一位移到最低位了
delay(4);
} //读指令之间需要 建立时间
return(tdata);
}
void write_onechar_ds18b20(uchar command_data) //?/数据线从高电平拉至低电平,产生写起始信号。15ms之内将所需写的位送到数据据线上
{
uchar i=0;
DQ=1;
for(i=8;i>0;i--)
{
DQ=0; //拉低
//delay(1); //相当于7us
DQ=command_data & 0x01;
delay(15); //保持一定时?0us
DQ=1; //拉高
command_data>>=1; //右移灰晃?
// delay(4); //写指令间需要恢复时间
}
}
uchar read_temp(void)
{
uchar templow;
uchar temphigh;
uchar tt;
//float t; //温度值
init_ds18b20(); //初始化
// if(flag) //若未初始化成功,继续初始化
// {
// init_ds18b20();
// while(flag<>0)
// {
// init_ds18b20();
// }
// }
write_onechar_ds18b20(0xCC); //单片操作,跳出读序列号操作
write_onechar_ds18b20(0x44); //启动温度转换
delay(125); //convert needs time
init_ds18b20(); //复位
write_onechar_ds18b20(0xCC);
write_onechar_ds18b20(0xBE); //读温度寄存器,分高位和低位
templow=read_onechar_ds18b20();//read lsb
temphigh=read_onechar_ds18b20();//read msb
//t=(temphigh*256+templow)*0.0625;//温度转化
tt=temphigh;
tt=tt<<8 ;
tt|=templow;
return(tt);
}
void s_data_convert(uint data_to_convert)//转换数据便于发送给上位机
{ data_convert[0]=(uchar)((data_to_convert&0xf000)>>12);
data_convert[1]=(uchar)((data_to_convert&0x0f00)>>8);
data_convert[2]=(uchar)((data_to_convert&0x00f0)>>4);
data_convert[3]=(uchar)(data_to_convert&0x000f);
}
void init_serial(void)
//串口初始化
{
TMOD=0x20; //model 2,T1
TH1=0xfd; //baud rate is 9600,11.0592HZ
TL1=0xfd;
// TCON=0x40; //start T1
SCON=0x50; //receive permission
PCON=0x00;
// IE=0x99; //enable EA,ES,ET1,EX0
ES=1;
EA=1;
TR1=1;
}
void read_serial(void) interrupt 4
{
RI =0; //RI=0接受数据
ES=0; //关闭所有中断
temp_command=SBUF; //接受命令,是否开始转换温度
ES=1; //接受完,打开所有中断
}
void main(void)
{ uint temp;
uchar i;
init_serial();
while(1)
{
while(temp_command!=0x11); //0x11定义为开始标志
temp_command=0; //清楚标志;
temp=read_temp(); //读温度
s_data_convert(temp);
for(i=0;i<4;i++)
{
SBUF=data_convert;
while(TI==0); //等待传送数据
TI =0;
}
}
} |
|