嵌入式技术论坛
直播中

万物死

8年用户 1223经验值
擅长:MEMS/传感技术
私信 关注
[经验]

基于Art-Pi的NTP同步时钟+DHT11获取温度的设计实现

开发环境:RT-Thread Studio

开发板:Art-Pi

OS版本:4.0.3

硬件

显示屏:金逸晨GMG12864-03A

温湿度:DHT11

嘉立创打样 扩展板

参考资料

Art_Pi学习笔记3:学习驱动wifi模块AP6212

ART-Pi与RT-Thread入门】⑦启用NTP同步时钟

新建一个项目

开启软件包设置

dht11.c

/*

  • Copyright (c) 2006-2020, RT-Thread Development Team
  • SPDX-License-Identifier: Apache-2.0
  • Change Logs:
  • Date Author Notes
  • 2021-01-30 78818 the first version

*/

#include <rtthread.h>

#include <rtdevice.h>

#include "drv_common.h"

#include <dht11.h>

#include "lcdst7567.h"

rt_thread_t tid4 = RT_NULL;

extern rt_mutex_t dynamic_mutex;

extern rt_uint8_t key_flag;

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;

DHT11_Data_TypeDef DHT11_D;

/**

* [url=home.php?mod=space&uid=2666770]@Brief[/url] DHT11 读取字节

*/

uint8_t DHT11_ReadByte(void)

{

uint8_t i, temp = 0;

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

{

    while (DHT11_IN_READ == 0);    // 等待低电平结束

    // 经过测试,这个值最好是 40 ~ 60,这里我选择 50 us

    rt_hw_us_delay(55);     // 至少延时 40 微秒  低电平为 0 ,高电平为 1

    if (DHT11_IN_READ == 1)

    {

        while (DHT11_IN_READ == 1);  // 等待高电平结束

        temp |= (uint8_t)(0X01 << (7 - i));     // 先发送高位 MSB

    }

    else

    {

        temp &= (uint8_t)~(0X01 << (7 - i));

    }

}

return temp;

}

/**

* @brief DHT11 读取一次数据

*/

uint8_t DHT11_ReadData(DHT11_Data_TypeDef *DHT11_Data)

{

dht11_out;        // 主机输出,主机拉低

DHT11_OUT_0;

rt_thread_mdelay(18);                  // 延时 18 ms

DHT11_OUT_1;                        // 主机拉高,延时 30 us

rt_hw_us_delay(30);

dht11_in;         // 主机输入,获取 DHT11 数据

if (DHT11_IN_READ == 0)          // 收到从机应答

{

    while (DHT11_IN_READ == 0);      // 等待从机应答的低电平结束

    while (DHT11_IN_READ == 1);      // 等待从机应答的高电平结束

    /*开始接收数据*/

    DHT11_Data->humi_int  = DHT11_ReadByte();

    DHT11_Data->humi_deci = DHT11_ReadByte();

    DHT11_Data->temp_int  = DHT11_ReadByte();

    DHT11_Data->temp_deci = DHT11_ReadByte();

    DHT11_Data->check_sum = DHT11_ReadByte();

    dht11_out;        // 读取结束,主机拉高

    DHT11_OUT_1;

    // 数据校验

    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;

}

}

/* 线程1的入口函数 */

static void thread4_entry(void *parameter)

{

while (1)

{

   // rt_mutex_take(dynamic_mutex, RT_WAITING_FOREVER);

    if (DHT11_ReadData(&DHT11_D))

    {

        rt_kprintf("\r\n%d.%d %RH,%d.%d℃ \r\n",

        DHT11_D.humi_int,DHT11_D.humi_deci,DHT11_D.temp_int,DHT11_D.temp_deci);

        clear();

        display_num(1,10,'b',DHT11_D.temp_int);

        show_letter_m(2,46,'.');

        show_letter_m(3,50,'C');

        display_num(1,70,'b',DHT11_D.humi_int);

        show_letter_m(3,110,'%');

    }

    else

    {

        rt_kprintf("Read DHT11 ERROR!\r\n");

    }

 //   rt_mutex_release(dynamic_mutex);

    rt_thread_mdelay(3000);

}

}

