【BLE 5.3无线MCU CH582】11、手机app控制led亮灭
本帖最后由 freeelectron 于 2022-3-28 20:15 编辑<p>系列文章:</p>
<p><a href="https://bbs.eeworld.com.cn/thread-1195192-1-1.html" target="_blank">【BLE 5.3无线MCU CH582】1、初识CH582开发板(开箱)</a></p>
<p><a href="https://bbs.eeworld.com.cn/thread-1195464-1-1.html" target="_blank">【BLE 5.3无线MCU CH582】2、MounRiver IDE初体验</a></p>
<p><a href="https://bbs.eeworld.com.cn/thread-1196099-1-1.html#pid3126477" target="_blank">【BLE 5.3无线MCU CH582】3、非阻塞方式点灯</a></p>
<p><a href="https://bbs.eeworld.com.cn/thread-1196188-1-1.html" target="_blank">【BLE 5.3无线MCU CH582】4、串口不定长数据接收</a></p>
<p><a href="https://bbs.eeworld.com.cn/thread-1196777-1-1.html" target="_blank">【BLE 5.3无线MCU CH582】5、硬件I2C驱动0.96吋OLED</a></p>
<p><a href="https://bbs.eeworld.com.cn/thread-1196846-1-1.html" target="_blank">【BLE 5.3无线MCU CH582】6、pwm呼吸灯</a></p>
<p><a href="https://bbs.eeworld.com.cn/thread-1196850-1-1.html" target="_blank">【BLE 5.3无线MCU CH582】7、按键——GPIO外部中断</a></p>
<p><a href="https://bbs.eeworld.com.cn/thread-1196888-1-1.html" target="_blank">【BLE 5.3无线MCU CH582】8、adc采样(内部bat、内部温度,外部输入)</a></p>
<p><a href="https://bbs.eeworld.com.cn/thread-1197780-1-1.html" target="_blank">【BLE 5.3无线MCU CH582】9、硬件spi驱动lcd</a></p>
<p><a href="https://bbs.eeworld.com.cn/thread-1198080-1-1.html" target="_blank">【BLE 5.3无线MCU CH582】10、ble广播者角色</a></p>
<p> </p>
<p><span style="font-size:26px;">1、前面的话</span></p>
<p><span style="font-size:16px;">本文使用ble的另一种角色——外围设备,也叫从机,也是最常用的一种角色。</span></p>
<p> </p>
<p><span style="font-size:26px;">2、ble数据传输</span></p>
<p><span style="font-size:16px;">这里需要明确一点,ble是属性传输数据的,属性是有权限的,可读可写等。</span></p>
<p> </p>
<h3><span style="font-size:26px;">3、led控制特征分析</span></h3>
<p><span style="font-size:16px;">控制led亮灭:通过对一个特征值<strong>写</strong>来实现;<br />
获取led状态:通过对一个特征值<strong>读</strong>来实现。</span></p>
<p> </p>
<p><span style="font-size:26px;">4、控制led亮灭服务</span></p>
<p><span style="font-size:16px;">要实现特征值的读写,必须要有<strong>服务</strong>,<strong>特征声明</strong>,<strong>特征值声明</strong></span></p>
<h3><span style="font-size:26px;">5、属性表定义</span></h3>
<pre>
<code class="language-cpp">static gattAttribute_t ledProfileAttrTb[] =
{
// led Profile Service, // 服务,主要服务
{
{ ATT_BT_UUID_SIZE, primaryServiceUUID }, /* type */
GATT_PERMIT_READ, /* permissions */
0, /* handle */
(uint8 *)&ledProfileService /* pValue */
},
// CharacteristicDeclaration// 特征声明
{
{ ATT_BT_UUID_SIZE, characterUUID },
GATT_PERMIT_READ,
0,
&ledProfileCharProps
},
// Characteristic Value// 特征值声明
{
{ ATT_BT_UUID_SIZE, ledProfilecharUUID },
GATT_PERMIT_READ | GATT_PERMIT_WRITE,
0,
ledProfileChar
},
// CharacteristicUser Description// 特征描述(非必须)
{
{ ATT_BT_UUID_SIZE, charUserDescUUID },
GATT_PERMIT_READ,
0,
ledProfileCharUserDesp
},
};</code></pre>
<p><span style="font-size:16px;">上述表中定义了服务、特征声明、特征值声明、特征用户描述(非必须);服务、特征声明、特征值声明、特征用户描述,分别都属于属性。</span></p>
<p> </p>
<h3><span style="font-size:26px;">6、注册服务</span></h3>
<pre>
<code class="language-cpp">bStatus_t LedProfile_AddService( uint32 services )
{
uint8 status = SUCCESS;
if ( services & LEDPROFILE_SERVICE )
{
// Register GATT attribute list and CBs with GATT Server App
status = GATTServApp_RegisterService( ledProfileAttrTb,
GATT_NUM_ATTRS( ledProfileAttrTb ),
GATT_MAX_ENCRYPT_KEY_SIZE,
&ledProfileCBs );
}
return ( status );
}</code></pre>
<h3><span style="font-size:26px;">7、属性读回调</span></h3>
<pre>
<code class="language-cpp">static bStatus_t ledProfile_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-bit UUID
uint16 uuid = BUILD_UINT16( pAttr->type.uuid, pAttr->type.uuid);
switch ( uuid )
{
case LEDPROFILE_CHAR_UUID:
*pLen = LEDPROFILE_CHAR_LEN;
tmos_memcpy( pValue, pAttr->pValue, LEDPROFILE_CHAR_LEN );
PRINT("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 );
}</code></pre>
<h3><span style="font-size:26px;">8、属性写回调</span></h3>
<pre>
<code>static bStatus_t ledProfile_WriteAttrCB( uint16 connHandle, gattAttribute_t *pAttr,
uint8 *pValue, uint16 len, uint16 offset,uint8 method)
{
bStatus_t status = SUCCESS;
uint8 notifyApp = 0xFF;
// If attribute permissions require authorization to write, return error
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, pAttr->type.uuid);
switch ( uuid )
{
case LEDPROFILE_CHAR_UUID:
//Validate the value
// Make sure it's not a blob oper
if ( offset == 0 )
{
if ( len > LEDPROFILE_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, LEDPROFILE_CHAR_LEN );
notifyApp = LEDPROFILE_CHAR;
}
PRINT("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 ) && ledProfile_AppCBs && ledProfile_AppCBs->pfnLedProfileChange )
{
ledProfile_AppCBs->pfnLedProfileChange( notifyApp, pValue, len );
}
return ( status );
}</code></pre>
<h3><span style="font-size:26px;">9、应用层控制LED</span></h3>
<pre>
<code>static void ledProfileChangeCB( uint8 paramID, uint8 *pValue, uint16 len )
{
switch( paramID )
{
case LEDPROFILE_CHAR:
{
uint8 newValue;
tmos_memcpy( newValue, pValue, len );
if(newValue)
{
GPIOB_ResetBits (GPIO_Pin_18);
PRINT("led on\n");
}
else
{
GPIOB_SetBits(GPIO_Pin_18);
PRINT("led off\n");
}
break;
}
default:
// should not reach here!
break;
}
}</code></pre>
<h3><span style="font-size:26px;">10、APP控制LED</span></h3>
<p>(1)扫描</p>
<p></p>
<p>(2)连接</p>
<p> </p>
<p>(3)属性权限</p>
<p> 可以看到,扫描出来后是可读可写的,与我们代码中定义的是一致的。</p>
<p>(3)控制亮灭</p>
<p></p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p>顶一下楼主,楼主对蓝牙还是很有研究的。</p>
<p>更进一步了哦,有没有考虑用小爱同志,或者其他的APP来控制呀。</p>
lugl4313820 发表于 2022-3-29 16:43
更进一步了哦,有没有考虑用小爱同志,或者其他的APP来控制呀。
<p><img height="53" src="https://bbs.eeworld.com.cn/static/editor/plugins/hkemoji/sticker/facebook/sad.gif" width="54" />暂时没有小爱</p>
<p>这个app也是自己做的吗?牛逼了哦</p>
freebsder 发表于 2022-3-29 17:13
这个app也是自己做的吗?牛逼了哦
<p>这是官方的app</p>
tagetage 发表于 2022-3-29 11:14
顶一下楼主,楼主对蓝牙还是很有研究的。
<p>以前用ch579学过蓝牙,那一套api和ch582的基本一致。</p>
<p>大佬,有没有专案分享一下,我正在学习 CH582 蓝牙,我试了好久这专案都跑不起来...鬱闷.... 感觉这是我找到最适合入门蓝牙的例程了,谢谢大佬</p>
aaa1218bbb 发表于 2022-4-26 11:41
大佬,有没有专案分享一下,我正在学习 CH582 蓝牙,我试了好久这专案都跑不起来...鬱闷.... 感觉这是我找 ...
<p>对照着蓝牙核心规范和代码学习</p>
<p>楼主你好请问文中的例程可以分享一下吗 有一些细节的东西想再看代码学习一下</p>
页:
[1]