参照网上的资料和DATESHEET写了一个DS18B20的程序,单片机为ATMEL128,晶振为8M,但是温度一直显示为255,从早上开始找原因,没有找到。现在把源代码发上来,各位能帮我分析一下原因吗?(程序未完整,只是发了温度部分,显示部分就不发了,调试是成功了)
#include <stdio.h>
#include <avr/io.h>
#include <util/delay.h>
#include <avr/iom128.h>
#include <string.h>
#define FREQ 8 //芯片工作频率
#define uchar unsigned char
#define uint unsigned int
/*******************温度设定********************/
#define DQ_H PORTA|= (1<<PA3) //DQ_H置高
#define DQ_L PORTA&= ~(1<<PA3) //DQ_L置低
#define DQ_R PINA //读取总线数据
#define DQ_IN DDRA&=~(1<<PA3) //设置PA3为输入
#define DQ_OUT DDRA|=(1<<PA3)//设置PA3为输出
static uchar *table[10]={"0","1","2","3","4","5","6","7","8","9",};
/******延时函数********/
void delay_nms(uint n)
{
uint i=0 ;
for (i=0 ;i<n ;i++)
_delay_loop_2(250*FREQ) ;
}
/********************************************************/
/* */
/* y*us延时函数 */
/* */
/********************************************************/
void delay(uint y)
{
_delay_loop_2(2*y);
}
/***************************DS18B20复位程序**************************/
void reset(void)
{
uchar flag;
flag=1;
while(flag)
{
DQ_L;
delay(600); //拉低总线600us,发送复位命令
DQ_H;
DQ_IN;
delay(60); //等待回应
if(PINA&_BV(PA3))
delay(350); //延时后继续复位
else
flag=0; //跳出复位
}
delay(350);//初始化完成,恢复高电平
DQ_OUT;
delay(2);
}
/**********************向DS18B20发送数据(从低位到高位)*******************/
void send_date1(uchar date)
{
uchar temp,i;
for(i=8;i>0;i--)
{
temp=(date&0x01); //检测date第一位是否为1
DQ_L;
delay(15);//产生发送时序
if(temp)
DQ_H;
else
DQ_L; //发送数据
delay(60); //等待DS18B20采样
DQ_H;
delay(2); //结束发送,进入下一个字节发送
date=(date>>1);
}
}
/********************从DS18B20读数据(高位到低位)***********/
uchar read_date1(void)
{
uchar date,i;
date=0x00;
for(i=8;i>0;i--)
{
DQ_L;
delay(1); //产生读时序
date=(date>>1);
DQ_H; //发送读取命令
DQ_IN;
delay(3);//释放总线
if((DQ_R&=(1<<PA3)))
date=(date|0x80); //如果总线数据为1,那么高位置1
delay(60); //一个读周期
DQ_H; //恢复总线
DQ_OUT;
delay(1);
}
return(date);
}
/**********************************温度函数**********************/
unsigned int readtemp(void)
{
uchar TVL,TVH;
// tempvalue=0x00;
unsigned int tempvalue,temp;
tempvalue=0;
temp=0;
reset();
send_date1(0xCC); //忽略RAM匹配
send_date1(0x44); //发送温度查询命令
reset(); //复位
send_date1(0xCC);
send_date1(0xBE); //读取暂存器上的温度数据
TVL=read_date1(); //温度低8位
TVH=read_date1(); //温度高8位
// TVL=0x55;
// TVH=0x02;
temp=TVH;
temp=(temp<<8);
tempvalue=(temp|TVL);
tempvalue=(tempvalue*0.0625);
/* t=(TVL&0xf0);
TVL=(t>>4);//整数部分低4位
TVH=((TVH&0x0f)<<4);//整数部分高4位
tempvalue=TVH|TVL;*/
return tempvalue;
}
|