„ 全数字温度转换及输出。 „ 先进的单总线数据通信。
„ 最高12位分辨率,精度可达土 0.5 摄氏度。 „ 12位分辨率时的最大工作周期为 750 毫秒。 „ 检测温度范围为–55°C ~+125 °C (–67°F ~+257 °F) „ 内置EEPROM ,限温报警功能。
DS18B20的温度检测与数字数据输出全集成于一个芯片之上,从而抗干扰力更强。其一个工作周期可分为两个部分,即温度检测和数据处理。在讲解其工作流程之前我们有必要了解 18B20 的内部存储器资源。18B20 共有三种形态的存储器资源,它们分别是:
ROM 只读存储器,用于存放DS18B20ID编码,其前 8 位是单线系列编码(DS18B20的编码是19H ),后面 48位是芯片唯一的序列号,最后 8 位是以上56的位的CRC 码(冗余校验)。数据在出产时设置不由用户更改。DS18B20共64位ROM。 RAM 数据暂存器,用于内部计算和数据存取,数据在掉电后丢失, DS18B20共9 个字节RAM,每个字节为8 位。第 1 、2 个字节是温度转换后的数据值信息,第 3 、4 个字节是用户 EEPROM(常用于温度报警值储存)的镜像。在上电复位时其值将被刷新。第5 个字节则是用户第 3 个EEPROM的镜像。第6、7 、8 个字节为计数寄存器,是为了让用户得到更高的温度分辨率而设计的,同样也是内部温度转换、计算的暂存单元。第9 个字节为前 8 个字节的CRC 码。EEPROM 非易失性记忆体,用于存放长期需要保存的数据,上下限温度报警值和校验数据,DS18B20共3 位EEPROM ,并在RAM都存在镜像,以方便用户操作。
此程序采用ATmega8_单片机,对DS18B20进行驱动。 #include #include #define DQ PC0 unsigned int temper;//温度 unsigned int temp1,temp2; unsigned char is_fuwen; #define uint unsigned int #define uchar unsigned char unsigned char flag; /***********18B20程序********/ void DS1302_Reset(void); unsigned char DS1302_Read(void); void DS1302_Write(unsigned char Data); void Read_Temperature(void); void putchar(unsigned int c); void putstring(unsigned int *p); unsigned int loaddata(void); void USARTINT(void); uint temp_convert(void);//温度转换 整数温度 //DS18B20 复位 void DS1302_Reset(void) { DDRC|=_BV(DQ); //DQ为输出状态 PORTC&=~_BV(DQ); //输出低电平 _delay_us(500); PORTC|=_BV(DQ); //示范总线 _delay_us(60); DDRC&=~_BV(DQ); //DQ位输出状态 while(PINC&_BV(DQ)); //等待从机DS18B20应答(低电平有效) while(!(PINC&_BV(DQ))); //等待从机DS18B20释放总线 } //DS18B20 读字节函数 unsigned char DS1302_Read(void) { unsigned char Temp=0,i; for(i=0;i<8;i++) { Temp>>=1; //数据右移 DDRC|=_BV(DQ); //DQ为输出状态 PORTC&=~_BV(DQ); //拉低总线,启动输入 PORTC|=_BV(DQ); //释放总线 DDRC&=~_BV(DQ); //DQ为输入状态 if(PINC&_BV(DQ)) Temp|=0x80; _delay_us(45); //延迟45微妙(最大45微妙) } return Temp; } void DS1302_Write(unsigned char Data) { unsigned char i; DDRC|=_BV(DQ); //DQ为输出 for(i=0;i<8;i++) { PORTC&=~_BV(DQ); //拉低总线 _delay_us(10); //延迟10微妙(最大15微妙) if(Data &0x01) PORTC|=_BV(DQ); else PORTC&=~_BV(DQ); _delay_us(40); //延迟40微妙(最大45微妙) PORTC|=_BV(DQ); //释放总线 _delay_us(1); //稍微延迟 Data>>=1; } } //读温度函数 void Read_Temperature(void) { DS1302_Reset(); //DS1302 复位 DS1302_Write(0xCC); //跳过ROM DS1302_Write(0x44); //温度转换 DS1302_Reset(); //DS1302 复位 DS1302_Write(0xCC); //跳过ROM DS1302_Write(0xbe); //读取RAM temp1=DS1302_Read(); //读低八位,LSByte,RAM0 temp2=DS1302_Read(); //读高八位,MSByte,RAM1 DS1302_Reset(); //DS1302 复位,表示读取结束 putchar(1); } uint temp_convert(void)//温度转换 整数温度 { uint a,b,temp_over; //temp_x=(temp_l&0x0f)*0.625+0.5; //小数部分 is_fuwen=temp2&0xf8; if(is_fuwen) { is_fuwen=1; temp2=~temp2; if(temp1==0) temp1++; //若低8位全为0且温度为负,取补时就要向高位进1 temp1=~temp1+1; } a=temp2; b=temp1; temp_over=(a<<8)|b; //移位>按位或>赋值 temp_over*=0.625; _delay_us(255); putchar(2); return temp_over; } /*******************************************************************************************************/ /***************************************串口程序********************************************************/ void putchar(unsigned int c) { while(!(UCSRA&(1< unsigned int loaddata(void) { while(!(UCSRA&(1< } /*******************************************************************************************************/ /*******************************************************************************************************/ int main(void) { USARTINT(); putchar(1); putchar(2); putchar(3); while(1) { Read_Temperature(); //调用读取温度函数 temper=temp_convert();//温度转换 整数温度 _delay_ms(1000);//稍微延迟 flag=0; putchar(temper); } } ISR(USART_RXC_vect) { flag=1; } 因篇幅问题不能全部显示,请点此查看更多更全内容