Design of Environmental Monitoring System Based on Renesas RA6M5

Design of Environmental Monitoring System Based on Renesas RA6M5

1. Design brief

The preliminary design idea of ​​this project is to use Renesas microcontroller as the control and data processing unit, use temperature, humidity, and light sensors to monitor the surrounding environmental parameters, and complete the display of sensor data and related information on the screen. At the same time, use the WIFI wireless module to exchange data with the single-chip microcomputer, and access the cloud platform of the Internet of Things. Try to use the host computer to realize the monitoring of relevant environmental parameters such as temperature, humidity, and light intensity. However, due to time constraints and limited personal ability, only part of the design has been completed.

This project is based on the Qiming 6M5 development board to complete the design of the environmental monitoring system. The sensor DHT11 obtains the data of temperature and humidity; the sensor GY39 obtains the data of light intensity; the 0.96-inch OLED screen provides display functions, which can display sensor data and related information. Write the host computer software to realize the reporting of temperature and humidity sensor data.

2. Design framework

3. Project description

The RA family of microcontrollers (MCUs), launched in October 2019, complements Renesas' 32-bit MCU portfolio. Renesas RA series product family includes: RA2 series RA4 series, RA6 series RA8 series

  • RA2 series – low power consumption : Based on Arm Cortex-M23 core, the highest frequency is 48 MHz, with up to 512 KB of flash memory and 64 KB of SRAM. The supply voltage range is 1.6 V to 5.5 V. Peripherals include full-speed USB, CAN, 24-bit sigma-delta analog-to-digital converter (ADC), 16-bit digital-to-analog converter (DAC), capacitive touch sensing, and security features.
  • RA4 Series – High Performance and Power Consumption : Built on TrustZone-enabled Arm Cortex-M33F core or Arm Cortex-M4F core up to 100 MHz. Up to 1 MB of Flash and 128 KB of SRAM. The voltage range is 1.6 V to 5.5 V. Peripherals include capacitive touch sensing, segment LCD controller, full-speed USB, CAN, security features, and data converters and timers. The RA4W1 series devices are additionally equipped with Bluetooth ® Low Energy (BLE) 5.0.
  • RA6 Series – High Performance : Based on Arm Cortex-M33F core or Arm Cortex-M4F core with TrustZone support. The highest frequency is 200 MHz. Up to 2 MB of Flash and 640 KB of SRAM. The voltage range is 2.7 V to 3.6 V. Peripherals include data converters, timers, external memory bus, Ethernet, full and high-speed USB, CAN, security features, capacitive touch sensing, and a graphics LCD controller for TFT displays, as well as a 2D graphics engine. RA6T1 series devices come with enhanced peripherals for motor control, such as high-resolution PWM timers or advanced analog modules.
  • RA8 Series – Higher Performance, HMI, IoT and Edge Computing

This project is based on the Qiming 6M5 development board to complete the design. The RA6M5 chip configuration is as follows: Renesas RA series 32-bit MCU with Arm Cortex-M33 core; the main chip is R7FA6M5BH3CFC, the main chip is up to 200MHz, 2MB code flash memory, 8KB data flash memory, And 512KB of SRAM with parity/ECC. The Qiming 6M5 development board has rich interfaces and peripherals, such as basic LEDs, buttons, capacitive buttons, buzzers, etc., and also has RS232, RS485, CAN, Ethernet interfaces, onboard ESP8266 wireless WiFi, etc.
insert image description here
insert image description here