int dht11_init(void)

{

/* 创建线程1,名称是thread1,入口是thread1_entry*/

tid4 = rt_thread_create("dht11",

                            thread4_entry, RT_NULL,

                            384,

                            26, 10);

    /* 如果获得线程控制块,启动这个线程 */

    if (tid4 != RT_NULL)

        rt_thread_startup(tid4);

   // rt_thread_suspend(tid4);

    return 0;

}

MSH_CMD_EXPORT(dht11_init, dht11_init);

dht11.h

/*

  • Copyright (c) 2006-2020, RT-Thread Development Team
  • SPDX-License-Identifier: Apache-2.0
  • Change Logs:
  • Date Author Notes
  • 2021-01-30 78818 the first version

*/

#ifndef APPLICATIONS_INC_DHT11_H_

#define APPLICATIONS_INC_DHT11_H_

#include <rtthread.h>

#include <rtdevice.h>

#include "drv_common.h"

#define dht11 GET_PIN(E, 4)

#define dht11_out rt_pin_mode(dht11,PIN_MODE_OUTPUT)

#define dht11_in rt_pin_mode(dht11,PIN_MODE_INPUT)

#define DHT11_OUT_1 rt_pin_write(dht11, PIN_HIGH)

#define DHT11_OUT_0 rt_pin_write(dht11, PIN_LOW)

#define DHT11_IN_READ rt_pin_read(dht11)

//uint8_t DHT11_ReadData(DHT11_Data_TypeDef *DHT11_Data);

int dht11_init(void);

#endif /* APPLICATIONS_INC_DHT11_H_ */

key.c

/*

  • Copyright (c) 2006-2020, RT-Thread Development Team
  • SPDX-License-Identifier: Apache-2.0
  • Change Logs:
  • Date Author Notes
  • 2021-01-29 78818 the first version

*/

#include <key.h>

#include <led.h>

//#include <dht11.h>

#include "lcdst7567.h"

static rt_thread_t tid_key_scan = RT_NULL;

static rt_uint8_t menu_flag=1,app_flag=0;

rt_uint8_t key_flag4=0,key_flag1=0,key_flag3=0;

extern rt_thread_t tid4,tid2;

extern const rt_uint8_t shi[24];

extern const rt_uint8_t zhong[24];

extern const rt_uint8_t wen[24];

extern const rt_uint8_t si[24];

extern const rt_uint8_t du[24];

extern void display_time(void);

extern int dht11_init(void);

void key_1(void *args) {

rt_kprintf("turn on key_1!\n");

key_flag1=1;

}

void key_2(void *args) {

rt_kprintf("turn on key_2!\n");

//rt_pin_write(led_2, PIN_HIGH);

//

//rt_pin_write(led_2, PIN_LOW);

}

void key_3(void *args) {

rt_kprintf("turn on key_3!\n");

key_flag3=1;

}

void key_4(void *args) {

rt_kprintf("turn on key_4!\n");

key_flag4=1;

}

static void tid_key_scan_entry(void *parameter)

