【IoT】TI BLE CC2541 串口控制蓝牙详解
一、简介
本文以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;
【IoT】TI BLE CC2541 串口控制蓝牙详解相关推荐
- 【BLE】OTA基础知识详解
[BLE]OTA基础知识详解 一. 概念 1. 缩写 BIM Boot Image Manager , the software bootloader CRC cyclic redundancy ch ...
- oracle控制文件都一样么,Oracle控制文件详解
一.Oracle控制文件 为二进制文件,初始化大小由CREATEDATABASE指定,可以使用RMAN备份 记录了当前数据库的结构信息,同时也包含数据文件及日志文件的信息以及相关的状态,归档信息等等 ...
- python的turtle怎么设置rgb颜色_Python : turtle色彩控制实例详解
? 1 turtle.pencolor(* args ) 返回或设置pencolor. 允许四种输入格式: ? 1 pencolor() 将当前的pencolor返回为颜色规范字符串或元组(参见示例) ...
- 远程访问及控制(详解)——SSH远程管理及TCP Wrappers 访问控制
远程访问及控制(详解)--SSH远程管理及TCP Wrappers 访问控制 一.SSH远程管理 1.定义 2.优点 3.客户端与服务端 4.SSH服务的开启.端口号和配置文件 二.配置 OpenSS ...
- ThinkPHP的RBAC(基于角色权限控制)详解
ThinkPHP的RBAC(基于角色权限控制)详解 一.什么是RBAC 基于角色的访问控制(Role-Based Access Control)作为传统访问控制(自主访问,强制访问)的有前景的代替受到 ...
- M1卡区块控制位详解
M1卡区块控制位详解 Mifare 1S50/Mifare 1S70 每个扇区的密码和存取控制都是独立的,可以根据实际需要设定各自的密码及存取 控制.存取控制为4个字节,共32位,扇区中的每个块(包括 ...
- 单片机控制两个步进电机画圆_基于单片机的步进电机转速控制设计详解(附程序)...
步进电机是将电脉冲信号转变为角位移或线位移的开环控制元件.在非超载的情况下,电机的转速.停止的位置只取决于脉冲信号的频率和脉冲数,而不受负载变化的影响,即给电机加一个脉冲信号,电机则转过一个步距角.这 ...
- 《前端》权限链接--vue前端权限控制方案详解附demo_feiyu_may的博客-CSDN博客_vue 前端权限
前端权限控制 - 潘正 - 博客园 https://www.cnblogs.com/guchengnan/p/11800947.html vue前端权限控制方案详解附demo_feiyu_may的博 ...
- 增程式发动机仿真控制逻辑详解(一)
本文转载在我的微信公众号:古德曼汽车工业. 希望关注本专栏的朋友,也能一并关注微信公众号. 原文地址:增程式发动机仿真控制逻辑详解(一) 1.前言 本订阅号的一个特色就是,你们都猜不到[思想]下一次更 ...
最新文章
- 发现一个有意思的博主(科研工作者)
- git-svn:通过git来管理svn代码
- P1198 [JSOI2008]最大数
- linux用unzip解压.zip文件失败解决方案
- token和session的区别
- mysql 设置事物自动提交_mysql事务自动提交的问题
- Linux C文件编译
- #考研#计算机文化知识1(局域网及网络互联)
- MAC修改保存bash_profile文件
- 锁表 for update
- python中字符编码:coding utf-8, unicde, defaultencoding, UnicodeDecodeError, UnicodeEncodeError
- 2012-2013QS计算机专业世界大学排名
- WZ-S甲醛传感器使用说明代码应用案例笔记
- 巴菲特指标:估值过高
- 永磁同步电机的直接转矩控制(三)一一一滑模控制器改进DTC
- 树莓派pico从零开始的入门(一)
- 小提琴统计图_箱形图和小提琴图
- 我的世界服务器修改spawn,编辑“命令/spawnpoint” - Minecraft Wiki,最详细的官方我的世界百科...
- Spring+SpringMVC+Hibernate整合(封装CRUD操作)
- 06.02、js之设置日期方法-年月日时分秒毫秒比较