微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > AVR单片机的DS18B20 C语言程序

AVR单片机的DS18B20 C语言程序

时间:11-27 来源:互联网 点击:
#include

#include

#define uchar unsigned char

#define uint unsigned int

//

#define BIT_SET(a,b) a|=(1

#define BIT_CLR(a,b) a&=~(1//清零位a.b

#define BIT_INV(a,b) a^=(1//翻转位a.b

#define BIT_STATUS(a,b) a&(1//读取位a.b

/

#define CLR_DS18B20 BIT_CLR(PORTC,PC7) //数据线强制拉低

#define SET_DS18B20 BIT_SET(PORTC,PC7) //数据线强制拉高,上拉

#define HLD_DS18B20 BIT_SET(DDRC,PC7) //Mega16控制总线

#define RLS_DS18B20 BIT_CLR(DDRC,PC7) //释放总线

#define STU_DS18B20 BIT_STATUS(PINC,PC7) //数据线的状态

uchar const SEG7[10]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};

uchar const ACT[8]={0x08,0x04,0x02,0x01,0x80,0x40,0x20,0x10};

uint T;

//=============================

void delayUs(uchar temp)

{

while(temp--);

}

uchar resetDS18B20(void);

unsigned int readTempDS18B20(void);

void port_init(void)

{

PORTA = 0xFF;

DDRA = 0x00;

PORTB = 0xFF;

DDRB = 0xFF; //输出

PORTC = 0xFF;

DDRC = 0xFF; //输出

DDRD = 0xFF;

PORTD = 0xFF;

}

void delay_ms(uint k)

{

uint i,j;

for(i=0;i

{

for(j=0;j<570;j++);

}

}

//=============================

void display(uchar counter)

{

uchar i;

DDRA=0xff;

DDRC=0xff;

PORTA=0x00;

PORTC=0xff;

for(i=0;i<100;i++)

{

PORTA=SEG7[counter];

PORTC=ACT[3];

delay_ms(10);

PORTA=SEG7[counter/10];

PORTC=ACT[2];

delay_ms(10);

PORTA=SEG7[counter/100];

PORTC=ACT[1];

delay_ms(10);

PORTA=SEG7[counter/1000];

PORTC=ACT[0];

delay_ms(10);

}

}

void main()

{

port_init();

while(1)

{

resetDS18B20();

T=readTempDS18B20();

T=T>>4; //去除ds18b20转换的小数位(低四位)

display(T);

}

}


/

uchar resetDS18B20(void)

{

uchar errTime=0;

RLS_DS18B20; //释放总线

_NOP();

HLD_DS18B20; //Maga16控制总线

CLR_DS18B20; //强制拉低

delayUs(255); //209.42us

delayUs(255); //209.42us

delayUs(255); //83.28us

//以上的三个延时大于480us

RLS_DS18B20; //释放总线,总线自动上拉

_NOP();

while(STU_DS18B20)

{

delayUs(4); //5.15us

errTime++;

if(errTime>20)

return(0x00); //如果等待大于约 5.15us*20就返回0x00,报告复位失败(实际上只要等待15-60us)

}

errTime=0;

while(!(STU_DS18B20))

{

delayUs(4); //5.15us

errTime++;

if(errTime>50)

return(0x00); //如果等带大于约 5.15us*50就返回0x00,报告复位失败(实际上只要等待60-240us)

}

return(0xff);

}

/

uchar readByteDS18B20(void)

{

uchar i;

uchar retVal=0;

RLS_DS18B20; //释放总线

for(i=8;i>0;i--)

{

retVal>>=1;

HLD_DS18B20; //Maga16控制总线

CLR_DS18B20; //强制拉低

NOP();

NOP();

NOP();

NOP();

NOP();

NOP();

NOP();

NOP(); //延时大于1us

RLS_DS18B20; //释放总线,DS18B20会将总线强制拉高

NOP();

NOP();

NOP();

if(STU_DS18B20)

retVal|=0x80;

delayUs(16); //14.92us

delayUs(16); //14.92us

RLS_DS18B20; //释放总线

delayUs(35); //30.38us

}

delayUs(1); //2.71us(大于1us就行了)

return(retVal);

}

/

void writeByteDS18B20(uchar wb)

{

uchar i;

uchar temp;

RLS_DS18B20; //释放总线

for(i=0;i<8;i++)

{

HLD_DS18B20; //Maga16控制总线

CLR_DS18B20; //强制拉低

delayUs(16); //14.92us

temp=wb>>i;

temp&=0x01;

if(temp)

RLS_DS18B20; //释放总线

else

CLR_DS18B20; //强制拉低

delayUs(16); //14.92us

delayUs(35); //30.38us

RLS_DS18B20; //释放总线

delayUs(1); //2.71us(大于1us就行了)

}

}

/

unsigned int readTempDS18B20(void)

{

uchar tempL,tempH;

uint x;

resetDS18B20();

writeByteDS18B20(0xcc); //跳过ROM

writeByteDS18B20(0x44); //启动温度转换

delayUs(1);

resetDS18B20();

writeByteDS18B20(0xcc); //跳过ROM

writeByteDS18B20(0xbe); //读数据

tempL=readByteDS18B20();

tempH=readByteDS18B20();

x=(tempH<8)|tempL;

return(x);

}

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top