分为两部分:
1、此部为从机写特征值的回调函数,主要是主机会写入CFG 0x0001打开Notify使能。 static bStatus_t battWriteAttrCB( uint16 connHandle, gattAttribute_t *pAttr, uint8 *pValue, uint8 len, uint16 offset ) {
bStatus_t status = SUCCESS;
uint16 uuid = BUILD_UINT16( pAttr->type.uuid[0], pAttr->type.uuid[1]); switch ( uuid ) {
case GATT_CLIENT_CHAR_CFG_UUID:
status = GATTServApp_ProcessCCCWriteReq( connHandle, pAttr, pValue, len, offset, GATT_CLIENT_CFG_NOTIFY ); if ( status == SUCCESS ) {
uint16 charCfg = BUILD_UINT16( pValue[0], pValue[1] );
if ( battServiceCB ) {
(*battServiceCB)( (charCfg == GATT_CFG_NO_OPERATION) ? BATT_LEVEL_NOTI_DISABLED : BATT_LEVEL_NOTI_ENABLED); } } break;
default:
status = ATT_ERR_ATTR_NOT_FOUND; break; }
return ( status ); }
2、这段程序为从机发送通知的示例,主机还需要做两件事情,一是通过Write过程将从机的CFG值写为0x0001,然后由第一步中的write特征值回调函数处理,并调用此函数。二是主机中需要有通知消息的处理过程
//linkDBItem_t是蓝牙建立链接之后的一个结构体,每个链接有自己的一个Handle值,如果当前蓝牙只有一个链接,则该handle值为0; plinkItem的值是从LinkDB_PerformFunc()传进来的。 static void battNotifyCB( linkDBItem_t *pLinkItem ) {
//检查是否已经建立蓝牙连接
if ( pLinkItem->stateFlags & LINK_CONNECTED ) {
//取 cfg的值,看是否为0x0001;(0x0001为Notify,0x0002为Indicate) uint16 value = GATTServApp_ReadCharCfg( pLinkItem->connectionHandle, battLevelClientCharCfg ); if ( value & GATT_CLIENT_CFG_NOTIFY ) {
attHandleValueNoti_t noti;
//此处的handle是将要发送的数据的handle,不是cfg的handle noti.handle = battAttrTbl[BATT_LEVEL_VALUE_IDX].handle; noti.len = 1;
noti.value[0] = battLevel;
GATT_Notification( pLinkItem->connectionHandle, ¬i, FALSE ); } } }
广播时间模式
1.保持无限广播:
General Discovery mode下,先设置TGAP_GEN_DISC_ADV_MIN = 0。GAP_SetParamValue(TGAP_GEN_DISC_ADV_MIN,0),再使能广播。
至于 GAPRole_SetParameter( GAPROLE_ADVERT_OFF_TIME, sizeof( uint16 ), &gapRole_AdvertOffTime );不用管,因为:
当TGAP_GEN_DISC_ADV_MIN = 0时。GAPROLE_ADVERT_OFF_TIME是无效的。 2.单次限时广播:
先设置广播的持续时间,如3s:
Limited Discovery mode下,GAP_SetParamValue(TGAP_LIM_ADV_TIMEOUT, 3);//单位秒 General Discovery mode下,GAP_SetParamValue(TGAP_GEN_DISC_ADV_MIN,3000);//单位ms 然后注意设置gapRole_AdvertOffTime = 0。
GAPRole_SetParameter( GAPROLE_ADVERT_OFF_TIME, sizeof( uint16 ), &gapRole_AdvertOffTime ); 这样你开启一次广播,持续3秒后就自动停止了。 3.循环限制广播:
先设置你每次的广播时间,如10秒:TGAP_LIM_ADV_TIMEOUT = 10。GAP_SetParamValue(TGAP_LIM_ADV_TIMEOUT,10)。 然后设置关闭广播的持续时间,如20秒: gapRole_AdvertOffTime = 20000。
GAPRole_SetParameter( GAPROLE_ADVERT_OFF_TIME, sizeof( uint16 ), &gapRole_AdvertOffTime ); 这样的效果就是:广播10秒,停止20秒。广播10秒...如此循环。
BLE芯片CC254x 系统资源
1.CC254x 内核
1.1.内核介绍
CC254x内部采用的是增强型8051内核,指令执行速度较标准的8051要快,主要基于: l 增强型8051的单周期指令是1个时钟周期,而标准8051需要12个时钟周期; l 没有了浪费的总线状态(wastedbus states);
由于一个指令周期能与存储中指令预取保持同步,使得大多数单周期指令能在一个时钟周期内完成,此外,增强型8051内核也包含一个“second data pointer”和一个扩展的18个中断单元。
1.2.存储空间
8051有分离的程序存储空间和数据存储空间,可细分成4中不同的存储空间: l CODE:只读程序存储,寻址空间64KB;
l DATA:可读写数据存储空间,可被直接或间接寻址,256 bytes,低128 byte 可被直接或间接寻址,高128 bytes只能间接寻址(SFR除外,SFR为直接寻址)
l XDATA:片外数据存储,寻址空间64K, l SFR:寄存器区域,直接寻址;
2. 时钟系统
CC254x内部时钟系统分两部分,系统时钟(system clock)和睡眠看门狗时钟。
2.1.系统时钟
· CPU运行主频,分频之后也为Timer1、Timer3、Timer4计数时钟; · 支持2种时钟源,内部16MHz RC晶振或外部的32MHz晶振; · 上电默认是IRC 16MHz;
· IRC 16MHz 启动时间比32MHz时间短,功耗低,但是精度差,不能用于射频相关的数据传输,射频相关操作必须要等32MHz时钟稳定之后才能进行;
2.2.睡眠看门狗时钟
· 为睡眠定时器和看门狗运行提供时钟;
相关推荐: