打印
[DemoCode下载]

使用滴答延时函数实现DS18B20驱动

[复制链接]
887|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
zhuomuniao110|  楼主 | 2024-6-21 21:13 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
/**************************************************************************//**
* [url=home.php?mod=space&uid=288409]@file[/url]     main.c
* [url=home.php?mod=space&uid=895143]@version[/url]  V2.10
* $Date: 15/03/25 3:21p $
* [url=home.php?mod=space&uid=247401]@brief[/url]    Sample Code for temperature sensor by GPIO 1wire.
*
* @note
* Copyright (C) 2019 Nuvoton Technology Corp. All rights reserved.
*
******************************************************************************/
#include <stdio.h>
#include <math.h>
#include "nano100series.h"

#define DQ      PD0
/*---------------------------------------------------------------------------------------------------------*/
/* Define global variables and constants                                                                   */
/*---------------------------------------------------------------------------------------------------------*/
volatile    uint16_t    g_u16Data;
volatile    uint8_t     g_u8DataH, g_u8DataL;

/* Initial DS18B20 */
uint8_t init_DS18B20(void)
{
    uint8_t flag = 0;

    /* TX rest pulse*/
    DQ = 0;
    CLK_SysTickDelay(480);

    /* Wait for DS18B20 response*/
    DQ = 1;
    CLK_SysTickDelay(100);

    /* Get response pulse*/
    if (DQ == 0)
        /* Detect DS18B20 success */
        flag = 1;
    else
        /* Detect DS18B20 fail */
        flag = 0;

    CLK_SysTickDelay(380);
    DQ = 1;

    return flag;
}

/* Write a byte to DS18B20 */
void writeDS18B20_byte(uint8_t u8wrData)
{
    uint8_t i;

    for (i = 0; i < 8; i++)
    {
        /* Start write status */
        DQ = 0;
        CLK_SysTickDelay(15);

        /* Write bit */
        DQ = u8wrData & 0x01;
        CLK_SysTickDelay(45);

        /* Release bus */
        DQ = 1;
        u8wrData >>= 1;
    }
}

/* Read a byte from DS18B20 */
uint8_t readDS18B20_byte(void)
{
    uint8_t i, u8rdData = 0;

    for (i = 0; i < 8; i++)
    {
        /* Start read status */
        DQ = 0;
        u8rdData >>= 1;
        DQ = 1;
        CLK_SysTickDelay(5);

        /* Read bit */
        if (DQ == 1)
            u8rdData |= 0x80;

        /* Wait bus in idle */
        CLK_SysTickDelay(60);
    }

    return (u8rdData);
}

/* Combine high byte data with low byte data as temperature data */
double DataCoding(uint16_t u16Data)
{
    double Temperature;
    uint8_t i;
    int8_t j;

    for (i = 0, j = -4; i < 12; i++, j++)
    {
        if (u16Data & 0x01)
            Temperature += pow(2, j);

        u16Data >>= 1;
    }

    return (Temperature);
}

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

    /* Enable external HIRC */
    CLK_EnableXtalRC(CLK_PWRCTL_HIRC_EN_Msk);

    /* Waiting for clock ready */
    CLK_WaitClockReady(CLK_CLKSTATUS_HIRC_STB_Msk);

    /* Set HCLK source form HIRC and HCLK source divide 1  */
    CLK_SetHCLK(CLK_CLKSEL0_HCLK_S_HIRC, CLK_HCLK_CLK_DIVIDER(1));

    /* Select IP clock source */
    CLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UART_S_HIRC, CLK_UART_CLK_DIVIDER(1));
    CLK_SetModuleClock(TMR0_MODULE, CLK_CLKSEL1_TMR0_S_HIRC, 0);

    /* Enable IP clock */
    CLK_EnableModuleClock(UART0_MODULE);
    CLK_EnableModuleClock(TMR0_MODULE);

    /*---------------------------------------------------------------------------------------------------------*/
    /* Init I/O Multi-function                                                                                 */
    /*---------------------------------------------------------------------------------------------------------*/
    /* Set PB multi-function pins for UART0 RXD and TXD */
    SYS->PB_L_MFP &= ~(SYS_PB_L_MFP_PB0_MFP_Msk | SYS_PB_L_MFP_PB1_MFP_Msk);
    SYS->PB_L_MFP |= (SYS_PB_L_MFP_PB0_MFP_UART0_RX | SYS_PB_L_MFP_PB1_MFP_UART0_TX);

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

void UART0_Init()
{
    /*---------------------------------------------------------------------------------------------------------*/
    /* Init UART                                                                                               */
    /*---------------------------------------------------------------------------------------------------------*/
    UART_Open(UART0, 115200);
}

/*---------------------------------------------------------------------------------------------------------*/
/* MAIN function                                                                                           */
/*---------------------------------------------------------------------------------------------------------*/
int main(void)
{
    /* Init System, IP clock and multi-function I/O
       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 if necessary */
    SYS_Init();

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

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

    /*  Configure PD.0 as Open Drain mode for 1wire communication */
    GPIO_SetMode(PD, BIT0, GPIO_PMD_OPEN_DRAIN);
    PD0 = 1;

    /*-----------------------------------------------------------------------------------------------------*/
    /* DS18B20 Temperature Sensor test                                                                     */
    /*-----------------------------------------------------------------------------------------------------*/
    while (1)
    {
        /* Step 1: Initial DS18B20 */
        if (init_DS18B20())
        {
            /* Step 2: ROM Command */
            writeDS18B20_byte(0xCC);    /* Skip ROM command */
            /* Step 3: Function Command */
            writeDS18B20_byte(0x44);  /* Convert temperature */

            /* Delay for converting temperature */
            TIMER_Delay(TIMER0, 1000000);

            /* Step 1: Initial DS18B20 */
            if (init_DS18B20())
            {
                /* Step 2: ROM Command */
                writeDS18B20_byte(0xCC);    /* Skip ROM command */
                /* Step 3: Function Command */
                writeDS18B20_byte(0xBE);    /* Read temperature data*/
                /* Get low byte data of temperature*/
                g_u8DataL = readDS18B20_byte();
                /* Get high byte data of temperature*/
                g_u8DataH = (readDS18B20_byte() & 0x0f);
                /* Combine high byte data with low byte data */
                g_u16Data = (g_u8DataH << 8) | g_u8DataL;

                printf("Temperature raw data = %f\n", DataCoding(g_u16Data));
            }
        }
    }
}

/*** (C) COPYRIGHT 2013 Nuvoton Technology Corp. ***/


使用特权

评论回复
沙发
zhuomuniao110|  楼主 | 2024-6-21 21:14 | 只看该作者
该函数可以提供准确的微秒延时函数,很适合驱动DS18b 20

使用特权

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

本版积分规则

197

主题

3286

帖子

10

粉丝