CC2541,请问 在工程 选项 中 使能 串口后 HAL_UART=TRUE ,怎么在 代码中关闭串口 ,从而 进入低功耗?
协议栈版本:ble_sdk_1.4.2.2,
1、请问 在工程 选项 中 使能 串口后 HAL_UART=TRUE ,怎么在 代码中关闭串口 ,从而 进入低功耗?
2、请问在进入PM2状态之前,需要先 初始化串口接收引脚RX为外部中断,并在中断服务函数中,关闭低功耗模式,启动32M 晶振,等待32M晶振稳定,初始化串口,从而使用串口,关闭 低功耗 使用 那个 API ,启动和等待32M 晶振稳定 使用哪个API?
2017年8月28日10:27:11
可以用uart_close关闭串口
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=FALSE
HAL_KEY=FALSE
HAL_UART=TRUE
2、这样设置后,无法进入低功耗,需要更改一下几个宏定义
在 工程里 NPI_UART_FC 宏定义 为 FALSE ,DMA_PM 宏定义为0 ,然后正常初始化串口即可 使用串口了,协议栈版本:ble_sdk_
1.4.2.2
#if !defined( NPI_UART_FC )
#define NPI_UART_FC FALSE
#endif // !NPI_UART_FC
#if !defined( DMA_PM )
#if defined POWER_SAVING
#define DMA_PM 0
#else
#define DMA_PM 0
#endif // POWER_SAVING
#endif // !DMA_PM
3、这样只能 在 BLE 唤醒期间 使用 串口收发,开启 低功耗 的 时候,电脑 发给 BLE ,没有回复 ,,关闭低功耗的 时候 电脑 发数据给 BLE,BLE能回复 相同的数据 。下面是我 的串口 测试方案。
4、现在 问题是 怎么 利用串口 唤醒 BLE?
这样 能保持 低功耗 ,又能 使用串口 ,低功耗电流 是 5uA,可能在广播 的 瞬间 跳到100uA, 我设置的 定时广播的时间是 500mS
// What is the advertising interval when device is discoverable (units of 625us, 160=100ms)
#define DEFAULT_ADVERTISING_INTERVAL 800
OSAL层的定时任务 是 15S 执行一次 ,
// How often to perform periodic event
#define SBP_PERIODIC_EVT_PERIOD 15000
在 定时任务中我 增加了 一下 几个代码 ,来打开和关闭低功耗 ,用于测试串口
/*********************************************************************
* @fn performPeriodicTask
*
* @brief Perform a periodic application task. This function gets
* called every five seconds as a result of the SBP_PERIODIC_EVT
* OSAL event. In this example, the value of the third
* characteristic in the SimpleGATTProfile service is retrieved
* from the profile, and then copied into the value of the
* the fourth characteristic.
*
* @param none
*
* @return none
*/
static void performPeriodicTask( void )
{
uint8 valueToCopy;
uint8 stat;
static uint8 pwrmgrFlag =0;
// Call to retrieve the value of the third characteristic in the profile
stat = SimpleProfile_GetParameter( SIMPLEPROFILE_CHAR3, &valueToCopy);
if( pwrmgrFlag == 0 )
{
pwrmgrFlag =1;
printf("PWRMGR_ALWAYS_ON.\r\n");
osal_pwrmgr_device( PWRMGR_ALWAYS_ON );
}
else if( pwrmgrFlag == 1 )
{
pwrmgrFlag =0;
printf("PWRMGR_BATTERY.\r\n");
osal_pwrmgr_device( PWRMGR_BATTERY );
}
if( stat == SUCCESS )
{
/*
* Call to set that value of the fourth characteristic in the profile. Note
* that if notifications of the fourth characteristic have been enabled by
* a GATT client device, then a notification will be sent every time this
* function is called.
*/
SimpleProfile_SetParameter( SIMPLEPROFILE_CHAR4, sizeof(uint8), &valueToCopy);
}
}
第三步的 截图 就是这么来的 !
请问 TI 同事, 外部中断唤醒 后,怎么 退出低功耗 ,用哪个 API?
应该这么问 就是, 进入 外部中断 服务函数中,调用那个API 退出 PM2或者 PM3,进入正常工作状态?
还有就是 你 关闭串口 这个 API 我 没有 在 协议栈中 搜索到!
还要 就是 我 休眠 唤醒后 ,调用 CLEAR_SLEEP_MODE(); 退出 休眠 ,但是 怎么 启用 32M 的 主 晶振,启用后 要做哪些操作?
外部中断 唤醒 ,我用 着 没问题 ,唤醒过程 5mS,函数如下
void initRxExterInterrupt(void)
{
P0SEL &= ~0x06; //P0.5 RX 设置为通用I/O口
P0DIR &= ~0x06; //P0.5 RX 设置为输入
P0IFG &= ~0x06; //P0.5 RX 中断状态标志位清0
PICTL |= 0x00; //P0端口下降沿触发
P0IEN |= 0x06; //P0.5 RX 中断使能
IEN1 |= 0x20; //端口P0中断使能
EA = 1; //开总中断
U0CSR &= ~0x40; //关闭 串口 接收使能
}
void initRxUart(void)
{
IEN1 &= ~0x20; //端口P0中断关闭
}
#pragma vector = P0INT_VECTOR
__interrupt void P0_ISR(void)
{
HAL_ENTER_ISR();
if(0x06 & P0IFG) //判断 是否是 P0.5 RX 引脚 中断
{
initRxUart();
NPI_InitTransport(NpiSerialCallback);
osal_start_timerEx( simpleBLEPeripheral_TaskID, SBP_PERIODIC_EVT, SBP_PERIODIC_EVT_PERIOD );
osal_pwrmgr_device( PWRMGR_ALWAYS_ON ); // 不在进入低功耗
CLEAR_SLEEP_MODE();//退出 休眠 ,进入工作状态
HAL_BOARD_INIT();//切换到外部32M 晶振 并且 等待稳定
printf("interrupt void P0_ISR(void).\r\n");
}
P0IFG = 0; //清中断标志
P0IF = 0; //清中断标志,IRCON[5],P0口中断
HAL_EXIT_ISR();
}
串口 发送一个 字符 1 即 0x31后 ,5ms 后 收到 中断里打印 的 数据
外部中断 唤醒 ,我用 着 没问题 ,唤醒过程 5mS,函数如下
void initRxExterInterrupt(void)
{
P0SEL &= ~0x06; //P0.5 RX 设置为通用I/O口
P0DIR &= ~0x06; //P0.5 RX 设置为输入
P0IFG &= ~0x06; //P0.5 RX 中断状态标志位清0
PICTL |= 0x00; //P0端口下降沿触发
P0IEN |= 0x06; //P0.5 RX 中断使能
IEN1 |= 0x20; //端口P0中断使能
EA = 1; //开总中断
U0CSR &= ~0x40; //关闭 串口 接收使能
}
void initRxUart(void)
{
IEN1 &= ~0x20; //端口P0中断关闭
}
#pragma vector = P0INT_VECTOR
__interrupt void P0_ISR(void)
{
HAL_ENTER_ISR();
if(0x06 & P0IFG) //判断 是否是 P0.5 RX 引脚 中断
{
initRxUart();
NPI_InitTransport(NpiSerialCallback);
osal_start_timerEx( simpleBLEPeripheral_TaskID, SBP_PERIODIC_EVT, SBP_PERIODIC_EVT_PERIOD );
osal_pwrmgr_device( PWRMGR_ALWAYS_ON ); // 不在进入低功耗
CLEAR_SLEEP_MODE();//退出 休眠 ,进入工作状态
HAL_BOARD_INIT();//切换到外部32M 晶振 并且 等待稳定
printf("interrupt void P0_ISR(void).\r\n");
}
P0IFG = 0; //清中断标志
P0IF = 0; //清中断标志,IRCON[5],P0口中断
HAL_EXIT_ISR();
}
串口 发送一个 字符 1 即 0x31后 ,5ms 后 收到 中断里打印 的 数据
这么 唤醒 后 , 还是不能 使用 串口 ,有时候 会 乱码, 必须 在 这个中断中 初始化 32M晶振 ,初始化 串口 才可以,但是不知道怎么做?
2017年8月31日09:23:47 ,分享我 的低功耗 下使用串口的 方式
协议栈版本: 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
#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(“wake up.\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 进入低功耗的开关