时钟DS1302和温度传感器DS18B20用在一起会导致温度读取错误
下面程序是在主程序while(1)中不断测温,按k1查看日期时间,再按k2退出回到温度查看,但是这时温度显示为0000!
一个是P3^456管脚,一个是P3^7管脚,应该不影响的呀
有谁能解答一下!
#include "reg52.h"
#include<intrins.h>
typedef unsigned char u8; // x<=255
typedef unsigned int u16;
sbit DQ=P3^7;
sbit k1=P3^1; sbit k2=P3^0;
sbit LSA=P2^2;sbit LSB=P2^3;sbit LSC=P2^4;
sbit CLK=P3^6;sbit CE=P3^5;sbit IO_ds1302=P3^4;
void delay(u16 t) {while(t--);}
u8 code smgd[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00};
unsigned char code read_addr[7]={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d};
unsigned char code write_addr[7]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c};
//秒分时日周年
unsigned char TIME[7]={0x00,0x00,0x00,0x01,0x01,0x01,0x00};
//0000年1月1日星期一00点00分00秒
unsigned char a[22];
void dtsmg(int i,int key,int num)
{
LSA=i%2;
LSB=(i/2)%2;
LSC=i/4;
if(key==0) P0=smgd[num];
else P0=key;
delay(100);
P0=0x00;
}
//DS1302写单字节
void DS1302_Write_Byte(unsigned dat)
{
unsigned char i;
for(i=0;i<8;i++)
{
IO_ds1302=dat&0x01;
dat>>=1;
CLK=1;
_nop_();
CLK=0;
_nop_();
}
}
//DS1302写入函数
void DS1302_Write(unsigned char addr,unsigned char dat)
{
CE=0;
_nop_();
CLK=0;//拉低时钟,使CE(RST)能置高
_nop_();
CE=1;
_nop_();
DS1302_Write_Byte(addr);//写入地址
DS1302_Write_Byte(dat);//操作地址数据
CE=0;
_nop_();
}
//DS1302读取单字节
unsigned char DS1302_Read_Byte()
{
unsigned char i;
unsigned char dat=0x00;
for(i=0;i<8;i++)
{
dat>>=1;
if(IO_ds1302) dat|=0x80;
CLK=1;
_nop_();
CLK=0;
_nop_();
}
return dat;
}
//DS1302读取函数
unsigned char DS1302_Read(unsigned char addr)
{
unsigned char data_a;
CE=0;
_nop_();
CLK=0;
_nop_();
CE=1;
_nop_();
DS1302_Write_Byte(addr);
_nop_();
data_a=DS1302_Read_Byte();
CE=0;
_nop_();
CLK=1; //我也不知道这里为什么
_nop_();
IO_ds1302=0;
_nop_();
IO_ds1302=1;
_nop_();
return data_a;
}
void DS1302_Init()
{
unsigned char i;
DS1302_Write(0x8e,0x00);//关闭写保护
for(i=0;i<7;i++)
{
DS1302_Write(write_addr[i],TIME[i]);//秒分时日月周年
}DS1302_Write(0x8e,0x80);//打开写保护
}
void read_time()
{ char i;
for(i=0;i<7;i++)
{
TIME[i]=DS1302_Read(read_addr[i]);
}
}
//初始化 返回0位初始化成功
unsigned char Init_DS18B20()
{
char x;
DQ=0;
delay(60);
DQ=1;
delay(2);
x=DQ;
delay(25);
return x;
}
//写时序,写入一个字节
void Write_DS18B20(unsigned char dat)
{
char i,x;
DQ=1;//置位
for(i=0;i<8;i++)
{
x=dat&0x01;
DQ=0;
DQ=x;
dat>>=1;
delay(10);
DQ=1;//置位
delay(1);
}
}
//读时序,读取一个字节
unsigned char Read_DS18B20()
{
unsigned char dat=0x00;
char i,t;
//DQ=1;
for(i=0;i<8;i++)
{
DQ=0;
dat>>=1;
DQ=1;
t++;
t++;
if(DQ) dat|=0x80;
delay(4);
//DQ=1; ???
}return dat;
}
//读取温度
int ReadTemperature()
{
int temp=0;
unsigned char tmh,tml;
Init_DS18B20();
delay(110);
Write_DS18B20(0xcc);//跳过RAM
Write_DS18B20(0x44);//温度转换
Init_DS18B20();
delay(110);
Write_DS18B20(0xcc);
Write_DS18B20(0xbe);//读取温度
tml=Read_DS18B20();
tmh=Read_DS18B20();
temp=tmh;
temp<<=8;
temp|=tml;
return temp;
}
void Trainsport_DS18B20(int temp)
{
float tp;
int i;
u8 a[8]={0,0,0,0,0,0,0,0};
if(temp<0)
{
a[7]=0x40;
tp=~(temp-1);
temp=tp*0.0625*100+0.5;
}else
{
a[7]=0x00;
tp=temp;
temp=tp*0.0625*100+0.5;
}
a[2]=smgd[temp%10];
a[3]=smgd[temp%100/10];
a[4]=smgd[temp%1000/100];
a[5]=smgd[temp%10000/1000];
for(i=0;i<8;i++) dtsmg(i,a[i],16);
}
void main()
{
//DS1302_Init();//这里注释掉初始化,如果不注释这一开始温度显示也为0000
while(1)
{
Trainsport_DS18B20(ReadTemperature());
if(k1==0)
{
if(k1==0)
{
while(k2)
{
read_time();
dtsmg(0,0,TIME[0]%16);
dtsmg(1,0,TIME[0]/16);
dtsmg(3,0,TIME[1]%16);
dtsmg(4,0,TIME[1]/16);
dtsmg(6,0,TIME[2]%16);
dtsmg(7,0,TIME[2]/16);
dtsmg(2,0x40,0);
dtsmg(5,0x40,0);
}
}
}
}
}