DS18B20是一个很常见的温度传感器,对于学51的来说算是老朋友了,年轻人的第一个单总线协议学习范例,这里简单介绍一下,DS18B20最高具有12为精度(默认模式),分辨率达到0.0625摄氏度,且外围电路极其简单,甚至可以不接VCC,就靠数据流吊着就能工作。当然它工作时时序可没有那么简单,稍有不慎(延时错误),整个工作时序就混乱了,因此准确把我每次延时至关重要。
我们这里主要针对CD107D平台进行讨论,但总线协议这里不讲,有兴趣自己去研究哇,比赛方提供的驱动程序中有单总线驱动,官方给配的,十有八九好使,不过我在用的过程中却发现有时都回来数据是错的,温度没读对,在仔细研究后发现,官方给的驱动是针对STC89C52的,其中给的延时函数如下:
void Delay_OneWire(unsigned int t) //STC89C52RC { while(t--) }
而我们实际用的芯片是IAP15系列,作为1T单片机,指令执行速度是12T单片机的12倍,那么上面这个简陋延时函数实际上是以原来的1/12时间就执行完了,这个延时在DS18B20中能够正常使用吗?当然不能,因此在上述函数基础上进行改进:
void Delay_OneWire(unsigned int t) //STC15 { u8 i; while(t--) { for(i=0;i<12;i++); } }
由于手头没有示波器,我只能粗略的进行12次累加,执行时间大概是原先的10倍左右。
接下来就是按照数据手册指示,按部就班获取温度数据。
工作指令
1.温度转换指令:0x44(即44H),启动Ds18b20启动转换温度
2.读暂存器指令:0xBE(即BEH),读取暂存器中的九字节数据
3.写暂存器置零:0x4E(即4EH),把数据写入暂存器的TH、TL
4.赋值暂存器:0x48(即48H),把暂存器中的TH、TL写入EEPROM中
5.读电源供电方式:0xB4(即B4H):启动Ds18b20,发送电源供电方式
6.重调EEPROM:0xB8(即B8H):把EEPROM中的TH、TL读至暂存器
u16 rd_temperature() { u16 temp; u8 TH,TL; init_ds18b20(); //每次写入指令之前都要初始化 Write_DS18B20(0xcc); //跳过rom指令,控制总线所有设备 Write_DS18B20(0x44); //温度转换指令 init_ds18b20(); Write_DS18B20(0xcc); // 跳过rom指令 Write_DS18B20(0xbe); // 读取暂存器内容 TL=Read_DS18B20(); //先读高8位 TH=Read_DS18B20(); //再度低8位 temp=TH<<8|TL; temp*=0.0625; //12位精度 return temp; }
经过测试,正常工作,返回相应温度数据。
原文:https://www.cnblogs.com/masterwayne/p/12370076.html