598330983 发表于 2023-2-12 17:03

18B20单线传感器操作方法

/**************************************************************************//**
* @file   DS18B20.c
* @versionV1.00
* $Date: 19/06/17 3:56p $
* @brief DS18B20 Driver
*
*****************************************************************************/
#include "mini51series.h"
/*---------------------------------------------------------------------------*/
/* Macro definition                                                          */
/*---------------------------------------------------------------------------*/
#defineDQ                      P52            //DQ Pin

#defineCMD_SKIP_ROM            0xCC
#defineCMD_CONVERT_T         0x44
#defineCMD_READ_SCRATCHPAD   0xBE
/*---------------------------------------------------------------------------*/
/* Functions                                                               */
/*---------------------------------------------------------------------------*/
static void DS18B20_Reset(void);
static void DS18B20_WriteByte(uint8_t u8dat);
static uint8_t DS18B20_ReadByte(void);



/**
* @briefRead temperature from DS18B20
* @paramNone
* @returni16temp: temperature
*/
int16_t DS18B20_ReadTemperature(void)
{
    uint8_tu8tempH, u8tempL;
    int16_ti16temp;

    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);
}



/**
* @briefReset the DS18B20 and check if the device is present
* @paramNone
* @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
    }
}


/**
* @briefRead 1 byte data from DS18B20
* @paramNone
* @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;
}


/**
* @briefWrite 1 byte of data to the DS18B20
* @paramu8dat            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
* @versionV1.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 @ %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

关于这个传感器的代码示例太多了调试起来的难点还是在波形的精准上

aoyi 发表于 2023-3-3 10:29

看代码应该是 使用的普通的引脚模拟的是吗

zljiu 发表于 2023-3-3 10:37

为什么有时候在正常运行的时候会受到错误码呢

gwsan 发表于 2023-3-3 10:56

zljiu 发表于 2023-3-3 10:37
为什么有时候在正常运行的时候会受到错误码呢

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

tfqi 发表于 2023-3-3 11:10

gwsan 发表于 2023-3-3 10:56
估计可能有干扰信号了   然后还能恢复正常吗

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

AdaMaYun 发表于 2023-3-6 15:01

体积小,硬件开销低,抗干扰能力强,精度高,这个接线方式还有很多种

海滨消消 发表于 2023-3-21 11:33

代码看着就那么多,调试起来也没多容易

豌豆爹 发表于 2023-3-22 15:28

使用的什么引脚模拟的

claretttt 发表于 2023-4-16 22:08

可以通过单线协议进行通信。               

51xlf 发表于 2023-4-18 12:25

使用Arduino开发板和DS18B20温度传感器

adolphcocker 发表于 2023-4-18 13:51

在使用DS18B20单线传感器时,还需要实现CRC校验以确保数据完整性和准确性。

albertaabbot 发表于 2023-4-18 16:30

初始化:将单线总线拉高,并保持至少480微秒,然后将总线拉低,持续60-240微秒,意味着开始一个操作。

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

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

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

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

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

Jacquetry 发表于 2023-4-18 23:17

单总线对时间的精度要求比较高

huangcunxiake 发表于 2023-4-19 19:06

这个用的很多的。

星辰大海不退缩 发表于 2023-4-23 20:57

调试过程还是有好多经验的

AloneKaven 发表于 2023-5-10 23:58

单总线对时间要求很严格
页: [1]
查看完整版本: 18B20单线传感器操作方法