本实验是在上篇推文《中科蓝讯AB32VG1之DHT11温湿度测量
》项目基础上,增加OLED显示功能,将采集到的温湿度数值显示在OLED显示屏。上面文章的连接中科蓝讯AB32VG1之DHT11温湿度测量。
第一步:首先双击打开RT-Thread Settings,添加SSD1309软件包.具体步骤参照推文中科蓝讯 AB32VG1 开发板OLED显示实验,添加成功之后如下图所示。
双击软件包进入SSD1306软件包配置界面,这里驱动要打上勾号,如下图所示
然后在硬件中,开启IIC功能,如下图所示
按ctrl+s键保存编译,SSD1306驱动配置完成。
第二步:修改main函数。
1.首先main函数包含要以下头文件
#include "board.h"
#include <rtdevice.h>
#include "sensor.h"
#include "sensor_dallas_dht11.h"//DHT11头文件
#include "drv_gpio.h"
#include "ssd1306.h"//包含SSD1306的头文件
2.修改DHT11的数据引脚
#define DHT11_DATA_PIN GET_PIN(A, 5)
3.定义两个全局变量
uint8_t temp,humi;存储温度和湿度数值
4.创建DHT11读取温度线程和线程入口函数
线程入口函数:
static void read_temp_entry(void *parameter)
{
rt_device_t dev = RT_NULL;
struct rt_sensor_data sensor_data;
rt_size_t res;
rt_uint8_t get_data_freq = 1; /* 1Hz */
dev = rt_device_find("temp_dht11");
if (dev == RT_NULL)
{
return;
}
if (rt_device_open(dev, RT_DEVICE_FLAG_RDWR) != RT_EOK)
{
rt_kprintf("open device failed!\n");
return;
}
rt_device_control(dev, RT_SENSOR_CTRL_SET_ODR, (void *)(&get_data_freq));
while (1)
{
res = rt_device_read(dev, 0, &sensor_data, 1);
if (res != 1)
{
rt_kprintf("read data failed! result is %d\n", res);
rt_device_close(dev);
return;
}
else
{
if (sensor_data.data.temp >= 0)
{
temp = (sensor_data.data.temp & 0xffff) >> 0; // get temp
humi = (sensor_data.data.temp & 0xffff0000) >> 16; // get humi
//rt_kprintf("temp:%d, humi:%d\n" ,temp, humi);
}
}
rt_thread_delay(1000);
}
}
线程创建函数:
void dht11_read_temp_sample(void)
{
rt_thread_t dht11_thread;
dht11_thread = rt_thread_create("dht_tem",
read_temp_entry,
RT_NULL,
1024,
RT_THREAD_PRIORITY_MAX / 2,
20);
if (dht11_thread != RT_NULL)
{
rt_thread_startup(dht11_thread);
}
}
5.DHT11的初始化
void rt_hw_dht11_port(void)
{
struct rt_sensor_config cfg;
cfg.intf.user_data = (void *)DHT11_DATA_PIN;
rt_hw_dht11_init("dht11", &cfg);
}4.创建OLED显示线程和线程入口函数
线程入口函数:
static void oled_display_entry(void *parameter)
{
char text[200];
while(1)
{
rt_memset(text, 0, sizeof(text));
rt_sprintf(text, "%d", temp);
ssd1306_SetCursor(60, 6);//添加代码,设置显示光标位置
ssd1306_WriteString(text, Font_11x18, White);//添加代码,设置显示内容
// ssd1306_UpdateScreen();添加代码,更新显示屏信息
rt_memset(text, 0, sizeof(text));
rt_sprintf(text, "%d", humi);
ssd1306_SetCursor(60, 40);//添加代码,设置显示光标位置
ssd1306_WriteString(text, Font_11x18, White);//添加代码,设置显示内容
ssd1306_UpdateScreen();添加代码,更新显示屏信息
rt_thread_mdelay(100);
}
}
线程创建函数:void oled_display_thread_create()
{
rt_thread_t oled_display_thread;
oled_display_thread = rt_thread_create("oled_display",
oled_display_entry,
RT_NULL,
1024,
20,
40);
if (oled_display_thread != RT_NULL)
{
rt_thread_startup(oled_display_thread);
}
}6.最后是Main函数:main函数主要完成OLED显示的初始化,创建和启动线程,初始化DHT11。
int main(void)
{
//OLED显示的初始化
ssd1306_Init();//添加代码,显示屏初始化
ssd1306_SetCursor(2, 6);//添加代码,设置显示光标位置
ssd1306_WriteString("Temp: ", Font_11x18, White);//添加代码,设置显示内容
ssd1306_SetCursor(2, 40);//添加代码,设置显示光标位置
ssd1306_WriteString("Humi: ", Font_11x18, White);//添加代码,设置显示内容
ssd1306_SetCursor(40, 40);//添加代码,设置显示光标位置
ssd1306_UpdateScreen();添加代码,更新显示屏信息
//相关线程的创建与启动
rt_hw_dht11_port();
dht11_read_temp_sample();
oled_display_thread_create();
return RT_EOK;
}
然后编译项目,没有错误,生成rtthread.dcf文件,下载文件至开发板,实际运行效果见原文视频。