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

xiaoxiao2021-02-28  102

一、简介

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

二、实验平台

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

三、版权声明

声明:转载请注明出处。 原文地址:http://blog.csdn.net/liwei16611/article/category/7000460

四、实验前提

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;

 

转载请注明原文地址: https://www.6miu.com/read-68957.html

最新回复(0)