加入星计划,您可以享受以下权益:

  • 创作内容快速变现
  • 行业影响力扩散
  • 作品版权保护
  • 300W+ 专业用户
  • 1.5W+ 优质创作者
  • 5000+ 长期合作伙伴
立即加入
  • 正文
    • 01模块来源
    • 02 规格参数
    • 03移植过程
    • ‍04移植验证
  • 相关推荐
  • 电子产业图谱
申请入驻 产业图谱

【CW32模块使用】DS18B20温度传感器

10/24 13:01
451
阅读需 21 分钟
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

0DS18B20数字温度传感器提供9位至12位精度的温度测量,并具有非易失性用户可编程上下触发点报警功能。DS18B20通过单总线通信,根据定义,只需要一条数据线(和地线)即可与单片机通信。此外,DS18B20可以直接从数据线获得电源(“寄生电源”),消除了每个DS18B20都有一个唯一的64位串行代码,这允许多个DS18B20在同一条总线上工作。因此,使用一个微处理器来实现是很简单的。

控制分布在大面积上的许多ds18b20。可以从此功能中受益的应用包括HVAC环境控制,建筑物,设备或机械内部的温度监测系统以及过程监测和控制系统

01模块来源

资料下载链接:https://pan.baidu.com/s/1L83uG8So6k1NG_QznraoFQ

02 规格参数

工作电压:3-5.5V

工作电流:750nA~1.5mA

测量分辨率:9位到12位可编程分辨率

温度量程: -55 ~ +125 ℃

测量精度:±0.5 ℃

通信协议:单总线

