瑞萨单片机论坛
直播中

安安踢球球

7年用户 142经验值
擅长:电源/新能源 嵌入式技术
私信 关注
[资料]

【RA-Eco-RA4M2开发板评测】+ OLED显示DHT11数据

RA-Eco-RA4M2 v2.0 延续了瑞萨一贯的高品质,在 100MHz 的高频驱动下,提供卓越的算力与安全保障。

内核大脑: 100MHz Arm Cortex-M33,支持 TrustZone 安全架构。

存储空间: 512KB Flash + 128KB SRAM(含 ECC 与奇偶校验)+ 8KB Data Flash(EEPROM 级别)。

丰富外设: 全速 USB 2.0、CAN 2.0B、SDHI/MMC 接口,支持 CTSU 电容触摸传感。

便捷开发: 板载 USB 转 TTL(直连串口)、标准 SWD 调试口、2 个 PMOD 扩展口。

板载交互: 1个复位键、2个用户按键、2个触摸按键、3个高亮 LED。

之前完成了OLED显示的测评现在进行DHT11传感器数据采集,然后显示,OLED部分不再重复说明;

DHT11 数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器,内部由一个 8 位单片机控制一个电阻式感湿元件和一个 NTC 测温元件。DHT11 虽然也是采用单总线协议,但是该协议与 DS18B20 的单总线协议稍微有些不同之处。

相比于 DS18B20 只能测量温度,DHT11 既能检测温度又能检测湿度,不过 DHT11 的精度和测量范围都要低于 DS18B20,其温度测量范围为 0~50℃,误差在±2℃;湿度的测量范围为 ~~~~20%90%RH(Relative Humidity 相对湿度—指空气中水汽压与饱和水汽压的百分比),误差在±5%RH。DHT11 电路很简单,只需要将 DATA 引脚连接单片机的一个 I/O 即可,不过该引脚需要上拉一个 5K 的电阻,DHT11 的供电电压为 35.5V
image.png

本次测评使用PA0104引脚作为数据线与DHT11连接;首先初始化引脚:
image.png

DHT11 采用单总线协议与单片机通信,单片机发送一次复位信号后,DHT11 从低功耗模式转换到高速模式,等待主机复位结束后,DHT11 发送响应信号,并拉高总线准备传输数据。一次完整的数据为 40bit,按照高位在前,低位在后的顺序传输。

数据格式为:8bit 湿度整数数据+8bit 湿度小数数据+8bit 温度整数数据+8bit 温度小数数据+8bit 校验和,一共 5 字节(40bit)数据。由于 DHT11 分辨率 只能精确到个位,所以小数部分是数据全为 0。校验和为前 4 个字节数据相加,校验的目的是为了保证数据传输的准确性。

DHT11 只有在接收到开始信号后才触发一次温湿度采集,如果没有接收到主机发送复位信号,DHT11 不主动进行温湿度采集。当数据采集完毕且无开始信号后,DHT11 自动切换到低速模式。

注意:由于 DHT11 时序要求非常严格,所以在操作时序的时候,为了防止中断干扰总线时序,先关闭总中断,操作完毕后再打开总中断。

DHT 11数据传输协议图如下:
image.png

步骤一:

DHT11上电后(DHT11上电后要等待 1S 以越过不稳定状态在此期间不能发送任何指令),测试环境

温湿度数据,并记录数据,同时 DHT11的DATA数据线由上拉电阻拉高一直保持高电平;此时 DHT11的 DATA 引脚处于输入状态,时刻检测外部信号。

步骤二:

微处理器的I/O设置为输出同时输出低电平,且低电平保持时间不能小于18ms(最大不得超过30ms),

然后微处理器的I/O设置为输入状态,由于上拉电阻,微处理器的I/O即DHT11的DATA数据线也随之变高,等待DHT11作出回答信号,发送信号如图所示:
image.png

步骤三:

DHT11的DATA引脚检测到外部信号有低电平时,等待外部信号低电平结束,延迟后DHT11的DATA引脚处于输出状态,输出 83微秒的低电平作为应答信号,紧接着输出 87 微秒的高电平通知外设准备接收数据,微处理器的 I/O 此时处于输入状态,检测到 I/O 有低电平(DHT11回应信号)后,等待87微秒的高电平后的数据接收,发送信号如图所示:
image.png

步骤四:

由DHT11的DATA引脚输出40位数据,微处理器根据I/O电平的变化接收40位数据,位数据“0”的格式为: 54 微秒的低电平和 23-27 微秒的高电平,位数据“1”的格式为: 54 微秒的低电平加68-74微秒的高电平。位数据“0”、“1”格式信号如图所示:
image.png

按照以上步骤编写启动信号和读取数据函数如下:

typedef struct

{

uint8\_t  humi\_high8bit;

uint8\_t  humi\_low8bit;

uint8\_t  temp\_high8bit;

uint8\_t  temp\_low8bit;

uint8\_t  check\_sum;

float humidity;

float temperature;

} DHT11_Data_TypeDef;

DHT11_Data_TypeDef DHT11_Data;

unsigned char U8FLAG,U8comdata,U8temp;

unsigned char U8RH_data_H_temp,U8RH_data_L_temp,U8checkdata_temp;

