基于瑞萨RA6M5的环境监测系统设计

news2024/11/13 18:01:46

基于瑞萨RA6M5的环境监测系统设计

1. 设计简介

本项目初步设计思路是打算以瑞萨单片机作为控制和数据处理的单元,使用温湿度,光照传感器去监测周围的环境参数,在屏幕上完成传感器数据和相关信息的显示。同时,使用WIFI无线模组与单片机之间进行数据交互,接入物联网云平台。尝试利用上位机实现对于温度、湿度、光照强度等相关环境参数监测。但是由于时间原因以及个人能力有限制,只完成了部分设计。

本项目是基于启明6M5开发板完成了环境监测系统设计,传感器DHT11获取温度湿度的数据;传感器GY39获取光照强度数据;0.96寸OLED屏幕提供显示功能,能够显示传感器数据以及相关信息。编写上位机软件,实现温湿度传感器数据的上报。

2. 设计框架

3. 项目说明

RA 产品家族单片机 (MCU) 于 2019 年 10 月推出,丰富了瑞萨的 32 位 MCU 系列产品。 除了 RA 系列之外的 32 位 MCU 产品还有 RX 系列(CPU使用瑞萨自家RX内核)和 Renesas Synergy™ 平台 MCU。

Renesas Advanced (RA) 32 位 MCU 是采用 Arm® Cortex®-M33、-M23 和 -M4 处理器内核, 并经过 PSA Certified ® 1 级认证的、行业领先的 32 位 MCU。

瑞萨 RA 系列产品家族包括:

  • RA2 系列,适用于低功耗应用;

  • RA4 系列,适用于需要低功耗、高性能和高安全性的设备;

  • RA6 系列,具有卓越的连接性能和安全性能;

  • RA8 系列,可以为采用人机界面、连接、安全和模拟功能的应用提供出色性能。

    • RA2 系列 – 低功耗:基于 Arm Cortex-M23 内核,最高频率 48 MHz, 拥有高达 512 KB 的闪存和 64 KB 的 SRAM。电源电压范围为 1.6 V 到 5.5 V。 外设包括全速 USB、CAN、24 位 ∑-△ 模数转换器 (ADC)、16 位数模转换器 (DAC)、电容式触摸感应以及安全功能。
    • RA4 系列 – 高性能和出色的功耗:基于支持 TrustZone 的 Arm Cortex-M33F 内核或 Arm Cortex-M4F 内核构建,最高频率 100 MHz。高达 1 MB 的闪存和 128 KB 的 SRAM。电压范围为 1.6 V 到 5.5 V。 外设包括电容式触摸感应、段码式 LCD 控制器、全速 USB、CAN、安全功能以及数据转换器和定时 器。RA4W1 系列器件还额外配备了 Bluetooth ® 低功耗 (BLE) 5.0。
    • RA6 系列 – 高性能:基于支持 TrustZone 的 Arm Cortex-M33F 内核或 Arm Cortex-M4F 内核。最高频 率 200 MHz。高达 2 MB 的闪存和 640 KB 的 SRAM。电压范围为 2.7 V 到 3.6 V。外设包括数据转换 器、定时器、外部存储总线、以太网、全速和高速 USB、CAN、安全功能、电容式触摸感应和用于 TFT 显示的图形 LCD 控制器,以及一个 2D 图形引擎。RA6T1 系列器件带有用于电机控制的增强型外 设,如高分辨率 PWM 定时器或高级模拟模块。
    • RA8 系列 – 更高性能、人机界面、物联网和边缘计算
      在这里插入图片描述
      在这里插入图片描述

3.1 传感器模块

  1. 温湿度传感器

    DHT11是一款有已校准数字信号输出的温湿度传感器。 精度湿度±5%RH, 温度±2℃,量程湿度20-90%RH, 温度0~50℃。

    更多DHT11信息请参考:https://baike.sogou.com/v73984313.htm?fromTitle=DHT11

    下图为DHT11的引脚说明图,DATA引脚为信号输入输出。

