软件部分
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);
}