【IoT】TI BLE CC2541 串口控制蓝牙详解

简介: CC254x驱动:串口控制蓝牙

一、简介

本文以SimpleBLECentral工程为例,介绍串口控制蓝牙。
过程:
扫描从机 - 根据从机号连接指定从机 - 获取RSSI值(信号强度) - 向char1写入特征值 - 断开连接

二、实验平台

协议栈版本:BLE-CC254x-1.3.2
编译软件: IAR 8.20.2
硬件平台: Smart RF开发板(主芯片CC2541)、USB Dongle
PC: 友善串口调试助手

三、版权声明

声明:转载请注明出处。

四、实验前提

1、在进行本文步骤前,请先阅读以下博文:
暂无

五、基础知识

1、为什么要通过串口控制蓝牙?
答:
可以为后续实现串口蓝牙透传做准备,比较适合低成本低功耗的短距离小数据传输;
封装AT指令,通过串口来控制蓝牙的相关操作。

六、实验步骤

1、在串口回调函数内添加AT指令处理(SerialApp.c)

// uart接收回调函数,当我们通过PC串口调试助手向开发板发送数据时,会调用该函数来接收
void sbpSerialAppCallback(uint8 port, uint8 event)
{
uint8 pktBuffer[SBP_UART_RX_BUF_SIZE];
(void)event;
//返回可读的字节
if ( (numBytes = Hal_UART_RxBufLen(port)) > 0 ){
//读取全部有效的数据,这里可以一个一个读取,以解析特定的命令
(void)HalUARTRead (port, pktBuffer, numBytes);
// AT指令处理函数

    CommondHandle(pktBuffer, numBytes);

}

}

2、AT指令处理函数CommondHandle:验证串口(simpleBLECentral.c)

使用串口调试助手发送 AT

AT指令处理函数返回OK给PC:

// AT占用两个字节
if(length<2)

return ;

if(pBuffer[0]!='A' && pBuffer[1]!='T')

return ;

if(length <=4) {

SerialPrintString("OK\r\n");
return ;

}

注:指令

AT 串口测试,返回OK
AT+ROLE? 获取当前角色
AT+SCAN 扫描从机
AT+CON[x] 连接指定的从机,x为搜索到的从机序号
AT+RSSI 获取rssi值
AT+DISCON 断开连接
AT+WRITE[0xXX] 向char1写入特征值

3、AT指令处理函数CommondHandle:BLE主机设备初始化完成(simpleBLECentral.c 的 simpleBLECentralEventCB 函数)

注册回调函数:

// GAP Role Callbacks
static const gapCentralRoleCB_t simpleBLERoleCB =
{

simpleBLECentralRssiCB,       // RSSI callback
simpleBLECentralEventCB       // Event callback

};

初始化成功会直接调用回调函数的 GAP_DEVICE_INIT_DONE_EVENT 事件:

case GAP_DEVICE_INIT_DONE_EVENT:
{

    SerialPrintString("BLE Central: ");

// 将 BLE 主机设备地址通过串口发送给PC

    SerialPrintString((uint8*)bdAddr2Str( pEvent->initDone.devAddr ));SerialPrintString("\r\n");

}
break;

4、AT指令处理函数CommondHandle:BLE主机扫描从机(simpleBLECentral.c 的 CommondHandle 和 simpleBLECentralEventCB 函数)

1) 接收PC端AT指令:AT+SCAN

if(length>=7 && str_cmp(pBuffer+3,"SCAN",4) == 0)
{

  simpleBLEScanning = TRUE;
  simpleBLEScanRes = 0;
  
  SerialPrintString("Discovering...\r\n");
  

// 开始扫描从机设备 - 需要开启蓝牙从机设备

  GAPCentralRole_StartDiscovery( DEFAULT_DISCOVERY_MODE,
                                 DEFAULT_DISCOVERY_ACTIVE_SCAN,
                                 DEFAULT_DISCOVERY_WHITE_LIST ); 
  return ;

}

2) 扫描到从机,调用回调函数处理

case GAP_DEVICE_DISCOVERY_EVENT:
{

simpleBLEScanning = FALSE;

// if not filtering device discovery results based on service UUID
if ( DEFAULT_DEV_DISC_BY_SVC_UUID == FALSE )
{
  // Copy results
  simpleBLEScanRes = pEvent->discCmpl.numDevs;
  osal_memcpy( simpleBLEDevList, pEvent->discCmpl.pDevList,
               (sizeof( gapDevRec_t ) * pEvent->discCmpl.numDevs) );
}

// 将扫描的从机个数通过串口输出到PC

SerialPrintValue("Devices Found", simpleBLEScanRes, 10);
SerialPrintString("\r\n");

if ( simpleBLEScanRes > 0 )
{
  SerialPrintString("<- To Select\r\n");
}

// initialize scan index to last device
simpleBLEScanIdx = simpleBLEScanRes; 

}
break;

