[DemoCode下载] 使用滴答延时函数实现DS18B20驱动

[复制链接]
1940|1
 楼主| zhuomuniao110 发表于 2024-6-21 21:13 | 显示全部楼层 |阅读模式
  1. /**************************************************************************//**
  2. * [url=home.php?mod=space&uid=288409]@file[/url]     main.c
  3. * [url=home.php?mod=space&uid=895143]@version[/url]  V2.10
  4. * $Date: 15/03/25 3:21p $
  5. * [url=home.php?mod=space&uid=247401]@brief[/url]    Sample Code for temperature sensor by GPIO 1wire.
  6. *
  7. * @note
  8. * Copyright (C) 2019 Nuvoton Technology Corp. All rights reserved.
  9. *
  10. ******************************************************************************/
  11. #include <stdio.h>
  12. #include <math.h>
  13. #include "nano100series.h"

  14. #define DQ      PD0
  15. /*---------------------------------------------------------------------------------------------------------*/
  16. /* Define global variables and constants                                                                   */
  17. /*---------------------------------------------------------------------------------------------------------*/
  18. volatile    uint16_t    g_u16Data;
  19. volatile    uint8_t     g_u8DataH, g_u8DataL;

  20. /* Initial DS18B20 */
  21. uint8_t init_DS18B20(void)
  22. {
  23.     uint8_t flag = 0;

  24.     /* TX rest pulse*/
  25.     DQ = 0;
  26.     CLK_SysTickDelay(480);

  27.     /* Wait for DS18B20 response*/
  28.     DQ = 1;
  29.     CLK_SysTickDelay(100);

  30.     /* Get response pulse*/
  31.     if (DQ == 0)
  32.         /* Detect DS18B20 success */
  33.         flag = 1;
  34.     else
  35.         /* Detect DS18B20 fail */
  36.         flag = 0;

  37.     CLK_SysTickDelay(380);
  38.     DQ = 1;

  39.     return flag;
  40. }

  41. /* Write a byte to DS18B20 */
  42. void writeDS18B20_byte(uint8_t u8wrData)
  43. {
  44.     uint8_t i;

  45.     for (i = 0; i < 8; i++)
  46.     {
  47.         /* Start write status */
  48.         DQ = 0;
  49.         CLK_SysTickDelay(15);

  50.         /* Write bit */
  51.         DQ = u8wrData & 0x01;
  52.         CLK_SysTickDelay(45);

  53.         /* Release bus */
  54.         DQ = 1;
  55.         u8wrData >>= 1;
  56.     }
  57. }

  58. /* Read a byte from DS18B20 */
  59. uint8_t readDS18B20_byte(void)
  60. {
  61.     uint8_t i, u8rdData = 0;

  62.     for (i = 0; i < 8; i++)
  63.     {
  64.         /* Start read status */
  65.         DQ = 0;
  66.         u8rdData >>= 1;
  67.         DQ = 1;
  68.         CLK_SysTickDelay(5);

  69.         /* Read bit */
  70.         if (DQ == 1)
  71.             u8rdData |= 0x80;

  72.         /* Wait bus in idle */
  73.         CLK_SysTickDelay(60);
  74.     }

  75.     return (u8rdData);
  76. }

  77. /* Combine high byte data with low byte data as temperature data */
  78. double DataCoding(uint16_t u16Data)
  79. {
  80.     double Temperature;
  81.     uint8_t i;
  82.     int8_t j;

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

  87.         u16Data >>= 1;
  88.     }

  89.     return (Temperature);
  90. }

  91. void SYS_Init(void)
  92. {
  93.     /* Unlock protected registers */
  94.     SYS_UnlockReg();

  95.     /* Enable external HIRC */
  96.     CLK_EnableXtalRC(CLK_PWRCTL_HIRC_EN_Msk);

  97.     /* Waiting for clock ready */
  98.     CLK_WaitClockReady(CLK_CLKSTATUS_HIRC_STB_Msk);

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

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

  104.     /* Enable IP clock */
  105.     CLK_EnableModuleClock(UART0_MODULE);
  106.     CLK_EnableModuleClock(TMR0_MODULE);

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

  113.     /* Lock protected registers */
  114.     SYS_LockReg();
  115. }

  116. void UART0_Init()
  117. {
  118.     /*---------------------------------------------------------------------------------------------------------*/
  119.     /* Init UART                                                                                               */
  120.     /*---------------------------------------------------------------------------------------------------------*/
  121.     UART_Open(UART0, 115200);
  122. }

  123. /*---------------------------------------------------------------------------------------------------------*/
  124. /* MAIN function                                                                                           */
  125. /*---------------------------------------------------------------------------------------------------------*/
  126. int main(void)
  127. {
  128.     /* Init System, IP clock and multi-function I/O
  129.        In the end of SYS_Init() will issue SYS_LockReg()
  130.        to lock protected register. If user want to write
  131.        protected register, please issue SYS_UnlockReg()
  132.        to unlock protected register if necessary */
  133.     SYS_Init();

  134.     /* Init UART for printf */
  135.     UART0_Init();

  136.     printf("+-------------------------------------+ \n");
  137.     printf("|    Temperature Sensor Sample Code   | \n");
  138.     printf("+-------------------------------------+ \n");

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

  142.     /*-----------------------------------------------------------------------------------------------------*/
  143.     /* DS18B20 Temperature Sensor test                                                                     */
  144.     /*-----------------------------------------------------------------------------------------------------*/
  145.     while (1)
  146.     {
  147.         /* Step 1: Initial DS18B20 */
  148.         if (init_DS18B20())
  149.         {
  150.             /* Step 2: ROM Command */
  151.             writeDS18B20_byte(0xCC);    /* Skip ROM command */
  152.             /* Step 3: Function Command */
  153.             writeDS18B20_byte(0x44);  /* Convert temperature */

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

  156.             /* Step 1: Initial DS18B20 */
  157.             if (init_DS18B20())
  158.             {
  159.                 /* Step 2: ROM Command */
  160.                 writeDS18B20_byte(0xCC);    /* Skip ROM command */
  161.                 /* Step 3: Function Command */
  162.                 writeDS18B20_byte(0xBE);    /* Read temperature data*/
  163.                 /* Get low byte data of temperature*/
  164.                 g_u8DataL = readDS18B20_byte();
  165.                 /* Get high byte data of temperature*/
  166.                 g_u8DataH = (readDS18B20_byte() & 0x0f);
  167.                 /* Combine high byte data with low byte data */
  168.                 g_u16Data = (g_u8DataH << 8) | g_u8DataL;

  169.                 printf("Temperature raw data = %f\n", DataCoding(g_u16Data));
  170.             }
  171.         }
  172.     }
  173. }

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


 楼主| zhuomuniao110 发表于 2024-6-21 21:14 | 显示全部楼层
该函数可以提供准确的微秒延时函数,很适合驱动DS18b 20
您需要登录后才可以回帖 登录 | 注册

本版积分规则

233

主题

3529

帖子

11

粉丝
快速回复 在线客服 返回列表 返回顶部