管脚数量:3 Pin(2.54mm间距排针

以上信息见厂家资料文件

03移植过程

我们的目标是将例程移植至CW32F030C8T6开发板上【实现读取温度的功能】。首先要获取资料,查看数据手册应如何实现读取数据,再移植至我们的工程。

3.1查看资料

时序说明

初始化:

将总线拉低,保存低电平至少480us。

转为输入模式,总线被上拉电阻拉高大约15~60us。

如果初始化成功则会产生一个由DS18B20所返回的低电平“0”,持续时间大约60~240us。

DS18B20释放总线,将总线拉高。

读时序:

将数据线拉低至少1us。

将数据线转为输入模式,DS18B20开始采集数据,大约15us。

18B20要送出0就把总线拉为低电平直到读周期结束。若要送出1则释放总线为高电平

注意:所有读时隙必须至少需要60us,且在两次独立的时隙之间至少需要1us的恢复时间。

写时序:

数据线先置低电平“0”,延时15us。

按从低位到高位的顺序发送数据(一次只发送一位)。

延时60us。

拉高数据线“1”。

穿越火线1~4步骤,直到发送完整的字节。

拉高数据线,释放总线。

寄存器说明

0xCC

主机可以使用此命令同时对总线上的所有设备进行寻址,而无需发送其他的任何地址。 DS18B20通过发出0XCC命令,然后是温度转换命令[44h]来执行同步温度转换。注意,只有在总线上有一个从设备时,Read Scratchpad [BEh]命令才能跟随Skip ROM命令。在这种情况下,通过允许主服务器从从服务器读取而不发送设备的64位ROM代码可以节省时间。如果总线上有多个从设备,那么Skip ROM命令后跟Read Scratchpad命令将导致数据冲突,因为多个设备将尝试传输数据同时进行。

0x44

该命令为启动单次温度转换。转换后,产生的温度数据存储在地址为【BEh】的2字节温度寄存器中。

0xBE

该命令允许主机读取温度寄存器上的内容。数据传输从低位开始,直到读取第9个字节(bit8=CRC)。如果只需要温度数据,主机可以在任何时候发出复位以终止读取。

温度换算

温度传感器的分辨率我们可配置为9、10、11或12位,分别对应于0.5°C、0.25°C、 0.125°C和0.0625°C的增量。开机时的默认分辨率是12位。我们不进行修改,因为分辨率越高就越精准。

例如数据手册中的示例,如当前当前的温度是+25.0625℃,寄存器读出的高8位数据为0000 0001,低8位数据为1001 0001。将其整合得到16位数据:0000 0001 1001 0001。再转换为10进制数据为401。将读取到的数据乘以分辨率即可得到实际温度。

401 * 0.0625 = 25.0625℃

2、引脚选择

3.2引脚选择

该模块有3个引脚,具体引脚连接见各引脚连接。

模块接线图

3.3移植至工程

工程模板参考入门手册的工程模板

移植步骤中的导入.c和.h文件与【CW32模块使用】DHT11温湿度传感器相同,只是将.c和.h文件更改为bsp_ds18b20.c与bsp_ds18b20.h。这里不再过多讲述,移植完成后面修改相关代码。

在文件bsp_ds18b20.c中,编写如下代码。

/* * Change Logs: * Date           Author       Notes * 2024-06-20     LCKFB-LP    first version */
#include "bsp_ds18b20.h"#include "stdio.h"
/****************************************************************** * 函 数 名 称:bsp_ds18b20_GPIO_Init * 函 数 说 明:MLX90614的引脚初始化 * 函 数 形 参:无 * 函 数 返 回:1未检测到器件   0检测到器件 * 作       者:LC * 备       注:无******************************************************************/char DS18B20_GPIO_Init(void){    unsigned char ret = 255;
    GPIO_InitTypeDef GPIO_InitStruct; // GPIO初始化结构体
    RCC_DQ_ENABLE();        // 使能GPIO时钟
    GPIO_InitStruct.Pins = GPIO_DQ;             // GPIO引脚    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; // 推挽输出    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;    // 输出速度高    GPIO_Init(PORT_DQ, &GPIO_InitStruct);       // 初始化
    ret = DS18B20_Check();//检测器件是否存在    return ret;}


/****************************************************************** * 函 数 名 称:DS18B20_Read_Byte * 函 数 说 明:从DS18B20读取一个字节 * 函 数 形 参:无 * 函 数 返 回:读取到的字节数据 * 作       者:LC * 备       注:无******************************************************************/uint8_t DS18B20_Read_Byte(void){        uint8_t i=0,dat=0;
        for (i=0;i<8;i++)        {        DQ_OUT();//设置为输入模式        DQ(0); //拉低        delay_us(2);        DQ(1); //释放总线        DQ_IN();//设置为输入模式        delay_us(12);        dat>>=1;        if( DQ_GET() )        {            dat=dat|0x80;        }        delay_us(50);     }        return dat;}
/****************************************************************** * 函 数 名 称:DS18B20_Write_Byte * 函 数 说 明:写一个字节到DS18B20 * 函 数 形 参:dat:要写入的字节 * 函 数 返 回:无 * 作       者:LC * 备       注:无******************************************************************/void DS18B20_Write_Byte(uint8_t dat){        uint8_t i;        DQ_OUT();//设置输出模式        for (i=0;i<8;i++)        {                if ( (dat&0x01) ) //写1                {                        DQ(0);                        delay_us(2);                        DQ(1);                        delay_us(60);                }                else //写0                {                        DQ(0);//拉低60us                        delay_us(60);                        DQ(1);//释放总线                        delay_us(2);                }        dat=dat>>1;//传输下一位        }}


/****************************************************************** * 函 数 名 称:DS18B20_Check * 函 数 说 明:检测DS18B20是否存在 * 函 数 形 参:无 * 函 数 返 回:1:未检测到DS18B20的存在  0:存在 * 作       者:LC * 备       注:无******************************************************************/uint8_t DS18B20_Check(void){        uint8_t timeout=0;    //复位DS18B20        DQ_OUT(); //设置为输出模式        DQ(0); //拉低DQ        delay_us(750); //拉低750us        DQ(1); //拉高DQ        delay_us(15);  //15us
    //设置为输入模式        DQ_IN();    //等待拉低,拉低说明有应答        while ( DQ_GET() &&timeout<200)        {                timeout++;//超时判断                delay_us(1);        };        //设备未应答        if(timeout>=200)                return 1;        else                timeout=0;
        //等待18B20释放总线        while ( !DQ_GET() &&timeout<240)        {                timeout++;//超时判断                delay_us(1);        };    //释放总线失败        if(timeout>=240)                return 1;
        return 0;}
/****************************************************************** * 函 数 名 称:DS18B20_Start * 函 数 说 明:DS18B20开始温度转换 * 函 数 形 参:无 * 函 数 返 回:无 * 作       者:LC * 备       注:无******************************************************************/void DS18B20_Start(void){        DS18B20_Check();                //查询是否有设备应答        DS18B20_Write_Byte(0xcc);   //对总线上所有设备进行寻址        DS18B20_Write_Byte(0x44);   //启动温度转换}
/****************************************************************** * 函 数 名 称:DS18B20_GetTemperture * 函 数 说 明:从ds18b20得到温度值 * 函 数 形 参:无 * 函 数 返 回:温度数据 * 作       者:LC * 备       注:无******************************************************************/float DS18B20_GetTemperture(void){        uint16_t temp;        uint8_t dataL=0,dataH=0;        float value;
        DS18B20_Start();        DS18B20_Check();        DS18B20_Write_Byte(0xcc);//对总线上所有设备进行寻址        DS18B20_Write_Byte(0xbe);// 读取数据命令        dataL=DS18B20_Read_Byte(); //LSB        dataH=DS18B20_Read_Byte(); //MSB        temp=(dataH<<8)+dataL;//整合数据

        if(dataH&0X80)//高位为1,说明是负温度        {                temp=(~temp)+1;                value=temp*(-0.0625);        }        else        {                value=temp*0.0625;        }        return value;}

在文件bsp_ds18b20.h中,编写如下代码。

/* * Change Logs: * Date           Author       Notes * 2024-06-20     LCKFB-LP    first version */#ifndef _BSP_DS18B20_H_#define _BSP_DS18B20_H_
#include "board.h"

//端口移植#define RCC_DQ_ENABLE() __RCC_GPIOB_CLK_ENABLE()#define PORT_DQ         CW_GPIOB#define GPIO_DQ         GPIO_PIN_0

//设置DQ输出模式#define DQ_OUT()  {                                GPIO_InitTypeDef GPIO_InitStruct;                                        GPIO_InitStruct.Pins = GPIO_DQ;                                         GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;                              GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;                                 GPIO_Init(PORT_DQ, &GPIO_InitStruct);                         }//设置DQ输入模式#define DQ_IN()   {                                GPIO_InitTypeDef GPIO_InitStruct;                                        GPIO_InitStruct.Pins = GPIO_DQ;                                         GPIO_InitStruct.Mode = GPIO_MODE_INPUT_PULLUP;                           GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;                                 GPIO_Init(PORT_DQ, &GPIO_InitStruct);                          }//获取DQ引脚的电平变化#define DQ_GET()        GPIO_ReadPin(PORT_DQ, GPIO_DQ)//DQ输出#define DQ(x)           GPIO_WritePin(PORT_DQ, GPIO_DQ, (x?GPIO_Pin_SET:GPIO_Pin_RESET))
void DS18B20_Reset(void);uint8_t DS18B20_Check(void);char DS18B20_GPIO_Init(void);void DS18B20_Start(void);float DS18B20_GetTemperture(void);#endif

‍04移植验证

在自己工程中的main主函数中,编写如下。

/* * Change Logs: * Date           Author       Notes * 2024-06-20     LCKFB-LP    first version */#include "board.h"#include "stdio.h"#include "bsp_uart.h"#include "bsp_ds18b20.h"
int32_t main(void){    board_init();        // 开发板初始化
    uart1_init(115200);        // 串口1波特率115200
    DS18B20_GPIO_Init();    while(1)    {        printf("温度 = %.2frnn", DS18B20_GetTemperture() );        delay_ms(1000);    }}

上电现象(手心温度36度、37度左右):

模块移植成功案例代码:

链接:https://pan.baidu.com/s/1FHARC1eodVU-O3N6vxbfAw?pwd=LCKF

提取码:LCKF

相关推荐

电子产业图谱

以开放、共享、互助为理念,致力于构建武汉芯源半导体CW32系列MCU生态社区。无论是嵌入式MCU小自还是想要攻破技术难题的工程师,亦或是需求解决方案的产品经理都可在CW32生态社区汲取营养、共同成长。

B站