{

while (1)

    {

        if (1 == key_flag4)

        {

            key_flag4 = 0;

            // 延迟10ms,消抖

            rt_thread_delay(100);

            if (0 == key_flag4)

            {

            rt_pin_write(RGB_G, PIN_HIGH);

            rt_kprintf(" Key4 press\n");

            if(menu_flag==1)

            {

                show_letter_m(app_flag,10,' ');

                app_flag+=2;

                if(app_flag == 4)

                {

                    app_flag=0;

                }

                show_letter_m(app_flag,10,'*');

            }

            else {

                menu_flag=1;

                switch(app_flag)

                    {

                    case 0:

                        rt_thread_delete(tid2);break;

                    case 2:

                        rt_thread_delete(tid4);break;

                    default:break;

                    }

                app_flag+=2;

                if(app_flag == 4)

                    {

                        app_flag=0;

                    }

                clear();

                show_letter_m(0,20,'1');

                show_letter_m(0,28,'.');

                show_zw_m(0,36,(rt_uint8_t *)shi);

                show_zw_m(0,48,(rt_uint8_t *)zhong);

                show_letter_m(2,20,'2');

                show_letter_m(2,28,'.');

                show_zw_m(2,36,(rt_uint8_t *)wen);

                show_zw_m(2,48,(rt_uint8_t *)si);

                show_zw_m(2,48,(rt_uint8_t *)du);

                show_letter_m(app_flag,10,'*');

            }

            rt_pin_write(RGB_G, PIN_LOW);

            }

            else

            {

            key_flag4 = 0;

            }

        }

        if (1 == key_flag3)

                    {

                        key_flag3 = 0;

                        // 延迟10ms,消抖

                        rt_thread_delay(100);

                        if (0 == key_flag3)

                        {

                        rt_pin_write(led_3, PIN_HIGH);

                        rt_kprintf(" Key3 press\n");

                        if(menu_flag==1)

                        {

                        switch(app_flag)

                            {

                            case 0:

                                display_time();menu_flag=0;break;

                            case 2:

                                dht11_init();menu_flag=0;break;

                            default:break;

                            }

                        }

                        rt_pin_write(led_3, PIN_LOW);

                        }

                        else

                        {

                        key_flag3 = 0;

                        }

                    }

        if (1 == key_flag1)

                    {

                        key_flag1 = 0;

                        // 延迟10ms,消抖

                        rt_thread_delay(10);

                        if (0 == key_flag1)

                        {

                        rt_pin_write(led_1, PIN_HIGH);

                        rt_kprintf(" Key1 press\n");

                        rt_pin_write(led_1, PIN_LOW);

                        }

                        else

                        {

                        key_flag1 = 0;

                        }

                    }

        rt_thread_delay(500);

    }

}

void key_init(void)

{

//按 键1引 脚 为 输 入 模 式

rt_pin_mode(key1, PIN_MODE_INPUT_PULLUP);

//绑 定 中 断, 下 降 沿 模 式, 回 调 函 数 名 为beep_on

rt_pin_attach_irq(key1, PIN_IRQ_MODE_FALLING, key_1, RT_NULL);

//使 能 中 断

rt_pin_irq_enable(key1, PIN_IRQ_ENABLE);

//按 键2引 脚 为 输 入 模 式

//rt_pin_mode(key2, PIN_MODE_INPUT_PULLUP);

//绑 定 中 断, 下 降 沿 模 式, 回 调 函 数 名 为beep_on

//rt_pin_attach_irq(key2, PIN_IRQ_MODE_FALLING, key_2, RT_NULL);

// 使 能 中 断

//rt_pin_irq_enable(key2, PIN_IRQ_ENABLE);

//按 键3引 脚 为 输 入 模 式

rt_pin_mode(key3, PIN_MODE_INPUT_PULLUP);

// 绑 定 中 断, 下 降 沿 模 式, 回 调 函 数 名 为beep_on

rt_pin_attach_irq(key3, PIN_IRQ_MODE_FALLING, key_3, RT_NULL);

//使 能 中 断

rt_pin_irq_enable(key3, PIN_IRQ_ENABLE);

//按 键4引 脚 为 输 入 模 式

rt_pin_mode(key4, PIN_MODE_INPUT_PULLUP);

//绑 定 中 断, 下 降 沿 模 式, 回 调 函 数 名 为beep_on

rt_pin_attach_irq(key4, PIN_IRQ_MODE_FALLING, key_4, RT_NULL);

//使 能 中 断

rt_pin_irq_enable(key4, PIN_IRQ_ENABLE);

/* 创建线程1,名称是thread1,入口是thread1_entry*/

tid_key_scan = rt_thread_create("key_scan",

tid_key_scan_entry, RT_NULL,

                          352,

                          20, 10);

  /* 如果获得线程控制块,启动这个线程 */

  if (tid_key_scan != RT_NULL)

      rt_thread_startup(tid_key_scan);

}

key.h

/*

  • Copyright (c) 2006-2020, RT-Thread Development Team
  • SPDX-License-Identifier: Apache-2.0
  • Change Logs:
  • Date Author Notes
  • 2021-01-29 78818 the first version

*/

#ifndef APPLICATIONS_INC_KEY_H_

