CC2540 低功耗 POWER_SAVING 模式 下 串口 0 的使用
低功耗 模式 下 使用 串口 , 因為 PM2 或者 PM3 狀態下 32M晶振 是不工作 的,根據手冊得知沒有32M晶振, 串口是不能工作的,但是可以使用 外部中斷,因此,我把 串口的接收引腳設置為外部中斷,這樣 來喚醒BLE。
這樣就牽扯到 串口 和 外設中斷 的 來回切換 ,具體操作方法如下:
協議棧版本: ble_sdk_1.4.2.2 simpleBLEPeripheral
1、 工程 配置 如下
INT_HEAP_LEN=3072
HALNODEBUG
OSAL_CBTIMER_NUM_TASKS=1
HAL_AES_DMA=TRUE
HAL_DMA=TRUE
POWER_SAVING
xPLUS_BROADCASTER
HAL_LCD=FALSE
HAL_LED=TRUE
HAL_KEY=FALSE
HAL_UART=TRUE
2、 在npi.h代碼 中 做 如下修改
#if !defined( NPI_UART_FC )
#define NPI_UART_FC FALSE//所長,2017年8月31日09:38:28,關閉流控
#endif // !NPI_UART_FC
3、 在_hal_uart_dma.c 文件 中 修改 DMA_PM 為0
#if !defined( DMA_PM )
#if defined POWER_SAVING
#define DMA_PM 0
#else
#define DMA_PM 0
#endif // POWER_SAVING
#endif // !DMA_PM
4、 ble休眠進入之前,使用串口的RX引腳外部中斷來喚醒ble,配置如下:
(我 放在 SimpleBLEPeripheral_Init 函數中,串口初始化函數後面)
void initRxExterInterrupt(void)
{
P0SEL &= ~(0x08); //P0.3 TX 設置為通用I/O口
P0DIR &= ~(0x08); //P0.3 TX 設置為輸入
P0SEL &= ~(0x04); //P0.2 設置為通用I/O口
P0DIR &= ~(0x04); //P0.2 設置為輸入
P0IFG &= ~(0x04); //P0.2 設置為輸入
PICTL |= 0; //P0端口下降沿觸發
P0IEN |= (0x04); //P0.2 RX 中斷使能
IEN1 |= 0x20; //端口P0中斷使能
EA = 1; //開總中斷
U0CSR &= ~0x40; //關閉 串口 接收使能
}
5、 在外部中斷服務函數中,要 關閉RX 引腳的外部中斷,函數如下:
void initRxUart(void)
{
IEN1 &= ~0x20; //端口P0中斷關閉
P0SEL |= (0x08); //P0.3 TX 設置為外設串口TX功能
P0DIR |= (0x08); //P0.3 TX 設置為輸出
}
6、 外部 中斷服務函數如下
#pragma vector = P0INT_VECTOR
__interrupt void P0_ISR(void)
{
HAL_ENTER_ISR();
if(0x04 & P0IFG) //判斷 是否是 P0.2 RX 引腳 中斷
{
initRxUart();
//喚醒後 執行 定時任務 ,可以 這個任務中 使用 函數關閉 低功耗
osal_start_timerEx( simpleBLEPeripheral_TaskID, SBP_PERIODIC_EVT, 5 );
CLEAR_SLEEP_MODE();//退出 休眠 ,進入工作狀態
HAL_BOARD_INIT();//切換到外部32M 晶振 並且 等待穩定
}
P0IFG = 0; //清中斷標誌
P0IF = 0; //清中斷標誌,IRCON[5],P0口中斷
HAL_EXIT_ISR();
}
7、 在 第六步 啟動 的 定時任務中,static void performPeriodicTask( void )中
使用 下面 兩句代碼 重新初始化串口,和關閉低功耗
NPI_InitTransport(NpiSerialCallback); //重新初始化串口
osal_pwrmgr_device( PWRMGR_ALWAYS_ON ); // 不在進入低功耗
printf(“Wakeup OK.\r\n”);
8、 重新進入低功耗 的 方法 :
// makes sure LEDs are OFF
HalLedSet( (HAL_LED_1 | HAL_LED_2), HAL_LED_MODE_OFF );
HCI_EXT_ClkDivOnHaltCmd( HCI_EXT_ENABLE_CLK_DIVIDE_ON_HALT );
HCI_EXT_HaltDuringRfCmd( HCI_EXT_HALT_DURING_RF_ENABLE );
//關閉 定時事件,降低功耗
osal_stop_timerEx( simpleBLEPeripheral_TaskID, SBP_PERIODIC_EVT );
initRxExterInterrupt(); //重新 初始化 rx 為 外部中斷
osal_pwrmgr_device( PWRMGR_BATTERY );//打開 OSAL 進入低功耗的開關
9、經過 測試 喚醒 過程需要 40mS 的時間。
2017年8月31日11:11:26,所長,記錄
CC2540 低功耗 POWER_SAVING 模式 下 串口 0 的使用