Renesas R7FA8D1BH (Cortex®-M85) 控制DS18B20

目录

概述

1 软硬件

1.1 软硬件环境信息

1.2 开发板信息

1.3 调试器信息

2 FSP和KEIL配置

2.1 硬件接口电路

2.2  FSB配置DS18B20的IO

2.3 生成Keil工程文件

3 DS18B20驱动代码

3.1 DS18B20介绍

3.2 DS18B20驱动实现

3.2.1 IO状态定义

3.2.2 读IO状态函数

3.2.3 其他函数

4 测试程序

4.1 应用程序设计

4.2 测试 

5 附件


Renesas R7FA8D1BH (Cortex®-M85) 控制DS18B20和ADC,实现两个页面的跳转功能

概述

本文主要介绍Renesas R7FA8D1BH (Cortex®-M85)设计一个综合的应用案例:应用R7FA8D1BH的IO实现单总线协议,实现驱动ds18b20的功能,其主要完成读取温度值,并将该值格式化显示在OLED屏幕上。还通过串口终端将温度数据发送至串口终端上。

1 软硬件

1.1 软硬件环境信息

软硬件信息 版本信息
Renesas MCU R7FA8D1BH
Keil MDK ARM 5.38
FSP 版本 5.3.0
调试工具:N32G45XVL-STB DAP-LINK

1.2 开发板信息

笔者选择使用野火耀阳开发板_瑞萨RA8,该板块的主控MCU为R7FA8D1BHECBD,7FA8D1BHECBD的内核为ARM Contex-M85。

1.3 调试器信息

对于R7FA8D1BHECBD芯片,其使用的内核为Cortex®-M85 Core, ST-LINK-V2或者J-LINK-V9不支持下载和调试功能。笔者经过多次尝试,发现N32G45XVL-STB板卡上自带的DAP-LINK可以下载和调试R7FA8D1BHECBD。

下图为N32G45XVL-STB开发板实物图:

2 FSP和KEIL配置

2.1 硬件接口电路

耀阳开发板_瑞萨RA8上已经设计了DS18B20的接口电路,其使用P809接口作为DS18B20的DQ控制信号。

2.2  FSB配置DS18B20的IO

配置P809为普通的IO接口,然后在代码中动态配置该IO的输出或者输出状态

2.3 生成Keil工程文件

 完成FSP的参数配置之后,就可以Generate Project。打开项目文件,其架构如下:

创建ds18b20.c文件,实现驱动代码

3 DS18B20驱动代码

3.1 DS18B20介绍

笔者在之前的文章中,已经详细分析过DS18B20的时序以及实现逻辑,这里不在做介绍。

DS18B20应用笔记_ds18b20读取数据的波形-CSDN博客

3.2 DS18B20驱动实现

3.2.1 IO状态定义

代码第14行:定义us步长延时函数

代码第15行:定义ms步长延时函数

代码第18行:定义DS18B20的IO PIN

代码第21行:输入端口配置

代码第22行:输出端口配置

代码第24行:设置IO低电平

代码第25行:设置IO高电平

3.2.2 读IO状态函数

代码第47行:读取输入模式下IO的状态

 3.2.3 其他函数

函数:ds18b20Init, 检测DS18B20是否在线

函数:ds18b20BlockModeProcess。 读取DS18B20的数值

/**
  * @brief  reset DS18B20
  * @note   if reset ds18b20 sucess, the return value is TRUE
  * @param  None
  * @retval True or Flalse
  */
static uint8_t ds18b20Init( void )
{
    uint16_t tempCnt = 0;
    bsp_io_level_t status;
   
    // Set PIN mode output
    DS_Mode_Out_PP();
    
    // Master pin is high 
    DQ_SET_HIGH;
    timeDelayUS(10);
    
    // Master pin is low 
    DQ_SET_LOW;
    // wait for 600 us 
    timeDelayUS(750);
    
    // Set PIN mode input
    DS_Mode_IN_PUT();
    
    while(1)
    {
        status = DQ_RAD_PIN();
        if( status == 0)
        {
            tempCnt = 0;
            return TRUE;
        }
        else
        {
          timeDelayUS(1);
          tempCnt++;
          if( tempCnt > 480 )
              return FALSE;
        }
    }
}


static uint8_t readBit( void )
{
    uint8_t readCnt = 2;
    uint8_t bitVal = 1;

    DQ_SET_LOW;
    timeDelayUS(3);
    DQ_SET_HIGH;
    
    timeDelayUS(5); // 15 us 
    
    while(readCnt-- )
    {
        //read DQ value 
        if( DQ_RAD_PIN() == 0)
        {
           bitVal = 0;
        }
        timeDelayUS(2);  // 15 us 
    }
    
    timeDelayUS(30);      // 15 us 

    return  bitVal;
}

