关于LPL低功耗模式得疑问
现有设备在待机状态和接收状态时功耗在200ma左右,如果标签长时间处于接收状态则会让电池迅速的耗电,所以我设想使用Low_Power_Listening模式和帧过滤相互结合 标签长时间处于LPL模式 并定时唤醒检测信息 如果收到FCG则进入中断处理数据,我参照了官方提供的例程代码 原官方代码如下int main(void)
{
uint32 lp_osc_freq, sleep_cnt;
/* Start with board specific hardware init. */
peripherals_init();
/* Display application name on LCD. */
lcd_display_str(APP_NAME);
/* Install the low-power listening ISR handler.
* This is an interrupt service routine part of the driver that is specific to correctly handling the low-power listening wake-up. */
port_set_deca_isr(dwt_lowpowerlistenisr);
/* Reset and initialise DW1000. See NOTE 8 and 9 below.
* For initialisation, DW1000 clocks must be temporarily set to crystal speed. After initialisation SPI rate can be increased for optimum
* performance. */
reset_DW1000(); /* Target specific drive of RSTn line into DW1000 low for a period. */
spi_set_rate_low();
if (dwt_initialise(DWT_LOADNONE) == DWT_ERROR)
{
lcd_display_str("INIT FAILED");
while (1)
{ };
}
spi_set_rate_high();
/* This is put here for testing, so that we can see the receiver ON/OFF pattern using an oscilloscope. */
dwt_setlnapamode(1, 1);
/* Configure DW1000. See NOTE 10 below. */
dwt_configure(&config);
/* Calibrate and configure sleep count. This has to be done with DW1000 clocks set to crystal speed.
* This will define the duration of the "long sleep" phase. */
spi_set_rate_low();
lp_osc_freq = (XTAL_FREQ_HZ / 2) / dwt_calibratesleepcnt();
sleep_cnt = ((LONG_SLEEP_TIME_MS * lp_osc_freq) / 1000) >> 12;
dwt_configuresleepcnt(sleep_cnt);
spi_set_rate_high();
/* Configure sleep mode to allow low-power listening to operate properly. */
dwt_configuresleep(DWT_PRESRV_SLEEP | DWT_CONFIG | DWT_RX_EN, DWT_WAKE_SLPCNT | DWT_SLP_EN);
/* Set snooze time. This will define the duration of the "short sleep" phase. */
dwt_setsnoozetime(LPL_SHORT_SLEEP_SNOOZE_TIME);
/* Set preamble detect timeout. This will define the duration of the reception phases. */
dwt_setpreambledetecttimeout(LPL_RX_SNIFF_TIME);
/* Register RX call-back. */
dwt_setcallbacks(NULL, &rx_ok_cb, NULL, NULL);
/* Enable wanted interrupts (RX good frames only). */
dwt_setinterrupt(DWT_INT_RFCG, 1);
/* Enable low-power listening mode. */
dwt_setlowpowerlistening(1);
/* Go to sleep to trigger low-power listening mode. */
dwt_entersleep();
/* Loop forever receiving frames. */
while (1)
{
uint16 wus_end_frame_nb;
uint32 wus_end_time_ms;
/* Wait for a frame to be received.
* The user should look at the "rx_ok_cb" function below to see the next piece of RX handling before reading on through the rest of the main
* line code here. */
while (!rx_frame)
{ };
/* Configure DW1000 for next sleep phases so we can go to DEEPSLEEP and wake with SPI CS wake-up. */
dwt_configuresleep(DWT_PRESRV_SLEEP | DWT_CONFIG, DWT_WAKE_CS | DWT_SLP_EN);
/* Read received frame's countdown to the end of the wake-up sequence. */
wus_end_frame_nb = (rx_buffer << 8) + rx_buffer;
wus_end_time_ms = (wus_end_frame_nb * WUS_FRAME_TIME_US) / 1000;
/* Check that the wake-up sequence is destined to this application. */
if ((rx_buffer == 'R') && (rx_buffer == 'X'))
{
/* TESTING BREAKPOINT LOCATION #1 */
/* Put the DW1000 to sleep. */
dwt_entersleep();
/* Wait for the end of the wake-up sequence. */
sleep_ms(wus_end_time_ms);
/* Wake DW1000 up. See NOTE 7 below. */
dwt_spicswakeup(dummy_buffer, DUMMY_BUFFER_LEN);
/* Write interaction message data to DW1000 and prepare transmission. See NOTE 11 below. */
dwt_writetxdata(sizeof(interaction_msg), interaction_msg, 0); /* Zero offset in TX buffer. */
dwt_writetxfctrl(sizeof(interaction_msg), 0, 0); /* Zero offset in TX buffer, no ranging. */
/* Start transmission. */
dwt_starttx(DWT_START_TX_IMMEDIATE);
/* Poll DW1000 until TX frame sent event set. See NOTE 12 below.
* STATUS register is 5 bytes long but we are not interested in the high byte here, so we read a more manageable 32-bits with this API
* call. */
while (!(dwt_read32bitreg(SYS_STATUS_ID) & SYS_STATUS_TXFRS))
{ };
/* Clear TX frame sent event. */
dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_TXFRS);
/* Increment the frame sequence number (modulo 256). */
interaction_msg++;
}
else
{
/* TESTING BREAKPOINT LOCATION #2 */
/* Compute the time until the end of the interaction period (after end of the wake-up sequence). */
uint32 sleep_time_ms = wus_end_time_ms + INTERACTION_PERIOD_MAX_TIME_MS;
/* Put the DW1000 to sleep. */
dwt_entersleep();
/* Wait for the end of the interaction period. */
sleep_ms(sleep_time_ms);
/* Wake DW1000 up. See NOTE 7 below. */
dwt_spicswakeup(dummy_buffer, DUMMY_BUFFER_LEN);
}
/* Go back to low-power listening.
* Sleep mode must be reconfigured to allow low-power listening to operate properly as it has been modified earlier. */
dwt_configuresleep(DWT_PRESRV_SLEEP | DWT_CONFIG | DWT_RX_EN, DWT_WAKE_SLPCNT | DWT_SLP_EN);
dwt_setlowpowerlistening(1);
dwt_entersleep();
rx_frame = 0;
};
}
官方的例程如果收到正确得FCG 会进入到中断服务函数 static void rx_ok_cb(const dwt_cb_data_t *cb_data)
程序如下
/*! ------------------------------------------------------------------------------------------------------------------
* @fn rx_ok_callback()
*
* @brief Call-back to process RX good frames events
*
* @paramcb_datacall-back data
*
* @returnnone
*/
static void rx_ok_cb(const dwt_cb_data_t *cb_data)
{
if (cb_data->datalength == WUS_FRAME_LEN)
{
/* A frame of correct length to be a wake-up message has been received, copy it to our local buffer. */
dwt_readrxdata(rx_buffer, cb_data->datalength, 0);
/* Validate the frame is addressed to us from the expected sender and has the encoding of one of the wake-up sequence messages we expect.
* Then signal the arrival of the wake-up message to the background main loop by setting the rx_frame event flag. */
if ((rx_buffer == 0xDE) && (rx_buffer == 0xCA)
&& (rx_buffer == 'T') && (rx_buffer == 'X')
&& (rx_buffer == 0xE0))
{
rx_frame = 1;
}
}
/* If the frame is not from the expected wake-up sequence, go back to low-power listening. */
if (!rx_frame)
{
dwt_setlowpowerlistening(1); /* No need to reconfigure sleep mode here as it has not been modified since wake-up. */
dwt_entersleep();
non_wus_frame_rx_nb++;
}
}
现在我的问题是我将程序移植到我的代码里 不能进入到rx_ok_callback()中断内 以下是我设置的相关的代码
reset_DW1000(); /* RSTn低电平一段时间 */
//if (dwt_initialise(DWT_LOADNONE) == DWT_ERROR)
if (dwt_initialise(DWT_LOADUCODE) == DWT_ERROR)
{
Display_8x16_ASCII_Str("INIT FAILED",2,0);
while (1)
;
}
//设置发送功率
dwt_write32bitreg(TX_POWER_ID,0x3e3e3e3e);
status_reg = dwt_read32bitreg(TX_POWER_ID);
if(status_reg != 0x3e3e3e3e)
{
dwt_write32bitreg(TX_POWER_ID,0x3e3e3e3e);
}
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;
if (HAL_SPI_Init(&hspi1) != HAL_OK)
{
Error_Handler();
}
dwt_configure(&config_idle);
/* Apply default antenna delay value. See NOTE 1 below. */
dwt_setrxantennadelay(RX_ANT_DLY);
dwt_settxantennadelay(Station_Ant_Dly);
dwt_setrxaftertxdelay(POLL_TX_TO_RESP_RX_DLY_UUS);
dwt_setrxtimeout(RESP_RX_TIMEOUT_UUS);
// dwt_setpreambledetecttimeout(PRE_TIMEOUT);
// UWB_Message_Config();
dwt_setlnapamode(1, 1);
/* Calibrate and configure sleep count. This has to be done with DW1000 clocks set to crystal speed.
* This will define the duration of the "long sleep" phase. */
spi_set_rate_low();
lp_osc_freq = (XTAL_FREQ_HZ / 2) / dwt_calibratesleepcnt();
sleep_cnt = ((LONG_SLEEP_TIME_MS * lp_osc_freq) / 1000) >> 12;
dwt_configuresleepcnt(sleep_cnt);
spi_set_rate_high();
/* Configure sleep mode to allow low-power listening to operate properly. */
dwt_configuresleep(DWT_PRESRV_SLEEP | DWT_CONFIG | DWT_RX_EN, DWT_WAKE_SLPCNT | DWT_SLP_EN);
/* Set snooze time. This will define the duration of the "short sleep" phase. */
dwt_setsnoozetime(LPL_SHORT_SLEEP_SNOOZE_TIME);
/* Set preamble detect timeout. This will define the duration of the reception phases. */
dwt_setpreambledetecttimeout(LPL_RX_SNIFF_TIME);
/* Register RX call-back. */
dwt_setcallbacks(NULL, &rx_ok_cb, NULL, NULL);
/* Enable wanted interrupts (RX good frames only). */
dwt_setinterrupt(DWT_INT_RFCG, 1);
/* Enable low-power listening mode. */
dwt_setlowpowerlistening(1);
/* Go to sleep to trigger low-power listening mode. */
dwt_entersleep();
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
uint16 wus_end_frame_nb;
uint32 wus_end_time_ms;
while (!rx_frame)
{ };
dwt_configuresleep(DWT_PRESRV_SLEEP | DWT_CONFIG, DWT_WAKE_CS | DWT_SLP_EN);
} 有人对LPL模式比较了解么?是我哪里参数设置的错误了么? 测试的程序代码
链接:https://pan.baidu.com/s/1EoVsvn9jIQBiYpLGhvcToA
提取码:1234 Nero.qi 发表于 2022-3-18 10:22
测试的程序代码
链接:https://pan.baidu.com/s/1EoVsvn9jIQBiYpLGhvcToA
官方程序实在难懂不想看,你联系客服,提供订单号,要一份 我们自研带中断的程序吧
目前所有版型,均有支持中断的代码。
在我们的板子上调用官方api实现你的功能
页:
[1]