5、AT指令处理函数CommondHandle:BLE连接扫描到的从机(simpleBLECentral.c 的 CommondHandle 和 simpleBLECentralEventCB 函数)

1) 接收PC端AT指令:AT+CON1 1表示从机序列号,即连接从机1

if(length>=7 && str_cmp(pBuffer+3,"CON",3) == 0)
{

  // 连接参数CON后面跟的数值大于等于1,意思是连接第一个从机 第二个从机等
  uint8 tmp=pBuffer[5]-48-1;
  if ( simpleBLEState == BLE_STATE_IDLE ){
    // if there is a scan result
    if ( simpleBLEScanRes > 0 )
    {
      uint8 addrType;
      uint8 *peerAddr;
      // connect to current device in scan result
      peerAddr = simpleBLEDevList[tmp].addr;
      addrType = simpleBLEDevList[tmp].addrType;
    
      simpleBLEState = BLE_STATE_CONNECTING;
      

// 开始建立连接

      GAPCentralRole_EstablishLink( DEFAULT_LINK_HIGH_DUTY_CYCLE,
                                    DEFAULT_LINK_WHITE_LIST,
                                    addrType, peerAddr );

      SerialPrintString("Connecting:");
      SerialPrintString((uint8*)bdAddr2Str( peerAddr));SerialPrintString("\r\n");
    }
  }
  return ;

}

2) 连接成功,调用回调函数处理

case GAP_LINK_ESTABLISHED_EVENT:
{

if ( pEvent->gap.hdr.status == SUCCESS )
{          
  simpleBLEState = BLE_STATE_CONNECTED;
  simpleBLEConnHandle = pEvent->linkCmpl.connectionHandle;
  simpleBLEProcedureInProgress = TRUE;    

  // If service discovery not performed initiate service discovery
  if ( simpleBLECharHdl == 0 )
  {
    osal_start_timerEx( simpleBLETaskId, START_DISCOVERY_EVT, DEFAULT_SVC_DISCOVERY_DELAY );
  }
            
  SerialPrintString("Connected: ");
  SerialPrintString((uint8*) bdAddr2Str( pEvent->linkCmpl.devAddr ));SerialPrintString("\r\n");   
}
else
{
  simpleBLEState = BLE_STATE_IDLE;
  simpleBLEConnHandle = GAP_CONNHANDLE_INIT;
  simpleBLERssi = FALSE;
  simpleBLEDiscState = BLE_DISC_STATE_IDLE;
  
  SerialPrintString("Connect Failed: ");
  SerialPrintValue("Reason:",  pEvent->gap.hdr.status,10);
}

}

6、AT指令处理函数CommondHandle:BLE获取信号强度RSSI的值(simpleBLECentral.c 的 CommondHandle 和 simpleBLECentralEventCB 函数)

1) 接收PC端AT指令:AT+RSSI

if(length>=7 && str_cmp(pBuffer+3,"RSSI",4) == 0)
{

// Start or cancel RSSI polling
if ( simpleBLEState == BLE_STATE_CONNECTED )
{
  if ( !simpleBLERssi )
  {
    simpleBLERssi = TRUE;

// 开启获取RSSI值

    GAPCentralRole_StartRssi( simpleBLEConnHandle, DEFAULT_RSSI_PERIOD );
  }
  else
  {
    simpleBLERssi = FALSE;
    GAPCentralRole_CancelRssi( simpleBLEConnHandle );
    
    LCD_WRITE_STRING( "RSSI Cancelled", HAL_LCD_LINE_1 );
    SerialPrintString("RSSI Cancelled\r\n");
  }
}
return ;

}

2) RSSI获取成功,调用回调函数处理

static void simpleBLECentralRssiCB( uint16 connHandle, int8 rssi )
{

// RSSI 值通过串口发送给 PC
SerialPrintValue("RSSI -dB:", (uint8) (-rssi), 10);SerialPrintString("\r\n");

}

7、AT指令处理函数CommondHandle:BLE主机向char1写入特征值(simpleBLECentral.c 的 CommondHandle 和 simpleBLECentralEventCB 函数)

1) 接收PC端AT指令:AT+WRITE0x5A

