基于AVR的DS18b20程序.docx
《基于AVR的DS18b20程序.docx》由会员分享,可在线阅读,更多相关《基于AVR的DS18b20程序.docx(3页珍藏版)》请在冰点文库上搜索。
![基于AVR的DS18b20程序.docx](https://file1.bingdoc.com/fileroot1/2023-4/28/7044f563-0253-4102-ba07-58c79d957ad4/7044f563-0253-4102-ba07-58c79d957ad41.gif)
//说明:
单片机ATmega16的18B20程序。
调这个18B20程序问题主要出现在延时部分,即单片机实际输出的延时与设定不符。
//后面为别人精确延时,我用自己的单片机通过示波器重新测量实际延时。
建议调延时用示波器先看看。
我用的晶振12M,但延时根本就与理论不符。
其中480us的延时要在480us与960us之间,选取550us比较合适,一般都这么选。
最后一句话:
DS18B20的程序很多,模块基本相似,调不出来就是因为延时问题,示波器是必备工具,否则很盲目。
#include
#defineucharunsignedchar
#defineucharunsignedchar
#defineuintunsignedint
//------------------------//
//...................18B20......................
voidinit_1820(void)
{
intFlag_1820Error;
uchari;
uintj=0;
PORTD|=(1<<7);//PORTC|=(1<<7);
PORTD&=~(1<<7);//PORTC&=~(1<<7);
for(i=0;i<8;i++)delay(180);//delay_60us();//480us以上
PORTD|=(1<<7);//PORTC|=(1<<7);
DDRD&=~(1<<7);//DDRC&=~(1<<7);//
delay(40);//delay_15us();//15~60us
delay(40);//delay_15us();
Flag_1820Error=0;
while(PIND&(1<<7)
{delay(180);//delay_60us();
j++;
if(j>=18000){Flag_1820Error=1;break;}
}
DDRD|=(1<<7);//DDRC|=(1<<7);//PORTC7isOUTPUT
PORTD|=(1<<7);//PORTC|=(1<<7);
for(i=0;i<4;i++)delay(180);//delay_60us();//240us
}
/********************************/
/********************************/
voidwrite_1820(ucharx)
{
ucharm;
for(m=0;m<8;m++)
{
if(x&(1<{
PORTD&=~(1<<7);//PORTC&=~(1<<7);delay_5us();//5us
PORTD|=(1<<7);//PORTC|=(1<<7);//write"1"
delay(40);//delay_15us();//15~45us
delay(40);//delay_15us();
delay(40);//delay_15us();
}
else
{
PORTD&=~(1<<7);//PORTC&=~(1<<7);delay_15us();//15us
delay(40);//delay_15us();//write"0"
delay(40);//delay_15us();//15~45us
delay(40);//delay_15us();
PORTD|=(1<<7);//PORTC|=(1<<7);
}
PORTD|=(1<<7);//PORTC|=(1<<7);
}
/*******************************/
ucharread_1820(void)
{
uchartemp,k,n;
temp=0;
for(n=0;n<8;n++)
{
PORTD&=~(1<<7);//PORTC&=~(1<<7);
delay(13);//delay_5us();
PORTD|=(1<<7);//PORTC|=(1<<7);
delay(13);//delay_5us();
DDRD&=~(1<<7);//DDRC&=~(1<<7);//"PINC7isINPUT"
k=(PIND&(1<<7));//k=(PINC&(1<<7));//读数据,从低位开始
if(k)
temp|=(1<else
temp&=~(1<delay(40);//delay_15us();//45us
delay(40);//delay_15us();
delay(40);//delay_15us();
DDRD|=(1<<7);//DDRC|=(1<<7);//
}
return(temp);
}
/*************************************/
floatread_temperature(void)
{
floattemp;////////////
ucharteml=0,temh=0;
unsignedlongt=0;
init_1820();//复位18b20
write_1820(0xcc);//发出转换命令
write_1820(0x44);
//Delay_nms(100);
init_1820();
write_1820(0xcc);//发出读命令
write_1820(0xbe);
teml=read_1820();//读数据byte1
temh=read_1820();//byte2
t=temh;
t=t<<8;
t=t|teml;
temp=t*0.0625*260/286;
return(temp);
/*if(temh&0xf8)sign=0;
elsesign=1;
if(sign==0){temh=255-temh;teml=255-teml;}
temh=temh<<4;
temh|=(teml&0xf0)>>4;
teml=teml&0x0f;
teml=(teml*10)/16;
tempval=temh;e[0]=tempval/100;
tempval=temh;e[1]=(tempval/10)%10;
tempval=temh;e[2]=tempval%10;
tempval=teml;e[3]=tempval;*/
}
//再在主程序中调用一下read_temperature(void),读取温度。