#define APPLICATIONS_INC_KEY_H_

#include <rtthread.h>

#include <rtdevice.h>

#include "drv_common.h"

#define key1 GET_PIN(B, 1)

#define key2 GET_PIN(H, 3)

#define key3 GET_PIN(B, 0)

#define key4 GET_PIN(B, 2)

void key_init(void);

#endif /* APPLICATIONS_INC_KEY_H_ */

getntp.c

/*

  • Copyright (c) 2006-2020, RT-Thread Development Team
  • SPDX-License-Identifier: Apache-2.0
  • Change Logs:
  • Date Author Notes
  • 2021-01-28 78818 the first version

*/

#include <rtthread.h>

#include <rtdevice.h>

#include <ntp.h>

#include "lcdst7567.h"

#define THREAD_PRIORITY 25

//#define THREAD_STACK_SIZE 2048

#define THREAD_TIMESLICE 5

extern rt_uint8_t key_flag;

rt_thread_t tid1 = RT_NULL,tid2 = RT_NULL;

ALIGN(RT_ALIGN_SIZE)

/* 线程1的入口函数 */

static void thread1_entry(void *parameter)

{

while(rt_wlan_is_ready() != RT_TRUE)  //是否连上外网

    {

    rt_thread_mdelay(200);

    }

    time_t cur_time=0;

while(cur_time==0)

    {

    cur_time = ntp_sync_to_rtc(NULL);

    clear_page(5);

    clear_page(6);

    clear_page(7);

    rt_thread_mdelay(1000);

    if(cur_time)

    {

        rt_kprintf("cur time: %s", ctime((const time_t*) &cur_time));

        clear_page(5);

        rt_thread_mdelay(1000);

    }

    else {

        clear_page(5);

        rt_kprintf("ntp sync fail. \n");

        rt_thread_mdelay(1000);

    }

}

}

static void thread2_entry(void *parameter)

{

rt_uint8_t i=0;

while(1)

{

    time_t now; /* 保 存 获 取 的 当 前 时 间 值 */

    /* 获 取 时 间 */

    now = time(RT_NULL);

    /* 打 印 输 出 时 间 信 息 */

    //rt_kprintf("%s\n", ctime(&now));

    struct tm *t;

    t = gmtime((const time_t*) &now);

    clear();

    display_num(0,20,'b',t->tm_hour);

    display_num(0,71,'b',t->tm_min);

    if(i==0)

    {

        show_num_40(0,54,10);

    i=1;

    }

    else

    {

        show_num_40(0,54,11);

        i=0;

    }

    display_num(5,12,'m',t->tm_year+1900);

    show_letter_m(5,44,'-');

    display_num(5,52,'m', t->tm_mon+1);

    show_letter_m(5,68,'-');

    display_num(5,76,'m', t->tm_mday );

    show_letter_m(5,92,'|');

    display_num(5,100,'m', t->tm_wday );

    rt_thread_mdelay(500);

}

}

int getntp(void)

{

/* 创建线程1,名称是thread1,入口是thread1_entry*/

tid1 = rt_thread_create("getntp",

                            thread1_entry, RT_NULL,

                            1536,

                            THREAD_PRIORITY, THREAD_TIMESLICE);

    /* 如果获得线程控制块,启动这个线程 */

    if (tid1 != RT_NULL)

        rt_thread_startup(tid1);

    return 0;

}

void display_time(void)

{

/* 创建线程2*/

        tid2 = rt_thread_create("dptime",

                                    thread2_entry, RT_NULL,

                                    384,

                                    THREAD_PRIORITY+1, THREAD_TIMESLICE);

            /* 如果获得线程控制块,启动这个线程 */

        if (tid2 != RT_NULL)

         rt_thread_startup(tid2);

}

MSH_CMD_EXPORT(getntp, getntp);

MSH_CMD_EXPORT(display_time, display time);

main.c

/*

  • Copyright (c) 2006-2020, RT-Thread Development Team
  • SPDX-License-Identifier: Apache-2.0
  • Change Logs:
  • Date Author Notes
  • 2020-09-02 RT-Thread first version

*/

#include <rtthread.h>

