基于CH579实现蓝牙(ble4.2)控制led亮灭

2021-10-09 14:23:49 浏览数 (2)

1、特征分析

控制led亮灭:通过对一个特征值写来实现; 获取led状态:通过对一个特征值读来实现。

2、控制led亮灭服务

要实现特征值的读写,必须要有服务,特征声明,特征值声明。

3、属性表定义

代码语言:javascript复制
static gattAttribute_t ledAttrTbl[] = 
{
  // 服务,主要服务
  { 
    { ATT_BT_UUID_SIZE, primaryServiceUUID }, /* type */
    GATT_PERMIT_READ,                         /* permissions */
    0,                                        /* handle */
    (uint8 *)&ledService                 /* pValue */
  },
  // 特征声明
  { 
    { ATT_BT_UUID_SIZE, characterUUID },
    GATT_PERMIT_READ,                     
    0,
    &ledProps 
  },
  // 特征值声明
  { 
    { ATT_BT_UUID_SIZE, ledcharUUID },
    GATT_PERMIT_READ | GATT_PERMIT_WRITE, //可读可写
    0, 
    ledchar 
  },
  // 特征描述(非必须)
  { 
    { ATT_BT_UUID_SIZE, charUserDescUUID },
    GATT_PERMIT_READ, 
    0, 
    ledUserDesp 
  },      
};

上述表中定义了服务、特征声明、特征值声明、特征用户描述(非必须);服务、特征声明、特征值声明、特征用户描述,分别都属于属性。

4、注册服务

代码语言:javascript复制
bStatus_t Led_AddService( uint32 services )
{
  uint8 status = SUCCESS;

  if ( services & LED_SERVICE )
  {
    // Register GATT attribute list and CBs with GATT Server App
    status = GATTServApp_RegisterService( ledAttrTbl, 
                                          GATT_NUM_ATTRS( ledAttrTbl ),
																					GATT_MAX_ENCRYPT_KEY_SIZE,
                                          &simpleProfileCBs );
  }

  return ( status );
}

5、属性读回调

代码语言:javascript复制
static bStatus_t led_ReadAttrCB( uint16 connHandle, gattAttribute_t *pAttr, 
                            uint8 *pValue, uint16 *pLen, uint16 offset, uint16 maxLen,uint8 method  )
{
  bStatus_t status = SUCCESS;

  // If attribute permissions require authorization to read, return error
  if ( gattPermitAuthorRead( pAttr->permissions ) )
  //判断是否具有读权限
  {
    // Insufficient authorization
    return ( ATT_ERR_INSUFFICIENT_AUTHOR );
  }
  
  // Make sure it's not a blob operation (no attributes in the profile are long)
  if ( offset > 0 )
  {
    return ( ATT_ERR_ATTR_NOT_LONG );
  }
 
  if ( pAttr->type.len == ATT_BT_UUID_SIZE )//16位UUID
  {
    // 16-bit UUID
    uint16 uuid = BUILD_UINT16( pAttr->type.uuid[0], pAttr->type.uuid[1]);
    switch ( uuid )//在属性表里,初始化的UUID
    {
      case LED_CHAR_UUID:
        *pLen = LED_CHAR_LEN;
        tmos_memcpy( pValue, pAttr->pValue, LED_CHAR_LEN );	
		printf("LED readrn");
        break;
      default:
        // Should never get here! (characteristics 3 and 4 do not have read permissions)
        *pLen = 0;
        status = ATT_ERR_ATTR_NOT_FOUND;
        break;
    }
  }
  else
  {
    // 128-bit UUID
    *pLen = 0;
    status = ATT_ERR_INVALID_HANDLE;
  }
  return ( status );
}

6、属性写回调

代码语言:javascript复制
static bStatus_t led_WriteAttrCB( uint16 connHandle, gattAttribute_t *pAttr,
                                 uint8 *pValue, uint16 len, uint16 offset,uint8 method  )
{
  bStatus_t status = SUCCESS;
  uint8 notifyApp = 0xFF;
 
  if ( gattPermitAuthorWrite( pAttr->permissions ) )
  { //判断是否有写权限
    // Insufficient authorization
    return ( ATT_ERR_INSUFFICIENT_AUTHOR );
  }
  if ( pAttr->type.len == ATT_BT_UUID_SIZE )
  {
    // 16-bit UUID
    uint16 uuid = BUILD_UINT16( pAttr->type.uuid[0], pAttr->type.uuid[1]);
    switch ( uuid )
    {
      case LED_CHAR_UUID:
        //Validate the value
        // Make sure it's not a blob oper
        if ( offset == 0 )
        {
          if ( len > LED_CHAR_LEN )
          {
            status = ATT_ERR_INVALID_VALUE_SIZE;
          }
        }
        else
        {
          status = ATT_ERR_ATTR_NOT_LONG;
        }
        //Write the value
        if ( status == SUCCESS )
        {
          tmos_memcpy( pAttr->pValue, pValue, LED_CHAR_LEN );
          notifyApp = LED_CHAR;        
        }  
		printf("LED Writern");		
        break;
      default:
        // Should never get here! (characteristics 2 and 4 do not have write permissions)
        status = ATT_ERR_ATTR_NOT_FOUND;
        break;
    }
  }
  else
  {
    // 128-bit UUID
    status = ATT_ERR_INVALID_HANDLE;
  }

//  // If a charactersitic value changed then callback function to notify application of change
  if ( (notifyApp != 0xFF ) && led_AppCBs && led_AppCBs->ledChange )
  {
    led_AppCBs->ledChange( notifyApp, pValue, len );
    //数据传到应用层
  }
  return ( status );
}

7、应用层控制LED

在写回调中数据判断合法后会传递数据到应用层。

代码语言:javascript复制
static void ledChangeCB( uint8 paramID, uint8 *pValue, uint16 len )
{
	if(paramID==LED_CHAR)
	{
		if(len==1)
		{
			if(pValue[0])
			{
				GPIOB_SetBits(bPWM6);
				PRINT("highrn");
			}
			else
			{
				GPIOB_ResetBits(bPWM6);
				PRINT("lowrn");
			}
		}
	}
}

8、APP控制LED

控制LED亮灭服务的UUID为ffe0,即就是上图中左边红框中的,属性值可读可写;右边是写,发送0x01,LED亮,发送0x00,LED灭。

说明:篇幅限制,文中只列出了部分代码。

——————END——————

0 人点赞