在这里插入图片描述
2. 光照强度传感器

  1. GY-39 是一款低成本,气压,温湿度,光强度传感器模块。工作电压 3-5v,功耗小,安装方便。
  2. 其工作原理是,MCU 收集各种传感器数据,统一处理,直接输出计算后的结果。此模块,有两种方式读取数据,即串口 UART(TTL 电平)或者 IIC(2 线)。串口的波特率有 9600bps 与 115200bps,可配置,有连续,询问输出两种方式,可掉电保存设置。可适应不同的工作环境,与单片机及电脑连接。
  3. 模块另外可以设置单独传感器芯片工作模式,作为简单传感器模块,MCU 不参与数据处理工作。
  4. 参考资料网站 *https://www.gysensor.cn/air-gy39/
  5. 部分参数及资料
    在这里插入图片描述
    GY39-MCU-IIC协议
    在这里插入图片描述
    接线示意图
    在这里插入图片描述
    3.2 显示模块
    在这里插入图片描述

​ OLED,即有机发光二极管(Organic Light-Emitting Diode),又称为有机电激光显示(Organic Electroluminesence Display, OELD)。OLED 由于同时具备自发光不需背光源对比度高厚度薄视角广反应速度快可用于挠曲性面板使用温度范围广构造及制程较简单等优异之特性,被认为是下一代的平面显示器新兴应用技术。

LCD需要背光,而 OLED 不需要,因为它是自发光的。这样同样的显示,OLED 效果要来得好一些。以目前的技术,OLED 的尺寸还难以大型化,但是分辨率确可以做到很高。市场上常见OLED模块有以下特点

​ (1)模块有单色和双色两种可选,单色为纯蓝色,而双色则为黄蓝双色
​ (2)尺寸小,显示尺寸为 0.96 寸,而模块的尺寸仅为 27mm*26mm 大小。
​ (3)高分辨率,该模块的分辨率为 128*64
​ (4)多种接口方式,该模块提供了总共 5 种接口包括:6800、8080 两种并行接口方式、3线或 4 线的穿行 SPI 接口方式,、IIC 接口方式(只需要 2 根线就可以控制 OLED 了!)。
​ (5)不需要高压,直接接 3.3V 就可以工作了。

特别注意,市面上有部分的OLED屏幕不可以直接接5.0v电压,否则可能烧坏!

总结:目前市面上常用0.96寸OLED屏幕通讯方式主要有SPII2C两种!SPI为4线制较多,而I2C为2线制。2种通讯协议较为浅显的区别:总所周知,SPI的通讯速度明显快于I2C的通讯速度,所以通常使用SPI通讯协议的OLED屏幕可以实现更高的帧数显示,画面更为流畅丝滑

本次实验所采用的0.96寸OLED屏幕为I2C通讯方式,故在此稍微给读者介绍一下I2C通讯原理。

IIC(Inter-Integrated Circuit)总线是一种由 PHILIPS 公司开发的两线式串行总线,用于连接微控制器及其外围设备。它是由数据线 SDA时钟 SCL 构成的串行总线,可发送和接收数据。在 CPU 与被控 IC 之间、IC 与 IC 之间进行双向传送,高速 IIC 总线一般可达 400kbps 以上
​ I2C 总线在传送数据过程中共有三种类型信号, 它们分别是:开始信号结束信号应答信号
开始信号:SCL 为高电平时,SDA 由高电平向低电平跳变,开始传送数据。
结束信号:SCL 为高电平时,SDA 由低电平向高电平跳变,结束传送数据。
应答信号:接收数据的 IC 在接收到 8bit 数据后,向发送数据的 IC 发出特定的低电平脉冲,
​ 表示已收到数据。CPU 向受控单元发出一个信号后,等待受控单元发出一个应答信号,CPU 接收到应答信号后,根据实际情况作出是否继续传递信号的判断。若未收到应答信号,由判断为受控单元出现故障

​ 这些信号中,起始信号是必需的,结束信号和应答信号,都可以不要。
3.3 串口上位机
在这里插入图片描述

4 项目配置

  1. OLED显示模块

​ 选择了使用EBF模块接口上的I2C接口,因为改接口的布线顺序和OLED的I2C接口一致。可以直接将OLED插上去,减少了接线。该接口使用的是SCI6的I2C功能。

Pin下配置如下:选择SCI6,复用I2C模式。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

//==================================================================================================
//  实现功能: 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. 传感器模块

    温湿度传感器DHT11,任意配置一个GPIO端口就可以了,不需要其他的配置,只要注意时序问题即可,重点在GY39传感器的配置。

Pin下配置如下:选择SCI2,复用I2C模式。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

#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;
    }
}


主函数代码


