目录
概述
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 */



















