UPL 唤醒
ULP协处理器是RTC外设电源域的一部分,它运行存储在RTC慢速存储器中的程序。ULP协处理器可以在芯片处于休眠模式时运行,可用于轮询传感器、监控ADC或触摸传感器值,以及在检测到特定事件时唤醒芯片。如果请求此唤醒模式,则 RTC 慢速内存将在睡眠期间打开电源。在ULP协处理器开始运行程序之前,RTC外设将自动通电;一旦程序停止运行,RTC外设将再次自动断电。
esp_sleep_enable_ulp_wakeup() 该函数用于启用此唤醒源。
您可以使用以下命令上传 ULP 程序:
void init_ulp_program() {
const ulp_insn_t program[] = {
// initiate wakeup of the SoC启动SoC唤醒
I_WAKE(),
// stop the ULP program停止ULP程序
I_HALT()
};
size_t load_addr = 0;
size_t size = sizeof(program)/sizeof(ulp_insn_t);
ulp_process_macros_and_load(load_addr, program, &size);
ulp_run(0);
}
设置 ULP 唤醒周期的命令是:
esp_err_t ulp_set_wakeup_period(size_t period_index, uint32_t period_us);
参数: 报警周期设置(0 – 4) 唤醒周期的索引,以μs为单位period_index ``period_us a
成功
回报如果 period_index超出范围ESP_OK ESP_ERR_INVALID_ARG
用于唤醒 esp32 的 ULP 命令包括:
// initiate wakeup of the SoC
I_WAKE(),
// stop the ULP program
I_HALT()
这是完整的草图:
#include "esp32/ulp.h"
#include "soc/rtc_cntl_reg.h"
#include "driver/rtc_io.h"
void init_ulp_program();
RTC_DATA_ATTR int bootCount = 0;
void print_wakeup_reason(){
esp_sleep_wakeup_cause_t wakeup_reason;
wakeup_reason = esp_sleep_get_wakeup_cause();
switch(wakeup_reason)
{
case ESP_SLEEP_WAKEUP_EXT0 : Serial2.println("Wakeup caused by external signal using RTC_IO"); break;
case ESP_SLEEP_WAKEUP_EXT1 : Serial2.println("Wakeup caused by external signal using RTC_CNTL"); break;
case ESP_SLEEP_WAKEUP_TIMER : Serial2.println("Wakeup caused by timer"); break;
case ESP_SLEEP_WAKEUP_TOUCHPAD : Serial2.println("Wakeup caused by touchpad"); break;
case ESP_SLEEP_WAKEUP_ULP : Serial2.println("Wakeup caused by ULP program"); break;
default : Serial2.printf("Wakeup was not caused by deep sleep: %d\n",wakeup_reason); break;
}
}
void setup() {
Serial2.begin(115200);
while( !Serial ){}
Serial2.println("Init");
++bootCount;
Serial2.println("Boot number: " + String(bootCount));
print_wakeup_reason();
esp_sleep_wakeup_cause_t cause = esp_sleep_get_wakeup_cause();
if (cause != ESP_SLEEP_WAKEUP_ULP) {
Serial2.println("Initializing ULP");
init_ulp_program();
ulp_set_wakeup_period(0, 5 * 1000 * 1000);
}
Serial2.println("Entering deep sleep\n");
ESP_ERROR_CHECK( esp_sleep_enable_ulp_wakeup() );
esp_deep_sleep_start();
}
void loop(){
}
void init_ulp_program() {
const ulp_insn_t program[] = {
I_WAKE(),
I_HALT()
};
size_t load_addr = 0;
size_t size = sizeof(program)/sizeof(ulp_insn_t);
ulp_process_macros_and_load(load_addr, program, &size);
ulp_run(0);
}
串行2 输出为
Init
Boot number: 1
Wakeup was not caused by deep sleep: 0
Entering deep sleep
Init
Boot number: 2
Wakeup caused by ULP program
ULP wakeup
Entering deep sleep
Init
Boot number: 3
Wakeup caused by ULP program
ULP wakeup
Entering deep sleep
结束
你能砍掉所有的鲜花,但你不能阻止春天的到来。 – 巴勃罗?聂鲁达
|