回答

收藏

[评测分享] 【RISC-V 沁恒微-CH585M-R1开发板试用体验】+BLE远程控灯

#板卡评测 #板卡评测 588 人阅读 | 0 人回复 | 2025-07-08

       承接上期的呼吸灯效贴,今天来分享一下,将开发板做为BLE从机,手机做为BLE主机,在手机端的蓝牙调试助手发送指定字符去控制板上的LED0、LED1。

       基于SDK中提供的从机“Peripheral”例程,手机端应用市场安装好“BLE调试助手”app。编译“Peripheral”例程后,使用“WCHISPStudio”下载编译后的“Peripheral.hex”文件。然后打开手机端的蓝牙与GPS开关,打开“BLE调试助手”app,扫描连接“Simple Peripheral”设备。连接该设备后则可看到“Generic Access”、“Generic Attribute”、“设备信息”和“Unknown Service”所有服务项。


      其中的Unknown Service服务是我们所需着重关注的,该服务是程序中自定义的一个通讯服务,UUID为0xFFE0,点击该条目,界面显示出0xFFE0服务下所有的characteristic,其包括“0xFFE1”、“0xFFE2”、“0xFFE3”、“0xFFE4”和“0xFFE5”,并显示出该服务的Properties。具体如下图所示:


    根据图示可知,我们可通过“0xFFE1”,““0xFFE3”两个特征服务给开发进行写操作,也就是发送字符给开发板解析。然后回到例程中的“Peripheral_Init()”函数。
  1. void Peripheral_Init()
  2. {
  3.     Peripheral_TaskID = TMOS_ProcessEventRegister(Peripheral_ProcessEvent);

  4.     // Setup the GAP Peripheral Role Profile
  5.     {
  6.         uint8_t  initial_advertising_enable = TRUE;
  7.         uint16_t desired_min_interval = DEFAULT_DESIRED_MIN_CONN_INTERVAL;
  8.         uint16_t desired_max_interval = DEFAULT_DESIRED_MAX_CONN_INTERVAL;

  9.         // Set the GAP Role Parameters
  10.         GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t), &initial_advertising_enable);
  11.         GAPRole_SetParameter(GAPROLE_SCAN_RSP_DATA, sizeof(scanRspData), scanRspData);
  12.         GAPRole_SetParameter(GAPROLE_ADVERT_DATA, sizeof(advertData), advertData);
  13.         GAPRole_SetParameter(GAPROLE_MIN_CONN_INTERVAL, sizeof(uint16_t), &desired_min_interval);
  14.         GAPRole_SetParameter(GAPROLE_MAX_CONN_INTERVAL, sizeof(uint16_t), &desired_max_interval);
  15.     }

  16.     {
  17.         uint16_t advInt = DEFAULT_ADVERTISING_INTERVAL;

  18.         // Set advertising interval
  19.         GAP_SetParamValue(TGAP_DISC_ADV_INT_MIN, advInt);
  20.         GAP_SetParamValue(TGAP_DISC_ADV_INT_MAX, advInt);

  21.         // Enable scan req notify
  22.         GAP_SetParamValue(TGAP_ADV_SCAN_REQ_NOTIFY, ENABLE);
  23.     }

  24.     // Setup the GAP Bond Manager
  25.     {
  26.         uint32_t passkey = 0; // passkey "000000"
  27.         uint8_t  pairMode = GAPBOND_PAIRING_MODE_WAIT_FOR_REQ;
  28.         uint8_t  mitm = TRUE;
  29.         uint8_t  bonding = TRUE;
  30.         uint8_t  ioCap = GAPBOND_IO_CAP_DISPLAY_ONLY;
  31.         GAPBondMgr_SetParameter(GAPBOND_PERI_DEFAULT_PASSCODE, sizeof(uint32_t), &passkey);
  32.         GAPBondMgr_SetParameter(GAPBOND_PERI_PAIRING_MODE, sizeof(uint8_t), &pairMode);
  33.         GAPBondMgr_SetParameter(GAPBOND_PERI_MITM_PROTECTION, sizeof(uint8_t), &mitm);
  34.         GAPBondMgr_SetParameter(GAPBOND_PERI_IO_CAPABILITIES, sizeof(uint8_t), &ioCap);
  35.         GAPBondMgr_SetParameter(GAPBOND_PERI_BONDING_ENABLED, sizeof(uint8_t), &bonding);
  36.     }

  37.     // Initialize GATT attributes
  38.     GGS_AddService(GATT_ALL_SERVICES);           // GAP
  39.     GATTServApp_AddService(GATT_ALL_SERVICES);   // GATT attributes
  40.     DevInfo_AddService();                        // Device Information Service
  41.     SimpleProfile_AddService(GATT_ALL_SERVICES); // Simple GATT Profile

  42.     // Set the GAP Characteristics
  43.     GGS_SetParameter(GGS_DEVICE_NAME_ATT, GAP_DEVICE_NAME_LEN, attDeviceName);

  44.     // Setup the SimpleProfile Characteristic Values
  45.     {
  46.         uint8_t charValue1[SIMPLEPROFILE_CHAR1_LEN] = {1};
  47.         uint8_t charValue2[SIMPLEPROFILE_CHAR2_LEN] = {2};
  48.         uint8_t charValue3[SIMPLEPROFILE_CHAR3_LEN] = {3};
  49.         uint8_t charValue4[SIMPLEPROFILE_CHAR4_LEN] = {4};
  50.         uint8_t charValue5[SIMPLEPROFILE_CHAR5_LEN] = {1, 2, 3, 4, 5};

  51.         SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR1, SIMPLEPROFILE_CHAR1_LEN, charValue1);
  52.         SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR2, SIMPLEPROFILE_CHAR2_LEN, charValue2);
  53.         SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR3, SIMPLEPROFILE_CHAR3_LEN, charValue3);
  54.         SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR4, SIMPLEPROFILE_CHAR4_LEN, charValue4);
  55.         SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR5, SIMPLEPROFILE_CHAR5_LEN, charValue5);
  56.     }

  57.     // Init Connection Item
  58.     peripheralInitConnItem(&peripheralConnList);

  59.     // Register callback with SimpleGATTprofile
  60.     SimpleProfile_RegisterAppCBs(&Peripheral_SimpleProfileCBs);

  61.     // Register receive scan request callback
  62.     GAPRole_BroadcasterSetCB(&Broadcaster_BroadcasterCBs);

  63.     // Setup a delayed profile startup
  64.     tmos_set_event(Peripheral_TaskID, SBP_START_DEVICE_EVT);
  65. }