//--------------------------------------------------------------------------------------------------
// 函数头文件    |   0   |   1   |   2   |   3   |   4   |   5   |   6   |   7   |   8   |   9
//--------------------------------------------------------------------------------------------------
#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

测试效果

在这里插入图片描述
在这里插入图片描述
参考代码:https://gitee.com/delehubcode/OpenStudyNote/tree/master/Embedded-Note/Embedded_Board/Code-Renesas/RA6M5-Embedfire

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/840334.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

用于大型图像模型的 CNN 内核的最新内容

一、说明 由于OpenAI的ChatGPT的巨大成功引发了大语言模型的繁荣&#xff0c;许多人预见到大图像模型的下一个突破。在这个领域&#xff0c;可以提示视觉模型分析甚至生成图像和视频&#xff0c;其方式类似于我们目前提示 ChatGPT 的方式。 用于大型图像模型的最新深度学习方法…

Pytohn将matplotlib嵌入到tkinter中

文章目录 matplotlib窗口组成tkinter布局嵌入图像 matplotlib窗口组成 tkinter是Python标准库中自带的GUI工具&#xff0c;使用十分方便&#xff0c;如能将matplotlib嵌入到tkinter中&#xff0c;就可以做出相对专业的数据展示系统&#xff0c;很有竞争力。 在具体实现之前&a…

FTP使用教程

FTP使用教程 目录 一&#xff0e;FTP简介二&#xff0e;FTP搭建三&#xff0e;FTP使用 一&#xff0e;FTP简介 FTP中文为文件传输协议&#xff0c;简称为文传协议。它也是一个应用程序&#xff0c;不同的操作系统有不同的FTP应用程序&#xff0c;这些应用程序都遵守同一种协议以…

六寸相纸打印拼图 - opencv

准备自己打印一些照片&#xff0c;三寸相纸性价比低&#xff0c;只好买六寸来拼四张然后裁剪&#xff0c;不过并没有搜到提供了这个功能的工具&#xff0c;想想代码应该很简单&#xff0c;所以就造轮子了。可能其实有但是我没搜到。 轮子在这里&#xff1a; https://github.co…

ArraySetter

