打印
[DemoCode下载]

18B20单线传感器操作方法

[复制链接]
1075|18
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
598330983|  楼主 | 2023-2-12 17:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
/**************************************************************************//**
* [url=home.php?mod=space&uid=288409]@file[/url]     DS18B20.c
* [url=home.php?mod=space&uid=895143]@version[/url]  V1.00
* $Date: 19/06/17 3:56p $
* [url=home.php?mod=space&uid=247401]@brief[/url] DS18B20 Driver
*
*****************************************************************************/
#include "mini51series.h"
/*---------------------------------------------------------------------------*/
/* Macro definition                                                          */
/*---------------------------------------------------------------------------*/
#define  DQ                      P52            //DQ Pin

#define  CMD_SKIP_ROM            0xCC
#define  CMD_CONVERT_T           0x44
#define  CMD_READ_SCRATCHPAD     0xBE
/*---------------------------------------------------------------------------*/
/* Functions                                                                 */
/*---------------------------------------------------------------------------*/
static void DS18B20_Reset(void);
static void DS18B20_WriteByte(uint8_t u8dat);
static uint8_t DS18B20_ReadByte(void);



/**
  * @brief  Read temperature from DS18B20
  * @param  None
  * [url=home.php?mod=space&uid=266161]@return[/url]  i16temp: temperature
  */
int16_t DS18B20_ReadTemperature(void)
{
    uint8_t  u8tempH, u8tempL;
    int16_t  i16temp;

    DS18B20_Reset();
    DS18B20_WriteByte(CMD_SKIP_ROM);
    DS18B20_WriteByte(CMD_CONVERT_T);

    while (!DQ);                             //Waiting for conversion to complete

    DS18B20_Reset();
    DS18B20_WriteByte(CMD_SKIP_ROM);
    DS18B20_WriteByte(CMD_READ_SCRATCHPAD);
    u8tempL = DS18B20_ReadByte();            //Read temperature low byte
    u8tempH = DS18B20_ReadByte();            //Read temperature high byte
    i16temp = (u8tempH << 8) | u8tempL;

    return (i16temp);
}



/**
  * @brief  Reset the DS18B20 and check if the device is present
  * @param  None
  * @return None
  */
static void DS18B20_Reset(void)
{
    uint8_t i;
    i = 1;

    while (i)
    {
        DQ = 0;                              //Send a low level reset signal
        CLK_SysTickDelay(480);               //Delay at least 480us
        DQ = 1;                              //Release data line
        CLK_SysTickDelay(60);                //Waiting for 60us
        i = DQ;                              //Detect the presence of pulses
        CLK_SysTickDelay(420);               //Waiting for the device to release the data line
    }
}


/**
  * @brief  Read 1 byte data from DS18B20
  * @param  None
  * @return u8dat: Read data
  */
static uint8_t DS18B20_ReadByte(void)
{
    uint8_t i;
    uint8_t u8dat = 0;

    for (i = 0; i < 8; i++)
    {
        u8dat >>= 1;
        DQ = 0;                              //Start time slice
        CLK_SysTickDelay(1);                 //Delay waiting
        DQ = 1;                              //Ready to receive
        CLK_SysTickDelay(1);                 //Reception delay

        if (DQ) u8dat |= 0x80;               //Read data

        CLK_SysTickDelay(60);                //Waiting for the end of time
    }

    return u8dat;
}


/**
  * @brief  Write 1 byte of data to the DS18B20
  * @param  u8dat            Write data
  * @return None
  */
static void DS18B20_WriteByte(uint8_t u8dat)
{
    uint8_t i;

    for (i = 0; i < 8; i++)
    {
        DQ = 0;                              //Start time slice
        CLK_SysTickDelay(1);                 //Delay waiting

        if (u8dat & 0x01) DQ = 1;            //Send data

        CLK_SysTickDelay(60);                //Waiting for the end of time
        DQ = 1;                              //Restore data line
        CLK_SysTickDelay(1);                 //Recovery delay
        u8dat >>= 1;
    }
}


使用特权

评论回复
沙发
598330983|  楼主 | 2023-2-12 17:03 | 只看该作者
/**************************************************************************//**
* @file     main.c
* @version  V1.00
* $Date: 19/06/17 3:56p $
* @brief    MINI51 DS18B20 Driver Sample Code
*
* @note
* Copyright (C) 2019 Nuvoton Technology Corp. All rights reserved.
*
*****************************************************************************/
#include <stdio.h>
#include "mini51series.h"

int16_t DS18B20_ReadTemperature(void);

void SYS_Init(void)
{
    /* Unlock protected registers */
    SYS_UnlockReg();

    /*---------------------------------------------------------------------------------------------------------*/
    /* Init System Clock                                                                                       */
    /*---------------------------------------------------------------------------------------------------------*/

    /* Enable external 12MHz XTAL, internal 22.1184MHz */
    CLK->PWRCON |= CLK_PWRCON_XTL12M | CLK_PWRCON_IRC22M_EN_Msk;

    /* Waiting for clock ready */
    CLK_WaitClockReady(CLK_CLKSTATUS_XTL_STB_Msk | CLK_CLKSTATUS_IRC22M_STB_Msk);

    /* Switch HCLK clock source to XTL */
    CLK_SetHCLK(CLK_CLKSEL0_HCLK_S_XTAL, CLK_CLKDIV_HCLK(1));

    /* STCLK to XTL STCLK to XTL */
    CLK_SetSysTickClockSrc(CLK_CLKSEL0_STCLK_S_XTAL);

    /* Enable IP clock */
    CLK_EnableModuleClock(UART_MODULE);

    /* Select IP clock source */
    CLK_SetModuleClock(UART_MODULE, CLK_CLKSEL1_UART_S_XTAL, CLK_CLKDIV_UART(1));

    /*---------------------------------------------------------------------------------------------------------*/
    /* Init I/O Multi-function                                                                                 */
    /*---------------------------------------------------------------------------------------------------------*/
    /* Set P0 multi-function pins for UART RXD and TXD */
    SYS->P0_MFP &= ~(SYS_MFP_P01_Msk | SYS_MFP_P00_Msk);
    SYS->P0_MFP |= (SYS_MFP_P01_RXD | SYS_MFP_P00_TXD);

    /* To update the variable SystemCoreClock */
    SystemCoreClockUpdate();

    /* Lock protected registers */
    SYS_LockReg();
}