复制代码
// Register callback with SimpleGATTprofile即是初始化注册的特征值变化回调接口。
  1. // Simple GATT Profile Callbacks
  2. static simpleProfileCBs_t Peripheral_SimpleProfileCBs = {
  3.     simpleProfileChangeCB // Characteristic value change callback
  4. };
复制代码
然后再根据实验需求,在“simpleProfileChangeCB()”函数中实现控制板上LED0,LED1的逻辑处理代码。
  1. /*********************************************************************
  2. * @fn      simpleProfileChangeCB
  3. *
  4. * @brief   Callback from SimpleBLEProfile indicating a value change
  5. *
  6. * @param   paramID - parameter ID of the value that was changed.
  7. *          pValue - pointer to data that was changed
  8. *          len - length of data
  9. *
  10. * @return  none
  11. */
  12. static void simpleProfileChangeCB(uint8_t paramID, uint8_t *pValue, uint16_t len)
  13. {
  14.     switch(paramID)
  15.     {
  16.         case SIMPLEPROFILE_CHAR1:
  17.         {
  18.             uint8_t newValue[SIMPLEPROFILE_CHAR1_LEN];
  19.             tmos_memcpy(newValue, pValue, len);
  20.             if(newValue[0])
  21.             {
  22.                 if(newValue[0]== 0x30)
  23.                 {
  24.                     GPIOA_SetBits(GPIO_Pin_0);  //关闭LED0
  25.                 }
  26.                 else if(newValue[0]==0x31)
  27.                 {
  28.                     GPIOA_ResetBits(GPIO_Pin_0);    //打开LED0
  29.                 }
  30.                 else if(newValue[0]==0x32)
  31.                 {
  32.                     GPIOA_SetBits(GPIO_Pin_1);  //关闭LED1
  33.                 }
  34.                 else if(newValue[0]==0x33)
  35.                 {
  36.                     GPIOA_ResetBits(GPIO_Pin_1); //打开LED1
  37.                 }
  38.             }
  39.             PRINT("profile ChangeCB CHAR1.. \n");
  40.             break;
  41.         }

  42.         case SIMPLEPROFILE_CHAR3:
  43.         {
  44.             uint8_t newValue[SIMPLEPROFILE_CHAR3_LEN];
  45.             tmos_memcpy(newValue, pValue, len);
  46.             PRINT("profile ChangeCB CHAR3..\n");
  47.             break;
  48.         }

  49.         default:
  50.             // should not reach here!
  51.             break;
  52.     }
  53. }