3.1 Sensor Module

  1. Temperature and humidity sensor
    DHT11 is a temperature and humidity sensor with calibrated digital signal output. Accuracy humidity ±5%RH, temperature ±2°C, range humidity 20-90%RH, temperature 0~50°C.
    For more information about DHT11, please refer to: https://baike.sogou.com/v73984313.htm?fromTitle=DHT11
    The following figure shows the pin description of DHT11, and the DATA pin is the signal input and output.
    insert image description here
  2. light intensity sensor
    1. GY-39 is a low-cost, air pressure, temperature and humidity, light intensity sensor module. Working voltage 3-5v, low power consumption, easy installation.
    2. Its working principle is that the MCU collects various sensor data, processes them in a unified manner, and directly outputs the calculated results. There are two ways to read data in this module, serial UART (TTL level) or IIC (2-wire). The baud rate of the serial port is 9600bps and 115200bps, which can be configured. There are two modes of continuous and query output, and the settings can be saved after power-off. It can adapt to different working environments and connect with single-chip microcomputer and computer.
    3. In addition, the module can set the working mode of a separate sensor chip. As a simple sensor module, the MCU does not participate in data processing.
    4. Reference website https://www.gysensor.cn/air-gy39/
    5. Some parameters and information
      insert image description here
      GY39-MCU-IIC protocol
      insert image description here
      Wiring diagram
      insert image description here
      3.2 Display module
      OLED, that is, Organic Light-Emitting Diode (Organic Light-Emitting Diode), also known as Organic Electroluminesence Display (OELD). OLED has the characteristics of self-illumination, no need for backlight, high contrast, thin thickness, wide viewing angle, and fast response speed.
      ​ LCDs all need a backlight, but OLEDs don't because it's self-illuminating. For the same display, the OLED effect is better. With the current technology, it is still difficult to enlarge the size of OLED, but the resolution can indeed be very high. The common OLED modules on the market have the following characteristics:
      ​ (1) The modules are available in single-color and double-color, the single-color is pure blue, and the double-color is yellow-blue.
      ​ (2) The size is small, the display size is 0.96 inches, and the size of the module is only 27mm*26mm.
      ​ (3) High resolution, the resolution of this module is 128x64
      ​ (4) Various interface methods, this module provides a total of 5 kinds of interfaces including: 6800, 8080 two parallel interface methods, 3-wire or 4-wire through SPI interface mode, and IIC interface mode (only need 2 wires to control OLED!).
      (5) No need for high voltage, just connect to 3.3V to work.
      The 0.96-inch OLED screen used in this experiment uses I2C communication, so here is a brief introduction to the principle of I2C communication.
      The IIC (Inter-Integrated Circuit) bus is a two-wire serial bus developed by PHILIPS for connecting microcontrollers and their peripherals. It is a serial bus composed of data line SDA and clock SCL, which can send and receive data. Two-way transmission is carried out between the CPU and the controlled IC, and between ICs, and the high-speed IIC bus can generally reach more than 400kbps.
      ​ The I2C bus has three types of signals in the process of transmitting data, they are: start signal , end signal and response signal .
      ​Start signal : When SCL is high level, SDA jumps from high level to low level, and starts to transmit data.
      ​End signal : When SCL is at high level, SDA transitions from low level to high level, ending data transmission.
      ​Response signal : After receiving the 8bit data, the IC that receives the data sends a specific low-level pulse to the IC that sends the data,
      indicating that the data has been received. After the CPU sends a signal to the controlled unit, it waits for the controlled unit to send a response signal. After receiving the response signal, the CPU makes a judgment on whether to continue to transmit the signal according to the actual situation. If no response signal is received, it is judged that the controlled unit is faulty. Among these signals, the start signal is required, and the end signal and the response signal are optional.
      3.3 Serial host computer
      insert image description here

4 project configuration

The MCU of Renesas RA series provides a graphical configuration tool, which is similar to STM32CubeMX, which greatly facilitates the configuration of developers. Meanwhile, Renesas' Flexible Software Package is designed to provide fast and efficient drivers and protocol stacks with a low memory footprint. FSP integrates the middleware protocol stack, RTOS-independent hardware abstraction layer (HAL) driver, and the most basic board support package (BSP) driver.
In this design, the sensor module and the display module are mainly configured. The following is the configuration process.

  1. The OLED display module
    chose to use the I2C interface on the EBF module interface, because the wiring sequence of the modified interface is consistent with the I2C interface of the OLED. The OLED can be directly plugged in, reducing wiring. This interface uses the I2C function of SCI6.
    The configuration under Pin is as follows: select SCI6, multiplex I2C mode.insert image description hereinsert image description here
    insert image description here
//==================================================================================================
//  实现功能: 0.96寸OLED 接口演示例程
//  说明:
//              GND   电源地
//              VCC   接5V或3.3v电源
//              SCL   接P505(SCL6)
//              SDA   接P506(SDA6)
//==================================================================================================------------------------------------------------------------------------
//  |   -   |   -   |   0   |   1   |   2   |   3   |   4   |   5   |   6   |   7   |   8   |   9
//==================================================================================================
//==================================================================================================
#include "oled.h"
#include "stdlib.h"
#include "oledfont.h"
#include "math.h"
#include "hal_data.h"


extern fsp_err_t err;
extern int  timeout_ms;
extern  i2c_master_event_t i2c_event ;
//OLED的显存
//存放格式如下.
//[0]0 1 2 3 ... 127
//[1]0 1 2 3 ... 127
//[2]0 1 2 3 ... 127
//[3]0 1 2 3 ... 127
//[4]0 1 2 3 ... 127
//[5]0 1 2 3 ... 127
//[6]0 1 2 3 ... 127
//[7]0 1 2 3 ... 127

