社区导航

 

搜索
查看: 91|回复: 0

[资料分享] BLE协议栈UART调试指南

[复制链接]

6562

TA的帖子

19

TA的资源

纯净的硅(初级)

Rank: 4

发表于 2020-5-13 21:26 | 显示全部楼层 |阅读模式

UART在嵌入式软件开发中的重要性不言而喻;我之前有调通过TI BLE协议栈的串口,而且我记得当时有做过一个简单的文档记录,表明需要注意的地方。可遗憾的是换了个硬盘,源码也找不到,记录文档也丢了;直接导致我又花了好几个小时重新调试BLE协议栈的串口应用。废话不多说,赶紧记录要点。

首先贴出源码:SerialPortApp.h

/**************************************************************************************************
  Filename:       SiralPortApp.h
**************************************************************************************************/
#ifndef SiralPortApp_H
#define SiralPortApp_H

#include <stdio.h>
#include <string.h>
#include "hal_uart.h"

#define SPA_UART_PORT           HAL_UART_PORT_0
#define SPA_UART_FlowCtl        FALSE
#define SPA_UART_FC_THRESHOLD   48
#define SPA_UART_RX_BUF_SIZE    128
#define SPA_UART_TX_BUF_SIZE    128
#define SPA_UART_IDLE_TIMEOUT   6

void serialPortApp_Init( uint8 task_id );
//void serialPortAPP_PrintString(char* str);
void serialPortApp_Callback(uint8 port, uint8 event);

#endif

SerialPortApp.c

#include "SerialPortApp.h"

/*********************************************************************
 * @fn      serialPortApp_Init
 *
 * @brief   串口应用初始化
 *
 * @return  none
 */
void serialPortApp_Init( uint8 task_id )
{
  /*串口参数配置*/
  halUARTCfg_t  config;
  config.configured  = TRUE;
  config.baudRate    = HAL_UART_BR_115200;
  config.flowControl = SPA_UART_FlowCtl;
  config.flowControlThreshold = SPA_UART_FC_THRESHOLD;
  config.rx.maxBufSize = SPA_UART_RX_BUF_SIZE;
  config.tx.maxBufSize = SPA_UART_TX_BUF_SIZE;
  config.idleTimeout = SPA_UART_IDLE_TIMEOUT;
  config.intEnable = TRUE;
  config.callBackFunc = serialPortApp_Callback;//uart接收回调函数

  HalUARTOpen(SPA_UART_PORT, &config);//打开串口
}

/*********************************************************************
 * @fn      serialPortApp_Callback
 *
 * @brief   串口接收数据回调函数
 *
 * @return  none
 */
void serialPortApp_Callback(uint8 port, uint8 event)
{
  uint8 rxBuf[SPA_UART_RX_BUF_SIZE];

  while(Hal_UART_RxBufLen(port))//uart接收缓冲区有数据
  {
    HalUARTRead(port,rxBuf,1);
  }
}

/*********************************************************************
 * @fn      serialPortAPP_PrintString
 *
 * @brief   串口打印字符串
 *
 * @param   str 需要打印的字符串
 *
 * @return  none
 */
//void serialPortAPP_PrintString(char* str)
//{
//  HalUARTWrite(SPA_UART_PORT, (uint8*)str, strlen(str));
//}

/*********************************************************************
 * @fn      putchar
 *
 * @brief   将printf函数重定向至单片机串口
 *
 */
__near_func int putchar(int c)
{
  uint8 str[] = {c};   
  HalUARTWrite(SPA_UART_PORT, str, 1);
  return (c);
}

备注:上述代码在串口发送数据时,是成功的;数据接收部分还待调试!

UART应用代码完成后,接下来就是调用了。我在上次创建的BLE新应用IAR中创建BLE/Zigbee新项目中实现串口打印功能!

将文件添加如上述SerialPortAppPeripheral中后,只需要修改SiralPortAppPeripheral.c 三个地方就能实现UART输出应用:

