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

1、特征分析

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

2、控制led亮灭服务

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

3、属性表定义

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、注册服务

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、属性读回调

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 read\r\n");
        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、属性写回调

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 Write\r\n");		
        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

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

static void ledChangeCB( uint8 paramID, uint8 *pValue, uint16 len )
{
	if(paramID==LED_CHAR)
	{
		if(len==1)
		{
			if(pValue[0])
			{
				GPIOB_SetBits(bPWM6);
				PRINT("high\r\n");
			}
			else
			{
				GPIOB_ResetBits(bPWM6);
				PRINT("low\r\n");
			}
		}
	}
}

8、APP控制LED

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

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

  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

freemote

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值