//==================================================================================================
//  函数功能: IIC外设驱动函数部分
//  函数标记: Write_IIC_Command
//  函数说明: 无
//-------------------------------------------------------------------------------------------------
//  |   -   |   -   |   0   |   1   |   2   |   3   |   4   |   5   |   6   |   7   |   8   |   9
//==================================================================================================
void Write_IIC_Command(unsigned char IIC_Command)
{
    
    

    uint8_t ii[2]={
    
    0x00,0x00};
    ii[1] = IIC_Command;

    err = R_SCI_I2C_Write(&g_sci6_i2c_ctrl, ii, 0x02, true);
    assert(FSP_SUCCESS == err);
    /* Since there is nothing else to do, block until Callback triggers*/
    //while ((I2C_MASTER_EVENT_TX_COMPLETE != i2c_event) && timeout_ms)
    while ((I2C_MASTER_EVENT_TX_COMPLETE != i2c_event) && timeout_ms>0)
    {
    
    
        R_BSP_SoftwareDelay(100U, BSP_DELAY_UNITS_MICROSECONDS);
        timeout_ms--;
    }
    if (I2C_MASTER_EVENT_ABORTED == i2c_event)
    {
    
    
        __BKPT(0);
    }
    /* Read data back from the I2C slave */
    i2c_event = I2C_MASTER_EVENT_ABORTED;
    timeout_ms           = 100000;
}

//==================================================================================================
//  函数功能: IIC外设驱动函数部分
//  函数标记: Write_IIC_Data
//  函数说明: 无
//-------------------------------------------------------------------------------------------------
//  |   -   |   -   |   0   |   1   |   2   |   3   |   4   |   5   |   6   |   7   |   8   |   9
//==================================================================================================
void Write_IIC_Data(unsigned char IIC_Data)
{
    
    
    uint8_t ii[2]={
    
    0x40,0x00};
    ii[0] = 0x40;
    ii[1] = IIC_Data;
    err = R_SCI_I2C_Write(&g_sci6_i2c_ctrl, ii, 0x02, true);
           assert(FSP_SUCCESS == err);
           /* Since there is nothing else to do, block until Callback triggers*/
           //while ((I2C_MASTER_EVENT_TX_COMPLETE != i2c_event) && timeout_ms)
    while ((I2C_MASTER_EVENT_TX_COMPLETE != i2c_event) && timeout_ms>0)
    {
    
    
        R_BSP_SoftwareDelay(100U, BSP_DELAY_UNITS_MICROSECONDS);
        timeout_ms--;
    }
    if (I2C_MASTER_EVENT_ABORTED == i2c_event)
    {
    
    
        __BKPT(0);
    }
    /* Read data back from the I2C slave */
    i2c_event = I2C_MASTER_EVENT_ABORTED;
    timeout_ms           = 100000;

}
//==================================================================================================
//  函数功能: IIC外设驱动函数部分
//  函数标记: Write_IIC_Data
//  函数说明: 无
//-------------------------------------------------------------------------------------------------
//  |   -   |   -   |   0   |   1   |   2   |   3   |   4   |   5   |   6   |   7   |   8   |   9
//==================================================================================================
void OLED_WR_Byte(unsigned dat,unsigned cmd)
{
    
    
    if(cmd)
    {
    
    
        Write_IIC_Data(dat);
    }
    else
    {
    
    
        Write_IIC_Command(dat);
    }


}
/********************************************
// fill_Picture
********************************************/
void fill_picture(unsigned char fill_Data)
{
    
    
    unsigned char m,n;
    for(m=0;m<8;m++)
    {
    
    
        OLED_WR_Byte(0xb0+m,0);     //page0-page1
        OLED_WR_Byte(0x00,0);       //low column start address
        OLED_WR_Byte(0x10,0);       //high column start address
        for(n=0;n<128;n++)
            {
    
    
                OLED_WR_Byte(fill_Data,1);
            }
    }
}


/***********************Delay****************************************/
void Delay_50ms(unsigned int Del_50ms)
{
    
    
    unsigned int m;
    for(;Del_50ms>0;Del_50ms--)
        for(m=6245;m>0;m--);
}

void Delay_1ms(unsigned int Del_1ms)
{
    
    
    unsigned char j;
    while(Del_1ms--)
    {
    
    
        for(j=0;j<123;j++);
    }
}

//坐标设置