unsigned char U8T_data_H_temp,U8T_data_L_temp,U8RH_data_H,U8RH_data_L;

unsigned char str[5],U8T_data_H,U8T_data_L,U8checkdata;

static uint8_t DHT11_ReadByte (void )

{

uint8\_t i, temp=0;

R\_IOPORT\_PinCfg\(&g\_ioport\_ctrl,  BSP\_IO\_PORT\_01\_PIN\_04, BSP\_IO\_DIRECTION\_INPUT\);

for\(i=0;i<8;i\+\+\)

\{

    while\(R\_BSP\_PinRead\(BSP\_IO\_PORT\_01\_PIN\_04\)==0\);

    R\_BSP\_SoftwareDelay \(40, BSP\_DELAY\_UNITS\_MICROSECONDS\);

    if\(R\_BSP\_PinRead\(BSP\_IO\_PORT\_01\_PIN\_04\)==1\)

    \{

        while\(R\_BSP\_PinRead\(BSP\_IO\_PORT\_01\_PIN\_04\)==1\);

        temp|=\(uint8\_t\)\(0x01<<\(7\-i\)\);

    \}

    else

    \{

        temp&=\(uint8\_t\)~\(0x01<<\(7\-i\)\);

    \}

\}

return temp;

}

uint8_t DHT11_Read_TempAndHumidity(DHT11_Data_TypeDef *DHT11_Data)

{

uint8_t temp;

uint16_t humi_temp;

R_IOPORT_Open (&g_ioport_ctrl, g_ioport.p_cfg);

//R_IOPORT_PinCfg(&g_ioport_ctrl, BSP_IO_PORT_01_PIN_04, BSP_IO_DIRECTION_OUTPUT|IOPORT_CFG_PORT_OUTPUT_HIGH);

R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_01_PIN_04, BSP_IO_LEVEL_LOW);

R_BSP_SoftwareDelay (20,BSP_DELAY_UNITS_MILLISECONDS);

R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_01_PIN_04, BSP_IO_LEVEL_HIGH);

R\_BSP\_SoftwareDelay \(36, BSP\_DELAY\_UNITS\_MICROSECONDS\);

R\_IOPORT\_PinCfg\(&g\_ioport\_ctrl,  BSP\_IO\_PORT\_01\_PIN\_04, BSP\_IO\_DIRECTION\_INPUT\);

R_BSP_SoftwareDelay (30, BSP_DELAY_UNITS_MICROSECONDS);

if\(R\_BSP\_PinRead\(BSP\_IO\_PORT\_01\_PIN\_04\)==0\)

\{

while\(R\_BSP\_PinRead\(BSP\_IO\_PORT\_01\_PIN\_04\)==0\);

while\(R\_BSP\_PinRead\(BSP\_IO\_PORT\_01\_PIN\_04\)==1\);

DHT11\_Data\->humi\_high8bit= DHT11\_ReadByte\(\);

DHT11\_Data\->humi\_low8bit = DHT11\_ReadByte\(\);

DHT11\_Data\->temp\_high8bit= DHT11\_ReadByte\(\);

DHT11\_Data\->temp\_low8bit = DHT11\_ReadByte\(\);

DHT11\_Data\->check\_sum    = DHT11\_ReadByte\(\);

// DHT11_Mode_Out_PP();

R\_IOPORT\_PinCfg\(&g\_ioport\_ctrl,  BSP\_IO\_PORT\_01\_PIN\_04, BSP\_IO\_DIRECTION\_OUTPUT|IOPORT\_CFG\_PORT\_OUTPUT\_HIGH\);

R\_IOPORT\_PinWrite\(&g\_ioport\_ctrl, BSP\_IO\_PORT\_01\_PIN\_04, BSP\_IO\_LEVEL\_HIGH\);

humi\_temp=DHT11\_Data\->humi\_high8bit\*100\+DHT11\_Data\->humi\_low8bit;

DHT11\_Data\->humidity =\(float\)humi\_temp/100;

humi\_temp=DHT11\_Data\->temp\_high8bit\*100\+DHT11\_Data\->temp\_low8bit;

DHT11\_Data\->temperature=\(float\)humi\_temp/100;

temp = DHT11\_Data\->humi\_high8bit \+ DHT11\_Data\->humi\_low8bit \+

       DHT11\_Data\->temp\_high8bit\+ DHT11\_Data\->temp\_low8bit;

if\(DHT11\_Data\->check\_sum==temp\)

\{

  return 1;

\}

else

  return 0;

\}

else

 return 0;

}

在测试过程中遇到一个问题就是:

R_IOPORT_PinCfg(&g_ioport_ctrl,BSP_IO_PORT_01_PIN_04,BSP_IO_DIRECTION_OUTPUT|IOPORT_CFG_PORT_OUTPUT_HIGH);

这一条语句不起作用,最后使用了R_IOPORT_Open (&g_ioport_ctrl, g_ioport.p_cfg);替换才采集到数据;

在循环语句中调用:

DHT11_Read_TempAndHumidity(&DHT11_Data);

就可得到数据

最后给出接线和测试硬件图:
image.png

最后是逻辑分析仪上的波形:
image.png

更多回帖

发帖
×
20
完善资料,
赚取积分