static uint8_t ds18b20ReadByte( void )
{
   uint8_t byteVal = 0;
    
   for ( uint8_t i = 0; i < 8; i++ )
   {
        byteVal >>= 1;
       
        uint8_t bitVal = readBit(); 
        if( bitVal > 0)
        {
            byteVal |= 0x80;
        }
    }
   
    return  byteVal;
}


/**
  * @brief  write one byte to DS18B20
  * @note   
  * @param  byte: the data that is sended to ds18b20
  * @retval None
  */
void ds18b20WriteByte( uint8_t byte)
{
    unsigned char k;
    
    // Set PIN mode output
    DS_Mode_Out_PP();
    
    for ( k = 0; k < 8; k++ )
    {
        if (byte & (1<<k))
        {
            DQ_SET_LOW;
            timeDelayUS(2); 
 
            DQ_SET_HIGH;
            timeDelayUS(65); 
        }
        else
        {
            DQ_SET_LOW;
            timeDelayUS(65); 
 
            DQ_SET_HIGH;
            timeDelayUS(2); 
        }
    }
}

uint8_t ds18b20BlockModeProcess( void )
{
    uint16_t tempValue;
    uint8_t tempL, tempH;

    if (ds18b20Init() == FALSE)
    {
        return FALSE;
    }

    // wait for 600 us 
    timeDelayUS(600);
    
    ds18b20WriteByte(0xcc);
    ds18b20WriteByte(0x44);  // start convert temperature 

    if (ds18b20Init() == FALSE)
    {
        return FALSE;
    }
    // wait for 600 us 
    timeDelayUS(600);

    ds18b20WriteByte(0xcc);
    ds18b20WriteByte(0xbe);  // read temperature data register

    tempL = ds18b20ReadByte();
    tempH = ds18b20ReadByte();
    
    if (tempH > 0x7f) 
    {
        tempL    = ~tempL;
        tempH    = ~tempH+1; 
        st_ds1b20val.sign = 1;
    }

    tempValue = (uint16_t)((tempH << 8) | tempL);

    st_ds1b20val.temperatureVal = (float)(tempValue * 0.0625);
    
    return TRUE;
}


// NO blocking mode operate ds18b20 
uint8_t ds18b20NoBlockingProcess( void )
{
    uint16_t tempValue;
    static uint16_t waitCnt = 0;
    uint8_t tempL, tempH;
    static  uint8_t runState = 0;
    
    switch( runState )
    {
        default:
        case INIT_DQ:
            if (ds18b20Init() == FALSE)
            {
                return FALSE;
            }
            runState = WAIT_READY;
            break;
            
        case WAIT_READY:
            timeDelayUS(2);       // IDEL 
            runState = SKIDROM_CMD;
            break;
           
       case SKIDROM_CMD:
            ds18b20WriteByte(0xcc);
            ds18b20WriteByte(0x44);  // begin to convert temperature data
            waitCnt = 0;
            runState = WAIT_CONVERT;
            break;
       
       case WAIT_CONVERT:
           waitCnt++;
           if( waitCnt > WAIT_CNT_CONVERT)
           {
               waitCnt = 0;
               runState = RESET_CMD;
           }
           break;
        
        case RESET_CMD:
            if (ds18b20Init() == FALSE)
            {
                return FALSE;
            }
            runState = WAIT_DATA_READY;
            break;
            
        case WAIT_DATA_READY: 
            timeDelayUS(2);     // IDEL 
            runState = READ_CMD;
            break;
            
        case READ_CMD:
            ds18b20WriteByte(0xcc);
            ds18b20WriteByte(0xbe);  // read temperature data register
            runState = GET_VALUE;
            break;
            
        case GET_VALUE:

            tempL = ds18b20ReadByte();
            tempH = ds18b20ReadByte();

            if (tempH > 0x7f) 
            {
                tempL    = ~tempL;
                tempH    = ~tempH+1; 
                st_ds1b20val.sign = 1;
            }

            tempValue = (uint16_t)((tempH << 8) | tempL);

            st_ds1b20val.temperatureVal = (float)(tempValue * 0.0625);
            runState = INIT_DQ;
            return TRUE;
    }
    
    return FALSE;
}

4 测试程序

4.1 应用程序设计

代码113行:读取ds18b20的值

代码130行:获得ds18b20的结果数据

代码131行:格式化显示数据

代码132行:显示数据到OLED上

4.2 测试 

编译代码,并下载代码到板卡中,其运行结果如下:

5 附件

DS18B20的驱动代码

1)创建ds18b20.c文件,编写如下代码

 /*
 FILE NAME  :  ds18b20.c
 Description:  user ds18b20 interface 
 Author     :  tangmingfei2013@126.com
 Date       :  2024/06/03
 */
