#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);
}
}
[page]
/
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);
}