嵌入式开发入门-51单片机基础知识(9)- DS18B20
一、DS18B20简介
1、DS18B20是一个数字温度传感器,单总线传输数据,测量温度范围为-45℃-125℃,测量精度可配置为9位,10位,11位,12位,默认配置12位,分别对应0.5℃、0.25℃、0.125℃和0.0625℃。
二、温度测量
1、由于DS18B20通电后,处于空闲状态,不进行温度测量和转换,所以必须发出转换命令,DS18B20才开始工作。
2、DS18B20工作后,测量的数据存放自ScrachPad寄存器中,并返回空闲状态。在温度转换过程中,DS18B20发送0响应,转换完成后,发送1响应。
3、根据18B20 芯片手册中的电路图中看出,在不工作时,DQ拉高。
三、DS18B20操作步骤
第一步:初始化
1、主机发送复位脉冲;
2、主机接收DS18B20的存在脉冲;
第二步:ROM指令
1、SEARCH ROM(F0h)
搜索:系统刚通电时,如果存在多个从机,则需要使用Search ROM来识别总线中存在的各从机。
2、READ ROM(33h)
直接读取:该指令,只有在总线中只存在一个从机时使用。如果有多个存在,则会产生冲突。
3、MATCH ROM(55h)
匹配:该指令用于寻找总线中特定的从机。
4、SKIP ROM(CCh)
跳过:使用该指令不需要在使用其他ROM指令,可以直接操作总线上所有从机。如配合CONVERT指令,可以直接使能总线上所有从机开始工作转换。
5、ALARM ROM(ECh)
报警:该命令用于搜索总线中设置过报警参数的从机,在最近的转换过程中,是否有报警的设备。
第三步:功能指令
1、CONVERT T(44h)
转换温度:该指令用于启动单个温度转换,在外部供电时,18B20接收到该指令后,启动转换,转换进行时发送0,转换完成后发送1(DQ拉高,处于空闲状态)。
2、WRITE SCRATCHPAD(4Eh)
写指令:该命令用于主机将三字节的数据写入scratchpad寄存器中,第一个数据写入TH寄存器,第二个字节写入TL寄存器,第三个字节写入配置寄存器。
数据首先传输最低位。三个字节必须在主机发送复位请求前写入,否则数据会丢失。
3、READ SCRATCHPAD(BEh)
读指令:该命令用于主机读取scratchpad寄存器的内容。数据首先最低位开始,直到读取第九个字节。如果主机只需要一部分数据,则主机可以在读到自己需要的数据后,就发出复位指令终止读取。
4、COPY SCARTCHPAD(48h)
复制指令:该指令用于将scratchpad中TH、TL和配置寄存器的内容复制到主机EEPROM中。如果在寄生电源模式下使用,在发出该指令后的10us内,主机必须强上拉10ms。
5、RECALL E²
调用指令:该指令用于从EEPROM中调用报警触发值(TH和TL)和配置数据,并将数据分别放在scratchpad的字节2、3和4中。主机在调用命令之后,发出读取时隙,DS18B20将通过发送0或1来指示调用状态。
此命令允许主机将3字节的数据写入DS18B20的草稿行。第一个数据字节写入TH寄存器(暂存区的字节2),第二个字节写入TL寄存器(字节3),第三个字节写入配置寄存器(字节4)。数据必须首先传输最低有效位。所有三个字节必须在主机发出重置之前写入,否则数据可能已损坏。
四、初始化
1、大部分涉及到通信的地方,初始化一般就是握手过程,双方达成共识,我要开始发送数据了,对方准备好数据了等。
2、初始化步骤:
(1)主机拉低总线至少480us完成复位脉冲。(类似于先给对方搭个招呼,然后释放总线,看对方如何回复)
(2)主机释放总线。
(3)DS18B20检测上升沿(在15us和60us内)(DS18B20等待主机给他打招呼),
(4)检测到上升沿后,DS18B20将总线拉低60us-240us(DS18B20收到主机的招呼后,给主机回复招呼)
1 bit Ds18b20_Init(void) 2 { 3 bit flag; 4 DQ = 0; 5 Delay500us(); 6 DQ = 1; 7 Delay68us(); 8 flag = DQ; 9 Delay500us(); 10 return flag; 11 }
1 void Ds18b20_Check(void) 2 { 3 Lcd12864_Init(); 4 while(Ds18b20_Init())Lcd12864_Show_String(2,2,"NO SENSOR!"); //初始化 5 Lcd12864_Show_String(2,2,"Initial OK");//检测到DS18B20,打印ok,否则打印no sensor 6 Delay500ms(); 7 }
五、读写时隙
5.1写时隙
写入1时隙和写入0时隙。所有写入时隙持续时间至少为60us,单个写入时隙之间的恢复时间至少为1us,写入时隙都由主机将总线拉低开始。
要生成写入1的时隙,在总线拉低后,主机必须在15us内释放总线。
要生成写入0时隙,在总线拉低后,必须持续最少60us保持总线为低电平,然后在释放总线。
因为DS18B20在主机启动写入时隙后,在15us和60US之间采集主机数据,在这个期间为高,则向DS18B20写入1,如果为低,则写0。
1 void Ds18b20_Write_Low(void) 2 { 3 DQ = 0; 4 Delay68us(); 5 DQ = 1; 6 _nop_(); 7 _nop_(); 8 } 9 10 11 /******************************************************************************/ 12 // 函数名称:Ds18b20_Write_High 13 // 输入参数:无 14 // 输出参数:无 15 // 函数功能:DS18B20写1 16 /******************************************************************************/ 17 void Ds18b20_Write_High(void) 18 { 19 DQ = 0; 20 _nop_(); 21 _nop_(); 22 DQ = 1; 23 Delay68us(); 24 } 25 26 27 /******************************************************************************/ 28 // 函数名称:Ds18b20_Write_Cmd 29 // 输入参数:myCmd-命令 30 // 输出参数:无 31 // 函数功能:DS18B20写命令 32 /******************************************************************************/ 33 void Ds18b20_Write_Cmd(uint8 cmd) 34 { 35 uint8 i; 36 for(i=0;i<8;i++) 37 { 38 if(cmd&0x01)Ds18b20_Write_High(); 39 else Ds18b20_Write_Low(); 40 cmd >>= 1; 41 } 42 }
5.2读时隙
DS18B20只能在主机发出读取时隙时向主机发送数据。因此主机必须在发出readScratchpad[BEh]或readPower[B4h]命令后,立即生成读取时隙,以便DS18B20提供所请求的数据。
读取时隙的持续时间至少为60us,时隙之间的恢复时间至少为1us,然后释放总线,从而启动读取时隙。
在主机启动读取时隙后,DS18B20将在总线上传输1或0。
DS18B20通过使总线保持高电平来发送1,将总线拉低来发送0。
当发送0时,DS18B20将在时隙结束时释放总线,DS18B20发送的数据在启动读取时隙的下降沿之后15us内有效,因此,主机必须释放总线。然后从开始的15us内对总线状态进行采样。
uint8 Ds18b20_Read_Data(void) { uint8 tmpRead=0x00; uint8 i; for(i=0;i<8;i++) { tmpRead>>=1; DQ = 0; _nop_(); _nop_(); DQ = 1; _nop_(); _nop_(); if(DQ)tmpRead|=0x80;//读1 //else tmpRead|=0x00;//读0 Delay68us(); } return tmpRead; }
5.3忙信号检测
void Ds18b20_Busy_Check(void) { bit flag; //0-busy 1-done do{ DQ = 0; _nop_(); _nop_(); DQ = 1; _nop_(); _nop_(); flag = DQ; Delay68us(); }while(!flag); }
5.4获取温度值
void Ds18b20_Get_Temp(uint8 *tempValue){ uint8 valueLow,valueHigh; uint16 resultLow; //范围超过了255 Ds18b20_Init(); Ds18b20_Write_Cmd(0xcc);//skip rom Ds18b20_Write_Cmd(0x44);//convert T //Delay750ms();//busycheck Ds18b20_Busy_Check(); Ds18b20_Init(); Ds18b20_Write_Cmd(0xcc);//skip rom Ds18b20_Write_Cmd(0xbe);//read scratchpad valueLow = Ds18b20_Read_Data();//read byte0 valueHigh = Ds18b20_Read_Data();//read byte1 resultLow = (valueLow & 0x0f) * 625; valueLow >>= 4; *(tempValue+0) = (valueHigh *16 + valueLow)/100 + 0x30; //温度值的百位 *(tempValue+1) = (valueHigh *16 + valueLow)%100/10 + 0x30;//温度值的十位 *(tempValue+2) = (valueHigh *16 + valueLow)%100%10 + 0x30;//温度值的个位 *(tempValue+4) = resultLow/1000 + 0x30; //小数点后第一位 *(tempValue+5) = resultLow%1000/100 + 0x30; //小数点后第二位 *(tempValue+6) = resultLow%1000%100/10 + 0x30; //小数点后第三位 *(tempValue+7) = resultLow%1000%100%10 + 0x30; //小数点后第四位 }
5.5主函数
int main(void){ Ds18b20_Check(); //检测总线是否存在DS18B20 Lcd12864_Screen_Init(); //LCD12864界面初始化设置 while(1){ Ds18b20_Get_Temp(sampleResult); //读取温度 if (sampleResult[0] == '0')sampleResult[0] = ' ';//首位如果为0,则不显示 Lcd12864_Show_String(2, 2, sampleResult); //显示温度 } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理