void OLED_Set_Pos(unsigned char x, unsigned char y)
{
    
       OLED_WR_Byte(0xb0+y,OLED_CMD);
    OLED_WR_Byte(((x&0xf0)>>4)|0x10,OLED_CMD);
    OLED_WR_Byte((x&0x0f),OLED_CMD);
}
//开启OLED显示
void OLED_Display_On(void)
{
    
    
    OLED_WR_Byte(0X8D,OLED_CMD);  //SET DCDC命令
    OLED_WR_Byte(0X14,OLED_CMD);  //DCDC ON
    OLED_WR_Byte(0XAF,OLED_CMD);  //DISPLAY ON
}
//关闭OLED显示
void OLED_Display_Off(void)
{
    
    
    OLED_WR_Byte(0X8D,OLED_CMD);  //SET DCDC命令
    OLED_WR_Byte(0X10,OLED_CMD);  //DCDC OFF
    OLED_WR_Byte(0XAE,OLED_CMD);  //DISPLAY OFF
}
//清屏函数,清完屏,整个屏幕是黑色的!和没点亮一样!!!
void OLED_Clear(void)
{
    
    
    u8 i,n;
    for(i=0;i<8;i++)
    {
    
    
        OLED_WR_Byte(0xb0+i,OLED_CMD);    //设置页地址(0~7)
        OLED_WR_Byte(0x00,OLED_CMD);      //设置显示位置—列低地址
        OLED_WR_Byte(0x10,OLED_CMD);      //设置显示位置—列高地址
        for(n=0;n<128;n++)OLED_WR_Byte(0,OLED_DATA);
    } //更新显示
}
void OLED_On(void)
{
    
    
    u8 i,n;
    for(i=0;i<8;i++)
    {
    
    
        OLED_WR_Byte (0xb0+i,OLED_CMD);    //设置页地址(0~7)
        OLED_WR_Byte (0x00,OLED_CMD);      //设置显示位置—列低地址
        OLED_WR_Byte (0x10,OLED_CMD);      //设置显示位置—列高地址
        for(n=0;n<128;n++)OLED_WR_Byte(1,OLED_DATA);
    } //更新显示
}
//在指定位置显示一个字符,包括部分字符
//x:0~127
//y:0~63
//mode:0,反白显示;1,正常显示
//size:选择字体 16/12
void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 Char_Size)
{
    
    
    unsigned char c=0,i=0;
        c=chr-' ';//得到偏移后的值
        if(x>Max_Column-1){
    
    x=0;y=y+2;}
        if(Char_Size ==16)
            {
    
    
                OLED_Set_Pos(x,y);
                for(i=0;i<8;i++)
                    OLED_WR_Byte(F8X16[c*16+i],OLED_DATA);
                    OLED_Set_Pos(x,y+1);
                    for(i=0;i<8;i++)
                        OLED_WR_Byte(F8X16[c*16+i+8],OLED_DATA);
            }
            else {
    
    
                OLED_Set_Pos(x,y);
                for(i=0;i<6;i++)
                OLED_WR_Byte(F6x8[c][i],OLED_DATA);

            }
}
//m^n函数
u32 oled_pow(u8 m,u8 n)
{
    
    
    u32 result=1;
    while(n--)result*=m;
    return result;
}
//显示2个数字
//x,y :起点坐标
//len :数字的位数
//size:字体大小
//mode:模式   0,填充模式;1,叠加模式
//num:数值(0~4294967295);
void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size2)
{
    
    
    u8 t,temp;
    u8 enshow=0;
    for(t=0;t<len;t++)
    {
    
    
        temp=(num/oled_pow(10,len-t-1))%10;
        if(enshow==0&&t<(len-1))
        {
    
    
            if(temp==0)
            {
    
    
                OLED_ShowChar(x+(size2/2)*t,y,' ',size2);
                continue;
            }else enshow=1;

        }
        OLED_ShowChar(x+(size2/2)*t,y,temp+'0',size2);
    }
}
//显示一个字符号串
void OLED_ShowString(u8 x,u8 y,u8 *chr,u8 Char_Size)
{
    
    
    unsigned char j=0;
    while (chr[j]!='\0')
    {
    
           OLED_ShowChar(x,y,chr[j],Char_Size);
            x+=8;
        if(x>120){
    
    x=0;y+=2;}
            j++;
    }
}
//显示汉字
void OLED_ShowCHinese(u8 x,u8 y,u8 no)
{
    
    
    u8 t,adder=0;
    OLED_Set_Pos(x,y);
    for(t=0;t<16;t++)
        {
    
    
                OLED_WR_Byte(Hzk[2*no][t],OLED_DATA);
                adder+=1;
     }
        OLED_Set_Pos(x,y+1);
    for(t=0;t<16;t++)
            {
    
    
                OLED_WR_Byte(Hzk[2*no+1][t],OLED_DATA);
                adder+=1;
      }
}
/***********功能描述:显示显示BMP图片128×64起始点坐标(x,y),x的范围0~127,y为页的范围0~7*****************/
void OLED_DrawBMP(unsigned char x0, unsigned char y0,unsigned char x1, unsigned char y1,unsigned char BMP[])
{
    
    
 unsigned int j=0;
 unsigned char x,y;

  if(y1%8==0) y=y1/8;
  else y=y1/8+1;
    for(y=y0;y<y1;y++)
    {
    
    
        OLED_Set_Pos(x0,y);
    for(x=x0;x<x1;x++)
        {
    
    
            OLED_WR_Byte(BMP[j++],OLED_DATA);
        }
    }
}

