Skip to content

软件部分

1 源文件整合

这次实验是对代码做整合的,所以要把05_Low-Power-Mode-Btn-Wakeup工程复制一份,导入到e2s里。

此外,还要将04_OLED_BME280-I2C工程的bme280.h bme280.c i2c.c i2c.h oled_font.h oled.h oled.c复制到新工程的src文件夹下。

2 生成代码

因为工程05没有配置过I2C,参考工程04的I2C配置,在configuration.xml中配置I2C相关的即可。

配置文件修改后点击生成代码。

3 修改hal_entry.c

在文件开头加入代码

查看代码
c
#include "hal_data.h"
#include "debug_bsp_uart.h"
#include "rtc.h"
#include "irq.h"
#include "lpm.h"
#include "oled.h"
#include "bme280.h"

rtc_time_t get_time;
uint8_t wakeup_time=0;
BME_Struct bme = {0, 0, 0, false};

在hal_entry函数中加入

查看代码
c
    Debug_UART9_Init(); // SCI9 UART 调试串口初始化
    g_i2c_master0.p_api->open(&g_i2c_master0_ctrl, &g_i2c_master0_cfg);
    BME280_Init(&bme);
    OLED_Init();
    RTC_Init();
    IRQ_Init();
    LPM_Init();
    while (1)
    {
        if (key_pressed)
        {
            key_pressed = false;
            if(!in_LPM){
                wakeup_time = 0;
                EnterLowPowerMode();
            }
            else{
                in_LPM = false;
            }
        }
        if (rtc_flag)
        {
            rtc_flag = 0;
            uint8_t t1[50] = {0}, t2[50] = {0}, t3[50] = {0}, t4[50] = {0};
            wakeup_time++;
            if(wakeup_time>5){
                wakeup_time = 0;
                EnterLowPowerMode();
            }
            g_rtc0.p_api->calendarTimeGet(&g_rtc0_ctrl, &get_time); // 获取 RTC 计数时间
            sprintf((char *)t1, "%4d.%02d.%02d",
                    get_time.tm_year + 1900, get_time.tm_mon + 1, get_time.tm_mday);
            sprintf((char *)t2, "%02d:%02d:%02d",
                    get_time.tm_hour, get_time.tm_min, get_time.tm_sec);

            if (bme.initialized)
            {
                BME280_Get_Data(&bme);
                sprintf((char *)t3, "%.1fC %.1f%%RH", bme.temp, bme.humi);
                sprintf((char *)t4, "%.1fhPa", bme.press);
                OLED_ShowString(12, 32, t3, 16); // 显示温度湿度
                OLED_ShowString(24, 48, t4, 16); // 显示气压
            }
            OLED_ShowString(24, 0, t1, 16);  // 显示年月日
            OLED_ShowString(32, 16, t2, 16); // 显示时分秒
        }
        if (uart_rx_complete_flag)
        {
            char *time;
            uart_rx_complete_flag = 0;
            // 解析设置时间的命令 e.g: time:20250126080910
            // warning: 未添加错误纠正算法,请输入正确的时间,否则工作异常!
            if (strncmp(rx_data, "time:", 5) == 0)
            {
                time = rx_data + 5;
                set_time.tm_year = ((time[0] - '0') * 1000) + ((time[1] - '0') * 100) +
                                   ((time[2] - '0') * 10) + (time[3] - '0') - 1900;
                set_time.tm_mon = ((time[4] - '0') * 10) + (time[5] - '0') - 1;
                set_time.tm_mday = ((time[6] - '0') * 10) + (time[7] - '0');
                set_time.tm_hour = ((time[8] - '0') * 10) + (time[9] - '0');
                set_time.tm_min = ((time[10] - '0') * 10) + (time[11] - '0');
                set_time.tm_sec = ((time[12] - '0') * 10) + (time[13] - '0');
                g_rtc0.p_api->calendarTimeSet(&g_rtc0_ctrl, &set_time);
            }
        }
    }

主函数尽量做到简洁,只做调用各个模块的函数实现模块化编程(虽然还有部分业务代码漏在外面),因此本工程与工程04和05的部分源文件有些许不同,各模块的代码新增的函数列在下一节。

4 各模块新增/修改的函数

注意,如果是新增的函数,请自行在头文件中添加函数声明,这里就不一一指明头文件内修改的内容了。

4.1 lpm.c

查看代码
c
void EnterLowPowerMode()
{
    if(!in_LPM){
        OLED_DisPlay_Off();  //关闭屏幕
        BME280_Sleep();  //bme280进睡眠模式
//        printf("进入低功耗模式\n");
        in_LPM = true;
        g_lpm0.p_api->lowPowerModeEnter(&g_lpm0_ctrl);
        OLED_DisPlay_On();  //打开屏幕
        BME280_Wakeup();  //bme280恢复正常模式
    }

}

4.2 rtc.c

查看代码
c
void RTC_Init()
{
    g_rtc0.p_api->open(&g_rtc0_ctrl, &g_rtc0_cfg);
    g_rtc0.p_api->calendarTimeSet(&g_rtc0_ctrl, &set_time);
    g_rtc0.p_api->periodicIrqRateSet(&g_rtc0_ctrl, RTC_PERIODIC_IRQ_SELECT_1_SECOND);
}