1 前言
之前几次实验都是分开验证模块功能的,这次就把它们整合到一起,目的是把低功耗桌面日历摆件项目做出来。
2 软件部分
2.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.2 生成代码
因为工程05没有配置过I2C,参考工程04的I2C配置,在configuration.xml
中配置I2C相关的即可。
配置文件修改后点击生成代码。
2.3 修改hal_entry.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函数中加入
Debug_UART9_Init();
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);
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;
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的部分源文件有些许不同,各模块的代码新增的函数列在下一节。
## 2.4 各模块新增/修改的函数
注意,如果是新增的函数,请自行**在头文件中添加函数声明**,这里就不一一指明头文件内修改的内容了。
### 2.4.1 lpm.c
```c
void EnterLowPowerMode()
{
if(!in_LPM){
OLED_DisPlay_Off();
BME280_Sleep();
in_LPM = true;
g_lpm0.p_api->lowPowerModeEnter(&g_lpm0_ctrl);
OLED_DisPlay_On();
BME280_Wakeup();
}
}
2.4.2 rtc.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);
}
3 下载测试
把编译好的程序下载到开发板并复位,正确连接OLED屏幕和BME280传感器模块。
板子上电后,会亮屏5秒钟显示时间、温湿度气压数据,接着进入低功耗待机状态。点按板子上的用户按键,板子恢复工作状态,继续显示5秒钟,用户可中途再按下按键让其立即进入低功耗待机状态。
使用手上的INA219模块采集电流,其分辨率20uA,连接PC上位机,能看到下图所示的电流波形。
电源输入3.3V时,板子待机电流在20uA以下,采集值近似为0,工作时平均电流约12mA,峰值电流15.5mA。

工程附件
*附件:06_Low-Power-Desktop-Calender.zip