复制代码
       实验在“0xFFE1”服务特征值下进行,因此添加逻辑代码在“SIMPLEPROFILE_CHAR1”,如果想在“0xFFE3”服务特征值下实验,则将逻辑代码添加到SIMPLEPROFILE_CHAR3”下。
       完成上述代码编写完后,当然记得在main函数中添加LED0、LED1的GPIO口初始化代码,默认关闭LED0、LED1。这里笔者LED0使用PA0,LED1使用PA1。main()函数中内容如下:
  1. /*********************************************************************
  2. * @fn      main
  3. *
  4. * @brief   主函数
  5. *
  6. * @return  none
  7. */
  8. int main(void)
  9. {
  10. #if(defined(DCDC_ENABLE)) && (DCDC_ENABLE == TRUE)
  11.     PWR_DCDCCfg(ENABLE);
  12. #endif
  13.     HSECFG_Capacitance(HSECap_18p);
  14.     SetSysClock(CLK_SOURCE_HSE_PLL_62_4MHz);
  15. #if(defined(HAL_SLEEP)) && (HAL_SLEEP == TRUE)
  16.     GPIOA_ModeCfg(GPIO_Pin_All, GPIO_ModeIN_PU);
  17.     GPIOB_ModeCfg(GPIO_Pin_All, GPIO_ModeIN_PU);
  18. #endif
  19. #ifdef DEBUG
  20.     GPIOA_SetBits(GPIO_Pin_14);
  21.     GPIOPinRemap(ENABLE, RB_PIN_UART0);
  22.     GPIOA_ModeCfg(GPIO_Pin_14, GPIO_ModeOut_PP_5mA);
  23.     UART0_DefInit();
  24. #endif
  25.     PRINT("%s\n", VER_LIB);

  26.     //LED 0
  27.     GPIOA_ModeCfg( GPIO_Pin_0, GPIO_ModeOut_PP_5mA );
  28.     //LED 1
  29.     GPIOA_ModeCfg( GPIO_Pin_1, GPIO_ModeOut_PP_5mA );
  30.     GPIOA_SetBits(GPIO_Pin_0);
  31.     GPIOA_SetBits(GPIO_Pin_1);  //默认关闭LED0、LED1

  32.     CH58x_BLEInit();
  33.     HAL_Init();
  34.     GAPRole_PeripheralInit();
  35.     Peripheral_Init();
  36.     Main_Circulation();
  37. }
复制代码
开发板的硬件实物连线如下:


工程编译、下载后,实验的演示效果见B站视频:https://www.bilibili.com/video/BV1CfGnz2Ej8/




分享到:
回复

使用道具 举报

您需要登录后才可以回帖 注册/登录

本版积分规则

软件工程师
40453 积分
34 主题
+ 关注
热门推荐
关闭

站长推荐上一条 /3 下一条