AVR的DS18B20温度程序
#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;
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);
return tempvalue;
}
#define DQ_data PORTC.7
#define DQ_bus(x) DDRC.7 = x
void DS18B20_Init()
{
uint i = 0;
DQ_bus(1);
DQ_data = 1;
DQ_data = 0;
delay_us(640);
DQ_data =1;
DQ_bus(0);
// delay_us(60);
while(PINC.7)
{
delay_us(60);
i++;
if(i >= 10000)
{
flag = 1;
break;
}
}
delay_us(480);
DQ_bus(1);
DQ_data = 1;
}
void DS18b20_Write(uchar dat)
{
uchar m;
DQ_bus(1);
for(m = 0;m < 8; m++)
{
DQ_data = 0;
delay_us(15);
if(dat &(1 << m))
{
DQ_data = 1;
delay_us(15);
delay_us(15);
delay_us(15);
}
else
{
DQ_data = 0;
delay_us(15);
delay_us(15);
delay_us(15);
delay_us(15);
}
DQ_data = 1;
}
DQ_bus(1);
DQ_data = 1;
}
uchar DS18b20_Read()
{
uchar n,temp,k;
temp = 0;
// IO_In;
for(n = 0;n < 8;n++)
{
DQ_bus(1);
DQ_data = 1;
delay_us(2);
DQ_data = 0;
delay_us(6);
DQ_data = 1;
delay_us(4);
DQ_bus(0);
k = (PINC & (1 << 7));
if(k)
{
temp |= (1 << n);
}
else
{
temp &= ~(1 << n);
}
delay_us(30);
// DQ_bus(1);
}
return (temp);
}
void Gettemp()
{
uint w;
// uchar i;
DS18B20_Init();
DS18b20_Write(0xcc);
DS18b20_Write(0x44);
delay_ms(100);
DS18B20_Init();
DS18b20_Write(0xcc);
DS18b20_Write(0xbe);
templ = DS18b20_Read();
temph = DS18b20_Read();
// uint w;
// uchar i;
// Gettemp();
w = temph;
w = w << 8;
w = w | templ;
if(w < 0x0fff)
sign1 = 1;
else
{
w = ~w + 1;
sign1 = 0;
}
w = w * (0.625) - 40;
e[0] = w / 1000 + 0x30;
e[1] = w % 1000 / 100 + 0x30;
e[2] = w % 100 / 10 + 0x30;
e[3] = w % 10 +0x30;
}
这个程序我测试过了,你自己对一下吧
谢谢分享