//AT+WRITE0xXX
if(length>=10 && str_cmp(pBuffer+3,"WRITE0x",7) == 0)
{

//uint8 val=0;
simpleBLECharVal=str2hex(pBuffer+10);
if ( simpleBLEState == BLE_STATE_CONNECTED &&
          simpleBLECharHdl != 0 &&
          simpleBLEProcedureInProgress == FALSE )
{
  uint8 status;

  // Do a write
  attWriteReq_t req;
  
  req.handle = simpleBLECharHdl;
  req.len = 1;
  req.value[0] = simpleBLECharVal;
  req.sig = 0;
  req.cmd = 0;

// 写入特征值

  status = GATT_WriteCharValue( simpleBLEConnHandle, &req, simpleBLETaskId );         
  
  if ( status == SUCCESS )
  {
    simpleBLEProcedureInProgress = TRUE;
  }
} 
return ;

}

8、AT指令处理函数CommondHandle:BLE主机断开连接(simpleBLECentral.c 的 CommondHandle 和 simpleBLECentralEventCB 函数)

1) 接收PC端AT指令:AT+DISCON

if(length>=10 && str_cmp(pBuffer+3,"DISCON",6) == 0)
{

if ( simpleBLEState == BLE_STATE_CONNECTING ||
          simpleBLEState == BLE_STATE_CONNECTED )
{
  // disconnect
  simpleBLEState = BLE_STATE_DISCONNECTING;
  
  // 断开连接
  gStatus = GAPCentralRole_TerminateLink( simpleBLEConnHandle );
  
  SerialPrintString("Disconnecting\r\n");
}

}

2) 断开连接成功,调用回调函数处理

case GAP_LINK_TERMINATED_EVENT:
{

simpleBLEState = BLE_STATE_IDLE;
simpleBLEConnHandle = GAP_CONNHANDLE_INIT;
simpleBLERssi = FALSE;
simpleBLEDiscState = BLE_DISC_STATE_IDLE;
simpleBLECharHdl = 0;
simpleBLEProcedureInProgress = FALSE;
  
SerialPrintString("Disconnected: ");
SerialPrintValue("Reason:",  pEvent->linkTerminate.reason,10);

}
break;

卫朋

人人都是产品经理受邀专栏作家,CSDN 嵌入式领域新星创作者、资深技术博主。2020 年 8 月开始写产品相关内容,截至目前,人人都是产品经理单渠道阅读 56 万+,鸟哥笔记单渠道阅读200 万+,CSDN 单渠道阅读 210 万+,51CTO单渠道阅读 180 万+。

卫朋入围2021/2022年人人都是产品经理平台年度作者,光环国际学习社区首批原创者、知识合作伙伴,商业新知 2021 年度产品十佳创作者,腾讯调研云2022年达人榜第三名。

文章被人人都是产品经理、CSDN、华为云、运营派、产品壹佰、鸟哥笔记、光环国际、商业新知、腾讯调研云等头部垂直类媒体转载。文章见仁见智,各位看官可策略性选择对于自己有用的部分。

相关文章
|
存储 网络协议 物联网
Adobe XD CC 55.2.12.2 是一款非常专业的矢量图形规划软件Adobe XD 2023版本软件下载安装教程(内含所有版本)
Adobe XD CC 55.2.12.2 是一款非常专业的矢量图形规划软件,全新的桌面端UX原型工具,这是新一代网页与移动应用的UX设计工具。xd能够帮助设计者快速有效的设计图形、建立手机APP以及网站原型等等设计制作,支持设备的尺寸多样。集原型、设计和交互等功能于一体,从网站和移动应用程序到语音交互都可轻松实现,Adobe XD CC带来了响应调整大小、自动动画、语音原型、插件和应用程序集成等新功能,
Adobe Photoshop CC 2019下载中文永久安装和破解教程
Adobe Photoshop CC 2019下载中文永久安装和破解教程
50039 0
Animate CC 2019免费下载丨Adobe Animate CC 2019下载中文完整版永久安装教程
Adobe 提供了一整套可互相配合使用的动画应用程序,助您实现所有创意。使用 Animate CC 创建适用于游戏、应用程序和 Web 的交互式矢量动画。利用 Character Animator CC 将人物实时制成动画。
8444 0
AICC2019下载Adobe Illustrator CC 2019中文完整破解版免费下载与安装教程
AICC2019下载Adobe Illustrator CC 2019中文完整破解版免费下载与安装教程 在2018年10月15日,Adobe公司正式宣布Adobe Illustrator CC 2019更新之后,很多小伙伴都迫不及待的要下载使用,体验一下最新的功能,以及如何永久的使用它呢?那么接下来小编就带大家如何进行安装与永久使用的教程。
14273 0