1、#include “SerialPortApp.h”//添加串口应用头文件
2、在void SiralPortAppPeripheral_Init( uint8 task_id )
函数中初始化串口应用:

void SerialPortAppPeripheral_Init( uint8 task_id )
{
  SerialPortAppPeripheral_TaskID = task_id;

  //初始化串口应用
  serialPortApp_Init(SiralPortAppPeripheral_TaskID);

  // Setup the GAP
  VOID GAP_SetParamValue( TGAP_CONN_PAUSE_PERIPHERAL, DEFAULT_CONN_PAUSE_PERIPHERAL );

3、在应用事件处理函数中调用printf()打印输出:

uint16 SerialPortAppPeripheral_ProcessEvent( uint8 task_id, uint16 events )
{

  VOID task_id; // OSAL required parameter that isn't used in this function
  static int  cnt = 0;

  if ( events & SYS_EVENT_MSG )
  {
    uint8 *pMsg;

    if ( (pMsg = osal_msg_receive( SerialPortAppPeripheral_TaskID )) != NULL )
    {
      SerialPortAppPeripheral_ProcessOSALMsg( (osal_event_hdr_t *)pMsg );

      // Release the OSAL message
      VOID osal_msg_deallocate( pMsg );
    }

    // return unprocessed events
    return (events ^ SYS_EVENT_MSG);
  }

  if ( events & SBP_START_DEVICE_EVT )
  {
    // Start the Device
    VOID GAPRole_StartDevice( &SerialPortAppPeripheral_PeripheralCBs );

    // Start Bond Manager
    VOID GAPBondMgr_Register( &SerialPortAppPeripheral_BondMgrCBs );

    // Set timer for first periodic event
    osal_start_timerEx( SerialPortAppPeripheral_TaskID, SBP_PERIODIC_EVT, SBP_PERIODIC_EVT_PERIOD );

    return ( events ^ SBP_START_DEVICE_EVT );
  }

  if ( events & SBP_PERIODIC_EVT )
  {
    // Restart timer
    if ( SBP_PERIODIC_EVT_PERIOD )
    {
      osal_start_timerEx( SerialPortAppPeripheral_TaskID, SBP_PERIODIC_EVT, SBP_PERIODIC_EVT_PERIOD );
    }

    /*
      串口成功打印!!
      需要注意:
      1、在Options预处理器中添加 HAL_UART=TRUE
      2、将Options预处理器中原有的POWER_SAVING改为xPOWER_SAVING
      (如果不关闭该选项串口不能使用!!!)
    */
    //serialPortAPP_PrintString("start periodic event ...\r\n");
    printf("periodic times: %d\n",cnt++);

    // Perform periodic application task
    performPeriodicTask();

    return (events ^ SBP_PERIODIC_EVT);
  }

  // Discard unknown events
  return 0;
}

注意:
1、在Options预处理器中添加 HAL_UART=TRUE
2、将Options预处理器中原有的POWER_SAVING改为xPOWER_SAVING(如果不关闭该选项串口不能使用!!!)

这里还有一点比较有意思:在IAR中实现printf()函数重定向至单片机的UART。只需要理解

__near_func int putchar(int c)
{
  uint8 str[] = {c};   
  HalUARTWrite(SPA_UART_PORT, str, 1);
  return (c);
}

 

此帖出自无线连接论坛


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

关闭

站长推荐上一条 1/8 下一条

  • 论坛活动 E手掌握

    扫码关注
    EEWORLD 官方微信

  • EE福利  唾手可得

    扫码关注
    EE福利 唾手可得

词云| Archiver|手机版|小黑屋|电子工程世界 ( 京ICP证 060456 )

GMT+8, 2020-7-15 19:40 , Processed in 0.091620 second(s), 20 queries , Gzip On, MemCache On.

快速回复 返回顶部 返回列表