//初始化SSD1306
void OLED_Init(void)
{
    
    



    /* Wait for minimum time required between transfers. */
    R_BSP_SoftwareDelay(800, BSP_DELAY_UNITS_MICROSECONDS);

    OLED_WR_Byte(0xAE,OLED_CMD);//--display off
    OLED_WR_Byte(0x00,OLED_CMD);//---set low column address
    OLED_WR_Byte(0x10,OLED_CMD);//---set high column address
    OLED_WR_Byte(0x40,OLED_CMD);//--set start line address
    OLED_WR_Byte(0xB0,OLED_CMD);//--set page address
    OLED_WR_Byte(0x81,OLED_CMD); // contract control
    OLED_WR_Byte(0xFF,OLED_CMD);//--128
    OLED_WR_Byte(0xA1,OLED_CMD);//set segment remap
    OLED_WR_Byte(0xA6,OLED_CMD);//--normal / reverse
    OLED_WR_Byte(0xA8,OLED_CMD);//--set multiplex ratio(1 to 64)
    OLED_WR_Byte(0x3F,OLED_CMD);//--1/32 duty
    OLED_WR_Byte(0xC8,OLED_CMD);//Com scan direction
    OLED_WR_Byte(0xD3,OLED_CMD);//-set display offset
    OLED_WR_Byte(0x00,OLED_CMD);//

    OLED_WR_Byte(0xD5,OLED_CMD);//set osc division
    OLED_WR_Byte(0x80,OLED_CMD);//

    OLED_WR_Byte(0xD8,OLED_CMD);//set area color mode off
    OLED_WR_Byte(0x05,OLED_CMD);//

    OLED_WR_Byte(0xD9,OLED_CMD);//Set Pre-Charge Period
    OLED_WR_Byte(0xF1,OLED_CMD);//

    OLED_WR_Byte(0xDA,OLED_CMD);//set com pin configuartion
    OLED_WR_Byte(0x12,OLED_CMD);//

    OLED_WR_Byte(0xDB,OLED_CMD);//set Vcomh
    OLED_WR_Byte(0x30,OLED_CMD);//

    OLED_WR_Byte(0x8D,OLED_CMD);//set charge pump enable
    OLED_WR_Byte(0x14,OLED_CMD);//

    OLED_WR_Byte(0xAF,OLED_CMD);//--turn on oled panel
}
/*
 * oled.h
 *
 *  Created on: 2023年1月31日
 *      Author: a8456
 */

#ifndef OLED_H_
#define OLED_H_
#include "stdlib.h"
#include "stdint.h"
#define OLED_MODE 0

#define XLevelL     0x00
#define XLevelH     0x10
#define Max_Column  128
#define Max_Row     64
#define Brightness  0xFF
#define X_WIDTH     128
#define Y_WIDTH     64


#define OLED_CMD  0 //写命令
#define OLED_DATA 1 //写数据

typedef __uint8_t u8 ;
typedef __uint32_t u32 ;


//OLED控制用函数
void OLED_WR_Byte(unsigned dat,unsigned cmd);
void OLED_Display_On(void);
void OLED_Display_Off(void);
void OLED_Init(void);
void OLED_Clear(void);
void OLED_DrawPoint(u8 x,u8 y,u8 t);
void OLED_Fill(u8 x1,u8 y1,u8 x2,u8 y2,u8 dot);
void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 Char_Size);
void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size);
void OLED_ShowString(u8 x,u8 y, u8 *p,u8 Char_Size);
void OLED_Set_Pos(unsigned char x, unsigned char y);
void OLED_ShowCHinese(u8 x,u8 y,u8 no);
void OLED_DrawBMP(unsigned char x0, unsigned char y0,unsigned char x1, unsigned char y1,unsigned char BMP[]);
void Delay_50ms(unsigned int Del_50ms);
void Delay_1ms(unsigned int Del_1ms);
void fill_picture(unsigned char fill_Data);
void Picture();
void IIC_Start();
void IIC_Stop();
void Write_IIC_Command(unsigned char IIC_Command);
void Write_IIC_Data(unsigned char IIC_Data);
void Write_IIC_Byte(unsigned char IIC_Byte);

void IIC_Wait_Ack();
#endif /* OLED_H_ */
  1. Sensor module
    Temperature and humidity sensor DHT11, any GPIO port can be configured, no other configuration is required, just pay attention to the timing problem, the focus is on the configuration of the GY39 sensor.
    The configuration under Pin is as follows: select SCI2, multiplex I2C mode.
    insert image description here
    insert image description here
    insert image description here
#ifndef __BSP_DHT11_H
#define __BSP_DHT11_H
#include "hal_data.h"


#define Bit_RESET   0
#define Bit_SET     1

#define DHT11_LOW   0
#define DHT11_HIGH  1

#define DHT11_PORT  BSP_IO_PORT_00_PIN_01
#define DHT_HIGH    R_BSP_PinWrite(DHT11_PORT, BSP_IO_LEVEL_HIGH);
#define DHT_LOW     R_BSP_PinWrite(DHT11_PORT, BSP_IO_LEVEL_LOW);
#define Read_Data   R_BSP_PinRead(DHT11_PORT)