简介​ 用来展示属性类型为数组的 setter 展示​ 配置示例​ "setter": {"componentName": "ArraySetter","props": {"itemSetter": {"componentName": "ObjectSetter","props": {"c…

React 论文《ReAct: Synergizing Reasoning and Acting in Language Models》阅读笔记

文章目录 1. 简介论文摘要翻译动机和主要贡献 2. REACT : SYNERGIZING *RE*ASONING *ACT*ING3. KNOWLEDGE-INTENSIVE REASONING TASKS3.1 设置3.2 方法3.3 结果和观察 4. 决策任务5. 参考资料 1. 简介 论文摘要翻译 虽然大型语言模型&#xff08;LLM&#xff09;在自然语言理…

医疗实施-集成平台下门诊就诊流程详解

目录 集成平台下门诊就诊流程详解1.患者建档2. 门诊挂号3. 医生就诊4.处方开立5.费用收取、6、科室执行医嘱集成平台下门诊就诊流程详解 这篇文章是考虑医院使用了集成平台之后,门诊就诊流程详解。与我的文章《医疗实施-门诊就诊流程详解》的大致一样,供学有余力的人阅读。 …

图解java.util.concurrent并发包源码系列——深入理解ReentrantLock,看完可以吊打面试官

图解java.util.concurrent并发包源码系列——深入理解ReentrantLock&#xff0c;看完可以吊打面试官 ReentrantLock是什么&#xff0c;有什么作用ReentrantLock的使用ReentrantLock源码解析ReentrantLock#lock方法FairSync#tryAcquire方法NonfairSync#tryAcquire方法 Reentrant…

SpringBoot笔记:SpringBoot 集成 Dataway

文章目录 1、什么是 Dataway?2、主打场景3、技术架构4、整合SpringBoot4.1、maven 依赖4.2、初始化脚本4.3、整合 SpringBoot 5、Dataway 接口管理6、Mybatis 语法支持7、小结 1、什么是 Dataway? 官网地址&#xff1a;https://www.hasor.net/docs/guides/quickstart Da…

连通块是什么

刷题的时候遇到一个名词概念&#xff0c;连通块是什么&#xff1f; 在图论中&#xff0c;无向图中的连通块&#xff08;也叫作连通分量&#xff09;是指原图的一个子图&#xff08;即该子图只包含原图中的部分或全部顶点及边&#xff09;&#xff0c;该子图任意两个顶点都能通…

Swift 环境搭建

Swift是一门开源的编程语言&#xff0c;该语言用于开发OS X和iOS应用程序。 在正式开发应用程序前&#xff0c;我们需要搭建Swift开发环境&#xff0c;以便更好友好的使用各种开发工具和语言进行快速应用开发。由于Swift开发环境需要在OS X系统中运行&#xff0c;因此其环境的…

智能指针shared_ptr:自定义删除器

重点&#xff1a; 1.普通指针转化成智能指针。 2.智能指针创建的时候&#xff0c;第二个参数是自定义删除器&#xff0c;默认情况下&#xff0c;shared_ptr调用delete()函数。 class A { public:void Get() { cout << b << endl; }; private:int b{ 10 }; };clas…

Java 与其他编程语言:比较分析

Java 擅长可移植性和可靠性&#xff0c;Python 擅长通用性和简单性&#xff0c;JavaScript 擅长 Web 开发&#xff0c;C 擅长性能&#xff0c;Go 擅长效率。 在广阔的软件开发世界中&#xff0c;选择正确的编程语言对于任何项目的成功都至关重要。Java 是一种以其多功能性和可移…

交换机Vlan实验

介绍 Vlan表示虚拟局域网。 常见的网络安全技术 VlanACL Vlan的作用 Vlan隔离了广播域&#xff0c;增加了网络的安全性。 知识点 默认vlan vlan1 是默认vlan&#xff0c;主要机器开机了&#xff0c;默认所有的接口都属于Vlan1 交换机的接口模式 Access : 这个模式用来…

RK3588平台开发系列讲解(文件系统篇)什么是 VFS

文章目录 一、什么是 VFS二、VFS 数据结构2.1、超级块结构2.2、目录结构2.3、文件索引结点2.4、打开的文件2.5、四大对象结构的关系沉淀、分享、成长,让自己和他人都能有所收获!😄 📢 今天我们一起来瞧一瞧 Linux 是如何管理文件,也验证一下 Linux 那句口号:一切皆为文…

卡尔曼滤波 | Matlab实现无迹kalman滤波仿真

文章目录 效果一览文章概述研究内容程序设计参考资料效果一览 文章概述 卡尔曼滤波 | Matlab实现无迹kalman滤波仿真 研究内容 无迹kalman滤波(UKF)不是采用的将非线性函数线性化的做法。无迹kalman仍然采用的是线性kalman滤波的架构,对于一步预测方程,使用无迹变换(UT)来…

Baumer工业相机堡盟工业相机如何通过BGAPISDK获取相机接口数据吞吐量(C++)

Baumer工业相机堡盟工业相机如何通过BGAPISDK里函数来获取相机当前数据吞吐量&#xff08;C&#xff09; Baumer工业相机Baumer工业相机的数据吞吐量的技术背景CameraExplorer如何查看相机吞吐量信息在BGAPI SDK里通过函数获取相机接口吞吐量 Baumer工业相机通过BGAPI SDK获取数…

【技能实训】DMS数据挖掘项目(完整程序)

文章目录 1. 系统需求分析1.1 需求概述1.2 需求说明 2. 系统总体设计2.1 编写目的2.2 总体设计2.2.1 功能划分2.2.2 数据库及表2.2.3 主要业务流程 3. 详细设计与实现3.1 表设计3.2 数据库访问工具类设计3.3 配置文件3.4 实体类及设计3.5 业务类及设计3.6 异常处理3.7 界面设计…

优雅记录与保留:探秘Spring Boot与Logback的高级日志输出与存储

&#x1f60a; 作者&#xff1a; 一恍过去 &#x1f496; 主页&#xff1a; https://blog.csdn.net/zhuocailing3390 &#x1f38a; 社区&#xff1a; Java技术栈交流 &#x1f389; 主题&#xff1a; 优雅记录与保留&#xff1a;探秘Spring Boot与Logback的高级日志输出与…

Java中运算符要注意的一些点

目录 1. 算术运算符 1. 1 基本四则运算符&#xff1a;加减乘除模( - * / %) 1.2. 增量运算符 - * % 2. 关系运算符 3. 逻辑运算符 3.1. 逻辑与 && 3.2. 逻辑 || 3.3. 逻辑非 ! 3.4. 短路求值 4. 位运算符 4.1. 按位与 &: 如果两个二进制位都是 …