void UART_Init(void)
{
    /*---------------------------------------------------------------------------------------------------------*/
    /* Init UART                                                                                               */
    /*---------------------------------------------------------------------------------------------------------*/
    /* Reset IP */
    SYS_ResetModule(SYS_IPRSTC2_UART_RST_Msk);

    /* Configure UART and set UART Baudrate */
    UART_Open(UART, 115200);

}

/*---------------------------------------------------------------------------------------------------------*/
/* MAIN function                                                                                           */
/*---------------------------------------------------------------------------------------------------------*/
int main(void)
{
    float t;

    /* Init System, IP clock and multi-function I/O */
    SYS_Init(); //In the end of SYS_Init() will issue SYS_LockReg() to lock protected register. If user want to write protected register, please issue SYS_UnlockReg() to unlock protected register.

    /* Init UART for printf */
    UART_Init();

    printf("\n\nCPU [url=home.php?mod=space&uid=72445]@[/url] %dHz\n", SystemCoreClock);

    printf("+-------------------------------------+ \n");
    printf("|        DS18B20 Sample Code          | \n");
    printf("+-------------------------------------+ \n");

    /* Configure P5.2 as Quasi mode  */
    GPIO_SetMode(P5, BIT2, GPIO_PMD_QUASI);

    while (1)
    {
        t = DS18B20_ReadTemperature() * 0.0625;
        printf("\n%f\n", t);
        CLK_SysTickDelay(1000000);//delay 1 sec
    }

}


使用特权

评论回复
板凳
tpgf| | 2023-3-3 09:07 | 只看该作者
18B20是非常经典的温度传感器了  用的是iic总线通讯

使用特权

评论回复
地板
nawu| | 2023-3-3 09:43 | 只看该作者
关于这个传感器的代码示例太多了  调试起来的难点还是在波形的精准上

使用特权

评论回复
5
aoyi| | 2023-3-3 10:29 | 只看该作者
看代码应该是 使用的普通的引脚模拟的是吗

使用特权

评论回复
6
zljiu| | 2023-3-3 10:37 | 只看该作者
为什么有时候在正常运行的时候会受到错误码呢

使用特权

评论回复
7
gwsan| | 2023-3-3 10:56 | 只看该作者
zljiu 发表于 2023-3-3 10:37
为什么有时候在正常运行的时候会受到错误码呢

估计可能有干扰信号了   然后还能恢复正常吗

使用特权

评论回复
8
tfqi| | 2023-3-3 11:10 | 只看该作者
gwsan 发表于 2023-3-3 10:56
估计可能有干扰信号了   然后还能恢复正常吗

这个说不好  这得看是什么原因导致总线上返回错误码的

使用特权

评论回复
9
AdaMaYun| | 2023-3-6 15:01 | 只看该作者
体积小,硬件开销低,抗干扰能力强,精度高,这个接线方式还有很多种

使用特权

评论回复
10
海滨消消| | 2023-3-21 11:33 | 只看该作者
代码看着就那么多,调试起来也没多容易

使用特权

评论回复
11
豌豆爹| | 2023-3-22 15:28 | 只看该作者
使用的什么引脚模拟的

使用特权

评论回复
12
claretttt| | 2023-4-16 22:08 | 只看该作者
可以通过单线协议进行通信。               

使用特权

评论回复
13
51xlf| | 2023-4-18 12:25 | 只看该作者
使用Arduino开发板和DS18B20温度传感器

使用特权

评论回复
14
adolphcocker| | 2023-4-18 13:51 | 只看该作者
在使用DS18B20单线传感器时,还需要实现CRC校验以确保数据完整性和准确性。

使用特权

评论回复
15
albertaabbot| | 2023-4-18 16:30 | 只看该作者
初始化:将单线总线拉高,并保持至少480微秒,然后将总线拉低,持续60-240微秒,意味着开始一个操作。

发送指令:在总线上发送指令(例如读取温度)。

接收响应:释放总线,并等待从DS18B20返回的响应信号。如果DS18B20准备好了,则它会拉低总线15-60微秒作为响应信号。

读取数据:依次读取每个字节的数据,共计9个字节。第一个字节是温度数据的最低位,第二个字节是温度数据的次低位,第三个字节是温度数据的次高位,第四个字节是温度数据的最高位。

计算温度值:使用读取到的4个字节的数据计算出温度值。

完成操作:拉低总线至少1微秒,表示完成操作。

使用特权

评论回复
16
Jacquetry| | 2023-4-18 23:17 | 只看该作者
单总线对时间的精度要求比较高

使用特权

评论回复
17
huangcunxiake| | 2023-4-19 19:06 | 只看该作者
这个用的很多的。

使用特权

评论回复
18
星辰大海不退缩| | 2023-4-23 20:57 | 只看该作者
调试过程还是有好多经验的

使用特权

评论回复
19
AloneKaven| | 2023-5-10 23:58 | 只看该作者
单总线对时间要求很严格

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

249

主题

5397

帖子

22

粉丝