#define DHT11_DATA_OUT(a)   if (a)  \ DHT_HIGH\ else \  DHT_LOW

typedef struct
{
    
    
    uint8_t  humi_int;      //湿度的整数部分
    uint8_t  humi_deci;     //湿度的小数部分
    uint8_t  temp_int;      //温度的整数部分
    uint8_t  temp_deci;     //温度的小数部分
    uint8_t  check_sum;     //校验和
}DHT11_Data_TypeDef;

void DHT11_Init         (void);
void DHT11_Start        (void);
void DHT11_DELAY_US     (uint32_t delay);
void DHT11_DELAY_MS     (uint32_t delay);
uint8_t Read_DHT11(DHT11_Data_TypeDef *DHT11_Data);

#endif


#include "bsp_dht11.h"             // Device header
/* DHT11初始化函数 */
void DHT11_Init(void)
{
    
    
    /* 初始化配置引脚(这里重复初始化了,可以注释掉) */
    R_IOPORT_Open (&g_ioport_ctrl, g_ioport.p_cfg);
}
void DHT11_DELAY_US(uint32_t delay)
{
    
    
    R_BSP_SoftwareDelay(delay, BSP_DELAY_UNITS_MICROSECONDS);
}
void DHT11_DELAY_MS(uint32_t delay)
{
    
    
    R_BSP_SoftwareDelay(delay, BSP_DELAY_UNITS_MILLISECONDS);
}
//主机发送开始信号
void DHT11_Start(void)
{
    
    
    DHT_HIGH; //先拉高
    DHT11_DELAY_US(30);

    DHT_LOW; //拉低电平至少18us
    DHT11_DELAY_MS(20);

    DHT_HIGH; //拉高电平20~40us
    DHT11_DELAY_US(30);
}
/*
 * 从DHT11读取一个字节,MSB先行
 */
static uint8_t Read_Byte(void)
{
    
    
    uint8_t i, temp=0;
    for(i=0;i<8;i++)
    {
    
    
        /*每bit以50us低电平标置开始,轮询直到从机发出 的50us 低电平 结束*/
        while(Read_Data == Bit_RESET);

        /*DHT11 以26~28us的高电平表示“0”,以70us高电平表示“1”,
         *通过检测 x us后的电平即可区别这两个状 ,x 即下面的延时
         */
        DHT11_DELAY_US(40); //延时x us 这个延时需要大于数据0持续的时间即可
        if(Read_Data == Bit_SET)/* x us后仍为高电平表示数据“1” */
        {
    
    
            /* 等待数据1的高电平结束 */
            while( Read_Data ==Bit_SET);

            temp|=(uint8_t)(0x01<<(7-i));  //把第7-i位置1,MSB先行
        }
        else     // x us后为低电平表示数据“0”
        {
    
    
            temp&=(uint8_t)~(0x01<<(7-i)); //把第7-i位置0,MSB先行
        }
    }
    return temp;
}
/*
 * 一次完整的数据传输为40bit,高位先出
 * 8bit 湿度整数 + 8bit 湿度小数 + 8bit 温度整数 + 8bit 温度小数 + 8bit 校验和
 */
uint8_t Read_DHT11(DHT11_Data_TypeDef *DHT11_Data)
{
    
    
    uint16_t count;
    DHT11_Start();
    DHT_HIGH; //拉高电平

    /*判断从机是否有低电平响应信号 如不响应则跳出,响应则向下运行*/
    if( Read_Data == Bit_RESET)
    {
    
    
    count=0;
        /*轮询直到从机发出 的80us 低电平 响应信号结束*/
        while( Read_Data ==Bit_RESET)
        {
    
    
            count++;
            if(count>1000)
                    return 0;
            DHT11_DELAY_US(10);
        }

    count=0;
        /*轮询直到从机发出的 80us 高电平 标置信号结束*/
        while( Read_Data==Bit_SET)
        {
    
    
                count++;
                if(count>1000)
                    return 0;
                DHT11_DELAY_US(10);
        }
        /*开始接收数据*/
        DHT11_Data->humi_int= Read_Byte();

        DHT11_Data->humi_deci= Read_Byte();

        DHT11_Data->temp_int= Read_Byte();

        DHT11_Data->temp_deci= Read_Byte();

        DHT11_Data->check_sum= Read_Byte();

        DHT_LOW;
        DHT11_DELAY_US(55);
        DHT_HIGH;

        /*检查读取的数据是否正确*/
        if(DHT11_Data->check_sum == DHT11_Data->humi_int + DHT11_Data->humi_deci + DHT11_Data->temp_int+ DHT11_Data->temp_deci)
            return 1;
        else
            return 0;
    }
    else
    {
    
    
        return 0;
    }
}

main function code