#include <rtdevice.h>

#include "drv_common.h"

#include "lcdst7567.h"

#include <key.h>

#include <led.h>

extern void wlan_autoconnect_init(void);

extern int getntp(void);

const rt_uint8_t shi[24]={/-- 文字: 时 --/

/*--  Tahoma9;  此字体下对应的点阵为:宽x高=12x14   --*/

    /*--  高度不是8的倍数,现调整为:宽度x高度=12x16  --*/

    0xF8,0x88,0x88,0xF8,0x00,0x20,0x20,0x20,0x20,0xFC,0x20,0x00,0x1F,0x08,0x08,0x1F,

    0x00,0x00,0x01,0x26,0x20,0x3F,0x00,0x00};

const rt_uint8_t zhong[24]={/-- 文字: 钟 --/

/*--  Tahoma9;  此字体下对应的点阵为:宽x高=12x14   --*/

    /*--  高度不是8的倍数,现调整为:宽度x高度=12x16  --*/

    0x20,0x5C,0xD0,0x50,0x50,0x00,0xE0,0x20,0xFC,0x20,0xE0,0x00,0x02,0x02,0x3F,0x12,

    0x0A,0x00,0x07,0x02,0x3F,0x02,0x07,0x00};

const rt_uint8_t wen[24]={/-- 文字: 温 --/

/*--  Tahoma9;  此字体下对应的点阵为:宽x高=12x14   --*/

    /*--  高度不是8的倍数,现调整为:宽度x高度=12x16  --*/

    0x88,0x10,0x00,0x00,0x7C,0x54,0x54,0x54,0x7C,0x00,0x00,0x00,0x10,0x09,0x24,0x3F,

    0x21,0x3F,0x21,0x3F,0x21,0x3F,0x20,0x00};

const rt_uint8_t si[24]={/-- 文字: 湿 --/

/*--  Tahoma9;  此字体下对应的点阵为:宽x高=12x14   --*/

    /*--  高度不是8的倍数,现调整为:宽度x高度=12x16  --*/

    0x44,0x88,0x00,0xF8,0xA8,0xA8,0xA8,0xA8,0xA8,0xF8,0x00,0x00,0x10,0x08,0x22,0x24,

    0x20,0x3F,0x20,0x3F,0x20,0x24,0x22,0x00};

const rt_uint8_t du[24]={/-- 文字: 度 --/

/*--  Tahoma9;  此字体下对应的点阵为:宽x高=12x14   --*/

    /*--  高度不是8的倍数,现调整为:宽度x高度=12x16  --*/

    0x00,0xF8,0x28,0x28,0xF8,0xA8,0xAC,0xA8,0xF8,0x28,0x28,0x00,0x20,0x1F,0x00,0x22,

    0x26,0x2A,0x12,0x12,0x2A,0x26,0x20,0x00};

int main(void)

{

rt_pin_mode(key4, PIN_MODE_INPUT_PULLUP);

/* init Wi-Fi auto connect feature */

wlan_autoconnect_init();

/* enable auto reconnect on WLAN device */

rt_wlan_config_autoreconnect(RT_TRUE);

Init_ST7567();

getntp();

led_init();

key_init();

display_pic(0,1);

rt_thread_mdelay(1000);

clear();

show_letter_m(0,20,'1');

show_letter_m(0,28,'.');

show_zw_m(0,36,(rt_uint8_t *)shi);

show_zw_m(0,48,(rt_uint8_t *)zhong);

show_letter_m(2,20,'2');

show_letter_m(2,28,'.');

show_zw_m(2,36,(rt_uint8_t *)wen);

show_zw_m(2,48,(rt_uint8_t *)si);

show_zw_m(2,48,(rt_uint8_t *)du);

show_letter_m(0,10,'*');

while(1)

{

rt_thread_mdelay(1000);

}

return RT_EOK;

}

#include "stm32h7xx.h"

static int vtor_config(void)

{

/* Vector Table Relocation in Internal QSPI_FLASH */

SCB->VTOR = QSPI_BASE;

return 0;

}

INIT_BOARD_EXPORT(vtor_config);

原作者:freedom789

更多回帖

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