#include "ds18b20.h" 
#include "hal_data.h"

typedef enum{
  INPUT = 0,
  OUTPUT = 1,
}IO_TYPE;

typedef enum{
  FALSE = 0,
  TRUE = 1,
}RETURN_RESULT;

typedef enum{
   INIT_DQ = 0,
   WAIT_READY,
   SKIDROM_CMD,
    
   WAIT_CONVERT,
   RESET_CMD,
   READ_CMD,

   WAIT_DATA_READY,
   GET_VALUE,
   IDLE_NULL
}RUN_STATE;

ds18b20Struc st_ds1b20val;


ds18b20Struc get_ds18b20_value( void )
{
    return st_ds1b20val;
}

static bsp_io_level_t DQ_RAD_PIN(void)
{
    bsp_io_level_t state;

    // READ io
    R_IOPORT_PinRead(&g_ioport_ctrl, DS_IO_PORT_PIN, &state);
    
    return state;
}

/**
  * @brief  reset DS18B20
  * @note   if reset ds18b20 sucess, the return value is TRUE
  * @param  None
  * @retval True or Flalse
  */
static uint8_t ds18b20Init( void )
{
    uint16_t tempCnt = 0;
    bsp_io_level_t status;
   
    // Set PIN mode output
    DS_Mode_Out_PP();
    
    // Master pin is high 
    DQ_SET_HIGH;
    timeDelayUS(10);
    
    // Master pin is low 
    DQ_SET_LOW;
    // wait for 600 us 
    timeDelayUS(750);
    
    // Set PIN mode input
    DS_Mode_IN_PUT();
    
    while(1)
    {
        status = DQ_RAD_PIN();
        if( status == 0)
        {
            tempCnt = 0;
            return TRUE;
        }
        else
        {
          timeDelayUS(1);
          tempCnt++;
          if( tempCnt > 480 )
              return FALSE;
        }
    }
}


static uint8_t readBit( void )
{
    uint8_t readCnt = 2;
    uint8_t bitVal = 1;

    DQ_SET_LOW;
    timeDelayUS(3);
    DQ_SET_HIGH;
    
    timeDelayUS(5); // 15 us 
    
    while(readCnt-- )
    {
        //read DQ value 
        if( DQ_RAD_PIN() == 0)
        {
           bitVal = 0;
        }
        timeDelayUS(2);  // 15 us 
    }
    
    timeDelayUS(30);      // 15 us 

    return  bitVal;
}

static uint8_t ds18b20ReadByte( void )
{
   uint8_t byteVal = 0;
    
   for ( uint8_t i = 0; i < 8; i++ )
   {
        byteVal >>= 1;
       
        uint8_t bitVal = readBit(); 
        if( bitVal > 0)
        {
            byteVal |= 0x80;
        }
    }
   
    return  byteVal;
}


/**
  * @brief  write one byte to DS18B20
  * @note   
  * @param  byte: the data that is sended to ds18b20
  * @retval None
  */
void ds18b20WriteByte( uint8_t byte)
{
    unsigned char k;
    
    // Set PIN mode output
    DS_Mode_Out_PP();
    
    for ( k = 0; k < 8; k++ )
    {
        if (byte & (1<<k))
        {
            DQ_SET_LOW;
            timeDelayUS(2); 
 
            DQ_SET_HIGH;
            timeDelayUS(65); 
        }
        else
        {
            DQ_SET_LOW;
            timeDelayUS(65); 
 
            DQ_SET_HIGH;
            timeDelayUS(2); 
        }
    }
}

uint8_t ds18b20BlockModeProcess( void )
{
    uint16_t tempValue;
    uint8_t tempL, tempH;

    if (ds18b20Init() == FALSE)
    {
        return FALSE;
    }

    // wait for 600 us 
    timeDelayUS(600);
    
    ds18b20WriteByte(0xcc);
    ds18b20WriteByte(0x44);  // start convert temperature 

    if (ds18b20Init() == FALSE)
    {
        return FALSE;
    }
    // wait for 600 us 
    timeDelayUS(600);

    ds18b20WriteByte(0xcc);
    ds18b20WriteByte(0xbe);  // read temperature data register

    tempL = ds18b20ReadByte();
    tempH = ds18b20ReadByte();
    
    if (tempH > 0x7f) 
    {
        tempL    = ~tempL;
        tempH    = ~tempH+1; 
        st_ds1b20val.sign = 1;
    }

    tempValue = (uint16_t)((tempH << 8) | tempL);

    st_ds1b20val.temperatureVal = (float)(tempValue * 0.0625);
    
    return TRUE;
}