#include "hal_data.h"
#include "oled.h"
#include "bmp.h"
#include "bsp_debug_uart.h"
#include "bsp_led.h"
#include "bsp_dht11.h"
#include "bsp_gpt_timing.h"

#define SUCCESS 1
void Hardware_init(void);
FSP_CPP_HEADER
void R_BSP_WarmStart(bsp_warm_start_event_t event);
FSP_CPP_FOOTER
/* Callback function */
i2c_master_event_t i2c_event = I2C_MASTER_EVENT_ABORTED;
void sci6_i2c_master_callback(i2c_master_callback_args_t *p_args)
{
    
    
    i2c_event = I2C_MASTER_EVENT_ABORTED;
    if (NULL != p_args)
    {
    
    
        /* capture callback event for validating the i2c transfer event*/
        i2c_event = p_args->event;
    }
}

void sci2_i2c_master_callback(i2c_master_callback_args_t *p_args)
{
    
    
    i2c_event = I2C_MASTER_EVENT_ABORTED;
    if (NULL != p_args)
    {
    
    
        /* capture callback event for validating the i2c transfer event*/
        i2c_event = p_args->event;
    }

}


fsp_err_t err = FSP_SUCCESS;
uint32_t  timeout_ms = 1000;

DHT11_Data_TypeDef DHT11_Data;
uint8_t Temperature,Humidity;
extern uint8_t temp_humi_flag;
extern uint32_t time1s_flag;
typedef struct
{
    
    
    uint32_t P;
    uint16_t Temp;
    uint16_t Hum;
    uint16_t Alt;
} bme;
bme Bme;
uint32_t Lux;
float LightLux;

//==================================================================================================
//  函数说明: 硬件初始化
//  函数备注: Hardware_init
//--------------------------------------------------------------------------------------------------
//  |   -   |   -   |   0   |   1   |   2   |   3   |   4   |   5   |   6   |   7   |   8   |   9
//==================================================================================================
void Hardware_init(void)
{
    
    
        Debug_UART4_Init(); // SCI4 UART 调试串口初始化
        GPT0_Timing_Init();
        printf("Debug-UART4-Init OK \r\n");
        LED_Init();
        printf("LED_Init    OK \r\n");
        printf("IIC-Config  Start \r\n");
        DHT11_Init();
        printf("DHT11_Init OK \r\n");
        /* Initialize the I2C module */
        err = R_SCI_I2C_Open(&g_sci6_i2c_ctrl, &g_sci6_i2c_cfg);
        /* Handle any errors. This function should be defined by the user. */
        assert(FSP_SUCCESS == err);
        printf("IIC-Config OK \r\n");
        OLED_Init();            //初始化OLED
        OLED_Clear();
        printf("oled-Init OK \r\n");

}


void read_bme(void)
{
    
    
    uint16_t data_16[2] ={
    
     0 };
    uint8_t data[10] = {
    
     0x00 }; //接收读取后的数据
    uint8_t write_buffer = 0x04; //写数据
    err = R_SCI_I2C_Open (&g_sci2_i2c_ctrl, &g_sci2_i2c_cfg);
    err = R_SCI_I2C_Write (&g_sci2_i2c_ctrl, &write_buffer, 1, true);
    err = R_SCI_I2C_Abort (&g_sci2_i2c_ctrl);
    R_BSP_SoftwareDelay (3, BSP_DELAY_UNITS_MILLISECONDS);
    err = R_SCI_I2C_Read (&g_sci2_i2c_ctrl, data, 10, false);
    R_BSP_SoftwareDelay (3, BSP_DELAY_UNITS_MILLISECONDS);
    err = R_SCI_I2C_Abort (&g_sci2_i2c_ctrl);
    err = R_SCI_I2C_Close (&g_sci2_i2c_ctrl);

    Bme.Temp = (data[0] << 8) | data[1];
    data_16[0] = (data[2] << 8) | data[3];
    data_16[1] = (data[4] << 8) | data[5];

    Bme.P = (((uint32_t) data_16[0]) << 16) | data_16[1];
    Bme.Hum = (data[6] << 8) | data[7];
    Bme.Alt = (data[8] << 8) | data[9];
}
void read_lux(void)
{
    
    
    uint16_t data_16[2] ={
    
     0 };
    uint8_t data[4] = {
    
     0 };
    uint8_t write_buffer = 0x00; //写数据
    err = R_SCI_I2C_Open (&g_sci2_i2c_ctrl, &g_sci2_i2c_cfg);
    err = R_SCI_I2C_Write (&g_sci2_i2c_ctrl, &write_buffer, 1, true);
    err = R_SCI_I2C_Abort (&g_sci2_i2c_ctrl);
    R_BSP_SoftwareDelay (3, BSP_DELAY_UNITS_MILLISECONDS);
    err = R_SCI_I2C_Read (&g_sci2_i2c_ctrl, data, 4, false);
    R_BSP_SoftwareDelay (3, BSP_DELAY_UNITS_MILLISECONDS);
    err = R_SCI_I2C_Abort (&g_sci2_i2c_ctrl);
    err = R_SCI_I2C_Close (&g_sci2_i2c_ctrl);
    data_16[0] = (data[0] << 8) | data[1];
    data_16[1] = (data[2] << 8) | data[3];
    Lux = (((uint32_t) data_16[0]) << 16) | data_16[1];

}

