微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 无线和射频 > TI蓝牙设计交流 > CC2541,请问 在工程 选项 中 使能 串口后 HAL_UART=TRUE ,怎么在 代码中关闭串口 ,从而 进入低功耗?

CC2541,请问 在工程 选项 中 使能 串口后 HAL_UART=TRUE ,怎么在 代码中关闭串口 ,从而 进入低功耗?

时间:10-02 整理:3721RD 点击:

协议栈版本: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 进入低功耗的开关

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top