// NO blocking mode operate ds18b20 
uint8_t ds18b20NoBlockingProcess( void )
{
    uint16_t tempValue;
    static uint16_t waitCnt = 0;
    uint8_t tempL, tempH;
    static  uint8_t runState = 0;
    
    switch( runState )
    {
        default:
        case INIT_DQ:
            if (ds18b20Init() == FALSE)
            {
                return FALSE;
            }
            runState = WAIT_READY;
            break;
            
        case WAIT_READY:
            timeDelayUS(2);       // IDEL 
            runState = SKIDROM_CMD;
            break;
           
       case SKIDROM_CMD:
            ds18b20WriteByte(0xcc);
            ds18b20WriteByte(0x44);  // begin to convert temperature data
            waitCnt = 0;
            runState = WAIT_CONVERT;
            break;
       
       case WAIT_CONVERT:
           waitCnt++;
           if( waitCnt > WAIT_CNT_CONVERT)
           {
               waitCnt = 0;
               runState = RESET_CMD;
           }
           break;
        
        case RESET_CMD:
            if (ds18b20Init() == FALSE)
            {
                return FALSE;
            }
            runState = WAIT_DATA_READY;
            break;
            
        case WAIT_DATA_READY: 
            timeDelayUS(2);     // IDEL 
            runState = READ_CMD;
            break;
            
        case READ_CMD:
            ds18b20WriteByte(0xcc);
            ds18b20WriteByte(0xbe);  // read temperature data register
            runState = GET_VALUE;
            break;
            
        case GET_VALUE:

            tempL = ds18b20ReadByte();
            tempH = ds18b20ReadByte();

            if (tempH > 0x7f) 
            {
                tempL    = ~tempL;
                tempH    = ~tempH+1; 
                st_ds1b20val.sign = 1;
            }

            tempValue = (uint16_t)((tempH << 8) | tempL);

            st_ds1b20val.temperatureVal = (float)(tempValue * 0.0625);
            runState = INIT_DQ;
            return TRUE;
    }
    
    return FALSE;
}



/* End of this file */

2)创建ds18b20.h文件,编写如下代码

/*
    FILE NAME  :  ds18b20.h
    Description:  user ds18b20 interface 
    Author     :  tangmingfei2013@126.com
    Date       :  2024/06/03
*/
#ifndef DS18B20_H
#define DS18B20_H
#include "hal_data.h"
 
 
#define WAIT_CNT_CONVERT     500 

#define timeDelayUS(us)      R_BSP_SoftwareDelay(us, BSP_DELAY_UNITS_MICROSECONDS);
#define DS_DELAY_MS(ms)      R_BSP_SoftwareDelay(ms, BSP_DELAY_UNITS_MILLISECONDS);


#define DS_IO_PORT_PIN       BSP_IO_PORT_08_PIN_09


#define DS_Mode_IN_PUT()     R_IOPORT_PinCfg(&g_ioport_ctrl, DS_IO_PORT_PIN, IOPORT_CFG_PORT_DIRECTION_INPUT)
#define DS_Mode_Out_PP()     R_IOPORT_PinCfg(&g_ioport_ctrl, DS_IO_PORT_PIN, IOPORT_CFG_PORT_DIRECTION_OUTPUT)

#define DQ_SET_LOW           R_IOPORT_PinWrite(&g_ioport_ctrl, DS_IO_PORT_PIN, BSP_IO_LEVEL_LOW)
#define DQ_SET_HIGH          R_IOPORT_PinWrite(&g_ioport_ctrl, DS_IO_PORT_PIN, BSP_IO_LEVEL_HIGH)


typedef struct{
    float  temperatureVal; 
    bool sign;
}ds18b20Struc;

uint8_t ds18b20BlockModeProcess( void );
ds18b20Struc get_ds18b20_value( void );


#endif   /* DS18B20_H */


相关推荐

  1. 1单片机入门记录】DS18B20的应用

    2024-07-13 08:52:02       57 阅读
  2. 基于AT89C51单片机与DS18B20的温度测量系统

    2024-07-13 08:52:02       53 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-13 08:52:02       70 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-13 08:52:02       74 阅读
  3. 在Django里面运行非项目文件

    2024-07-13 08:52:02       62 阅读
  4. Python语言-面向对象

    2024-07-13 08:52:02       72 阅读

热门阅读

  1. Hive/Spark窗口函数

    2024-07-13 08:52:02       24 阅读
  2. 901. 股票价格跨度

    2024-07-13 08:52:02       26 阅读
  3. 北京电影学院学报

    2024-07-13 08:52:02       23 阅读
  4. C#往数据库上传文件

    2024-07-13 08:52:02       20 阅读
  5. 数据分包:145字节版本

    2024-07-13 08:52:02       24 阅读
  6. py2neo常用语句

    2024-07-13 08:52:02       29 阅读
  7. gitlab 备份和还原

    2024-07-13 08:52:02       31 阅读