//==================================================================================================
//  函数说明: 主函数入口
//  函数备注: hal_entry
//--------------------------------------------------------------------------------------------------
//  |   -   |   -   |   0   |   1   |   2   |   3   |   4   |   5   |   6   |   7   |   8   |   9
//==================================================================================================

/*******************************************************************************************************************//**
 * main() is generated by the RA Configuration editor and is used to generate threads if an RTOS is used.  This function
 * is called by main() when no RTOS is used.
 **********************************************************************************************************************/
void hal_entry(void)
{
    
    
    /* TODO: add your own code here */

          Hardware_init();
          printf("RA6M5-Board-Init OK \r\n");

           OLED_ShowCHinese(0,0,0);//瑞
           OLED_ShowCHinese(16,0,1);//萨
           OLED_ShowCHinese(32,0,5);//电
           OLED_ShowCHinese(48,0,6);//子
           OLED_ShowString(60,0,"Renesas",16);
           OLED_ShowNum(0,2,2023,4,16);//显示ASCII字符的码值
           OLED_ShowCHinese(32,2,2);//中文字->年
           OLED_ShowNum(48,2,8,2,16);//显示ASCII字符的码值
           OLED_ShowCHinese(64,2,3);//中文字->月
           OLED_ShowNum(80,2,5,2,16);//显示ASCII字符的码值
           OLED_ShowCHinese(96,2,4);//中文字->日

           OLED_ShowCHinese(0,4,7);   //中文字->温
           OLED_ShowCHinese(16,4,9);  //中文字->度

           OLED_ShowCHinese(64,4,8);  //中文字->湿
           OLED_ShowCHinese(80,4,9);  //中文字->度

           OLED_ShowString(0,6,"Light:",16);
           OLED_ShowString(96,6,"Lux",16);
          R_BSP_PinAccessEnable();
          R_BSP_PinWrite(BSP_IO_PORT_00_PIN_01, BSP_IO_LEVEL_HIGH); //DHT11端口配置


          while(1)
          {
    
    

              if (time1s_flag == 1)
              {
    
    
                  //printf("time1s_flag ......\r\n");
                  printf("T%dPH%dI", Temperature, Humidity);
                  printf("\r\n");

              }

             OLED_ShowNum(32,4,Temperature,2,16);
             OLED_ShowNum(96,4,Humidity,2,16);
             read_bme();
             read_lux (); //光照传感器
             LightLux = Lux / 100;
             //printf("LightLux: %.2f lux \r\n ",(float)LightLux );
             OLED_ShowNum(48,6,LightLux,5,16);
          }



#if BSP_TZ_SECURE_BUILD
    /* Enter non-secure code */
    R_BSP_NonSecureEnter();
#endif
}

/*******************************************************************************************************************//**
 * This function is called at various points during the startup process.  This implementation uses the event that is
 * called right before main() to set up the pins.
 *
 * @param[in]  event    Where at in the start up process the code is currently at
 **********************************************************************************************************************/
void R_BSP_WarmStart(bsp_warm_start_event_t event)
{
    
    
    if (BSP_WARM_START_RESET == event)
    {
    
    
#if BSP_FEATURE_FLASH_LP_VERSION != 0

        /* Enable reading from data flash. */
        R_FACI_LP->DFLCTL = 1U;

        /* Would normally have to wait tDSTOP(6us) for data flash recovery. Placing the enable here, before clock and
         * C runtime initialization, should negate the need for a delay since the initialization will typically take more than 6us. */
#endif
    }

    if (BSP_WARM_START_POST_C == event)
    {
    
    
        /* C runtime environment and system clocks are setup. */

        /* Configure pins. */
        R_IOPORT_Open (&g_ioport_ctrl, g_ioport.p_cfg);
    }
}

#if BSP_TZ_SECURE_BUILD

BSP_CMSE_NONSECURE_ENTRY void template_nonsecure_callable ();

/* Trustzone Secure Projects require at least one nonsecure callable function in order to build (Remove this if it is not required to build). */
BSP_CMSE_NONSECURE_ENTRY void template_nonsecure_callable ()
{
    
    

}
#endif

Test effect

insert image description here
insert image description here
I saw another host computer on the Internet, it felt good, and I used it
insert image description here

Guess you like

Origin blog.csdn.net/weixin_43599390/article/details/132117098