收到MM32W373PSB蓝牙开发板已有段时间,今天周末,来体验一下它的自拍杆功能。MM32W373PSB的应用广泛,可以Beacon、无线键盘、鼠标、工业应用:工业遥控、遥测、警报系统、门禁系统、数据采集和传输系统、便捷式医疗设备、可穿戴的运动和健身设备。MM32W373PSB集成了32位ARM Cortex-M3处理器内核,最高工作频率可达96MHz,ARM Cortex-M3处理器是最新一代的嵌入式ARM处理器,它为实现MCU的需要提供了低成本的平台、缩减的引脚数目、降低的系统功耗,同时提供卓越的计算性能和先进的中断系统响应。
       本次体验的功能比较简单,将开发板上电,然后打开手机蓝牙,搜索并连接上“MindMotion-Shutter”蓝牙设备,然后打开手机的照相机,放在离开发板有一定距离的地方,然后通过按下按键K4来抓拍美丽的瞬间。主要的几个源文件与调用函数简单的罗列一下:
  1. #include "sys.h"
  2. #include "delay.h"
  3. #include "uart.h"
  4. #include "spi.h"
  5. #include "RF_IRQ.h"
  6. #include <string.h>
  7. #include "HAL_conf.h"
  8. #include "mg_api.h"
  9. #include "mg_test_api.h"
  10. #include "iwdg.h"
  11. #include "RF_Callback.h"
  12. extern void Key_Shutter_Init(void);
  13. unsigned char *ble_mac_addr;
  14. u8 value_t[2];
  15. unsigned char *get_local_addr(void) //used for ble pairing case
  16. {
  17.   return ble_mac_addr;
  18. }
  19. void  BLE_SV()
  20. {
  21.   unsigned char *BLE_SV = get_ble_version();
  22. }
  23. u8 ADV_Data[] = {'T', 'E', 'S', 'T'};
  24. unsigned long i;
  25. int main(void)
  26. {
  27.   unsigned long temp = 0x800000;
  28.   while (temp--);
  29.   SPIM_Init(0x06);
  30.   IRQ_RF();
  31.   SYSTick_Configuration();
  32.   uart_initwBaudRate();
  33.   SetBleIntRunningMode();
  34.   radio_initBle(TXPWR_3DBM, &ble_mac_addr);
  35.   IWDG_Init(4, 625);
  36.   Key_Shutter_Init();
  37.   value_t[0] = 0xc0;
  38.   value_t[1] = *(u8 *)0x1FFFF820;    //Read FT value(FT value:The RF module is
  39.   calibrated at the factory to prevent frequency deviation. The user can call the
  40.   FT value in the program)
  41.   ble_run_interrupt_start(80);          //320*0.625=200 ms
  42.   while (1)
  43.   {
  44.   }
  45. }
       官方底层协议栈提供了封装好的库函数,用户直接包含头文件,调用库函数即可
  1. #ifndef _MG_API_H_
  2. #define _MG_API_H_
  3. //TX power
  4. #define TXPWR_3DBM 0x48
  5. #define TXPWR_0DBM 0x43
  6. #define        TXPWR__3DBM         64
  7. #define        TXPWR__6DBM         61
  8. #define        TXPWR__8DBM         58
  9. #define        TXPWR__15DBM 48
  10. // ATT Error Codes
  11. #define ATT_ERR_INVALID_HANDLE           0x01
  12. #define ATT_ERR_READ_NOT_PERMITTED       0x02
  13. #define ATT_ERR_WRITE_NOT_PERMITTED      0x03
  14. #define ATT_ERR_INVALID_PDU              0x04
  15. #define ATT_ERR_INSUFFICIENT_AUTHEN      0x05
  16. #define ATT_ERR_UNSUPPORTED_REQ          0x06
  17. #define ATT_ERR_INVALID_OFFSET           0x07
  18. #define ATT_ERR_INSUFFICIENT_AUTHOR      0x08
  19. #define ATT_ERR_PREPARE_QUEUE_FULL       0x09
  20. #define ATT_ERR_ATTR_NOT_FOUND           0x0a
  21. #define ATT_ERR_ATTR_NOT_LONG            0x0b
  22. #define ATT_ERR_INSUFFICIENT_KEY_SIZE    0x0c
  23. #define ATT_ERR_INVALID_VALUE_SIZE       0x0d
  24. #define ATT_ERR_UNLIKELY                 0x0e
  25. #define ATT_ERR_INSUFFICIENT_ENCRYPT     0x0f
  26. #define ATT_ERR_UNSUPPORTED_GRP_TYPE     0x10
  27. #define ATT_ERR_INSUFFICIENT_RESOURCES   0x11
  28. //adv header type
  29. #define ADV_HDR_TYPE_PUBLIC_IND         0x00
  30. #define ADV_HDR_TYPE_RANDOM_IND         0x80
  31. #define ADV_HDR_TYPE_PUBLIC_NONCONN_IND  0x02
  32. #define ADV_HDR_TYPE_RANDOM_NONCONN_IND  0x82
  33. //Function: radio_initBle
  34. //Parameters: txpwr - input, txpower;   addr - output, BLE device address
  35. //return: None
  36. void radio_initBle(unsigned char txpwr, unsigned char** addr/*out*/);  //init ble mode, should be called first after spi initialization
  37. //Function: radio_initBle_TO
  38. //Parameters: txpwr - input, txpower;   addr - output, BLE device address;   ms_timeout - timeout for BLE initialization, recommend value 10~50
  39. //return: 0 - fail;  none 0 - success
  40. unsigned char radio_initBle_TO(unsigned char txpwr, unsigned char** addr, unsigned short ms_timeout);
  41. //Function: radio_initBle_recover
  42. //Parameters: txpwr - input, txpower;   addr - output, BLE device address
  43. //return: None
  44. void radio_initBle_recover(unsigned char txpwr, unsigned char** addr);
  45. //Function: radio_setCal_nonBlocking
  46. //Parameters: nonblocking - 0: blocking;  1: non blocking
  47. //return: none
  48. void radio_setCal_nonBlocking(unsigned nonblocking);
  49. //Function: radio_standby
  50. //this function is to set rf to standby mode, I ~ 3uA
  51. //Parameters: none
  52. //return: None
  53. //called in UsrProcCallback or when ble_run_interrupt_McuCanSleep()>0
  54. void radio_standby(void);
  55. //Function: radio_resume
  56. //this function is to recover rf from standby mode
  57. //Parameters: none
  58. //return: None
  59. void radio_resume(void);
  60.    
  61. //Function: radio_setXtal
  62. //this function is to config the params of xtal
  63. //Parameters: xoib:0~f, xocc:0
  64. //return: None
  65. void radio_setXtal(unsigned char xoib, unsigned char xocc);
  66. //Function: radio_setRxGain
  67. //this function is to config the params of RX
  68. //Parameters: lna_gain:0,5,6,7, preambe_th: 0x20 when lna_gain=0, 0x38 when lna_gain=5,6,7
  69. //return: 0-input param error, 1-ok
  70. unsigned char radio_setRxGain(unsigned char lna_gain, unsigned char preamble_th);
  71. //Function: ble_run
  72. //Parameters: interv_adv - advertise packet interval, unit 0.625ms
  73. //return: None
  74. //Remarks: never reurn!!!
  75. void ble_run(unsigned short interv_adv);
  76. //Function: ble_set_adv_data
  77. //Parameters: adv - advertise packet payload; len - payload len
  78. //return: None
  79. void ble_set_adv_data(unsigned char* adv, unsigned char len);
  80. //Function: ble_set_adv_rsp_data
  81. //Parameters: rsp - advertise response payload; len - payload len
  82. //return: None
  83. void ble_set_adv_rsp_data(unsigned char* rsp, unsigned char len);
  84. //Function: ble_set_name
  85. //this function IS available when using default scan response data
  86. //Parameters: name - device name; len - name len
  87. //return: None
  88. void ble_set_name(unsigned char* name,unsigned char len);
  89. //Function: ble_set_adv_type
  90. //Parameters: type - advertisement type, 0-adv_ind, 2-adv_nonconn_ind. default 0x80
  91. //                   addr type,      0x80 - RANDOM, 0x00 - PUBLIC
  92. //return: None
  93. void ble_set_adv_type(unsigned char type);
  94. //Function: ble_set_interval
  95. //Parameters: interval - advertisement interval, unit 0.625ms
  96. //return: None
  97. void ble_set_interval(unsigned short interval);
  98. //Function: ble_set_wakeupdly
  99. //Parameters: counter - wake up delay time, unit 16uS
  100. //return: 1
  101. unsigned char ble_set_wakeupdly(unsigned short counter);
  102. //Function: ble_set_adv_enableFlag
  103. //this function is to enable/disable ble adv
  104. //Parameters: sEnableFlag - 0 to disable adv, 1 to enable adv
  105. //return: None
  106. void ble_set_adv_enableFlag(char sEnableFlag);
  107. //Function: ble_set_role
  108. //this function is to set ble role to peripheral(0) or central(1), by default ble role is peripheral(0)
  109. //Parameters: role_new - 0 peripheral, 1 central
  110. //            scan_window - scan window for central rol. range: 0x0004~0x4000 (2.5ms ~ 10.24s)
  111. //return: 0 - fail, 1 - success
  112. unsigned char ble_set_role(unsigned char role_new, unsigned short scan_window);
  113. //Function: ble_disconnect
  114. //this function is to disconnected the ble connection
  115. //Parameters: none
  116. //return: None
  117. void ble_disconnect(void);
  118. unsigned char* GetFirmwareInfo(void); //such as "FVxx.2.0.2mmx"
  119. unsigned char* get_ble_version(void); //such as "MG_BLE_LIB_V1.0"
  120. unsigned char GetRssiData(void); //only valid after receive a packet
  121. void att_notFd(unsigned char pdu_type, unsigned char attOpcode, unsigned short attHd );
  122. void att_ErrorFd_eCode(unsigned char pdu_type, unsigned char attOpcode, unsigned short attHd, unsigned char errorCode);
  123. void att_server_rdByGrTypeRspDeviceInfo(unsigned char pdu_type);
  124. void att_server_rdByGrTypeRspPrimaryService(unsigned char pdu_type, unsigned short start_hd, unsigned short end_hd, unsigned char*uuid, unsigned char uuidlen);
  125. void att_server_rd( unsigned char pdu_type, unsigned char attOpcode, unsigned short att_hd, unsigned char* attValue, unsigned char datalen );
  126. void ser_write_rsp_pkt(unsigned char pdu_type);
  127. unsigned char sconn_notifydata(unsigned char* data, unsigned char len);//returns data size has been sent, ******* user's safe API *********
  128. unsigned char sconn_indicationdata(unsigned char* data, unsigned char len);
  1. void SIG_ConnParaUpdateReq(unsigned short IntervalMin, unsigned short IntervalMax, unsigned short slaveLatency, unsigned short TimeoutMultiplier);
  2. unsigned short sconn_GetConnInterval(void);//get current used interval in the unit of 1.25ms
  3. //Get current (or the latest) connected master device's MAC
  4. //returns mac(6 Bytes, Little-Endian format) and the type(MacType, 0 means public type, others mean random type)
  5. unsigned char* GetMasterDeviceMac(unsigned char* MacType);
  6. //PAIR APIs
  7. void SetLePinCode(unsigned char *PinCode/*6 0~9 digitals*/);
  8. //Get current connected device's long term KEY's info(EDIV)
  9. //returns u8* EDivData /*2 Bytes*/ (encrypted)
  10. //newFlag: 1 means new paired device's info, 0 means old paired device's info.
  11. //Remarks:
  12. //  1. This function shall be invoked when [StartEncryption == 1].
  13. //  2. This function is ONLY supported in pairing cases.
  14. unsigned char* GetLTKInfo(unsigned char* newFlag);
  15. //security manager module request for pair
  16. //Remarks:
  17. //  1. This function shall be invoked when [connected status == 1].
  18. //  2. This function is ONLY supported in pairing cases.
  19. void s_llSmSecurityReq(void);
  20. //return:
  21. // OTA_OK             0
  22. // OTA_SN_ERROR       1
  23. // OTA_CHECKSUM_ERROR 2
  24. // OTA_FORMAT_ERROR   3
  25. // OTA_UNKNOWN_ERROR  255
  26. unsigned char OTA_Proc(unsigned char *data, unsigned short len);
  27. //interrupt running mode APIs
  28. //Function: SetBleIntRunningMode
  29. //this function SHOULD be invoked before init the ble
  30. //Parameters: None
  31. //return: None
  32. void SetBleIntRunningMode(void);
  33. //Function: ble_run_interrupt_start
  34. //   this function SHOULD be invoked to start the interrupt running mode in the main routine.
  35. //   ble_run(0) function SHOULD ONLY be invoked in the ble irq interrupt service subroutine.
  36. //Parameters:  interv_adv - advertise packet interval, unit 0.625ms
  37. //return: None
  38. void ble_run_interrupt_start(unsigned short interv_adv);
  39. //Function: ble_nMsRoutine
  40. //this function SHOULD be invoked every 1ms tick, one can invoke this function inside the systick routine
  41. //Parameters: None
  42. //return: None
  43. void ble_nMsRoutine(void);
  44. //Function: ble_run_interrupt_McuCanSleep
  45. //this function CAN be invoked at main task, one can invoke this function to detect the BLE status then goto MCU sleep.
  46. //Before doing so, one SHOULD configure the BLE irq down wakeup pin's function enabled.  
  47. //Parameters: None
  48. //return: None-zero means MCU can enter into stop/sleep mode.
  49. unsigned char ble_run_interrupt_McuCanSleep(void);
  50. //debug APIs
  51. //Parameters: isFixCh37Flag - input, 1-adv on ch37 only, 0-adv on ch37,38,39. default:0
  52. void SetFixAdvChannel(unsigned char isFixCh37Flag);
     BLE库以系统中断服务程序方式运行, 适合于实现用户某功能需要占用较长 CPU 时间但可以被打断的应用场景。常需要用到两个中断服务程序,一个是IRQ中断pin对应的GPIO中断, 一个是实现SysTick对应的中断。IRQ对应的中断服务程序用于运行蓝牙协议,需要有较高的中断优先级(针对其他用户中断来说)。关于开发板的工作状态可通过AT指令切换,其实质通过USE_AT_CMD的宏来进行模式切换
  1. //function list
  2. AT_CMD_FUNC at_func_list[] =
  3. {
  4.   {atcmd_SetName, "SETNAME="},
  5.   {atcmd_SetAdvInt, "SETINTERVAL="},
  6.   {atcmd_SendData, "BLESEND="},
  7.   {atcmd_LowPower, "LOWPOWER="},
  8.   {atcmd_SetBaud, "SETBAUD="},
  9.   {atcmd_SetAdvFlag, "SETADVFLAG="},
  10.   {atcmd_DisconnecteBle, "DISCON"},
  11.   {atcmd_Minfo, "MINFO"},
  12.   {atcmd_Help, "HELP"},
  13. };
     MM32W373PSB内置嵌套的向量式中断控制器,能够处理多达68个可屏蔽中断通道(不包括16个Cortex-M3的中断线)和16个可编程优先级。外部中断/事件控制器包含21个边沿检测器,用于产生中断/事件请求。每个中断线都可以独立地配置它的触发事件(上升沿或下降沿或双边沿),并能够单独地被屏蔽;有一个挂起寄存器维持所有中断请求的状态。EXTI可以检测到脉冲宽度小于内部APB2的时钟周期。多达40个通用I/O口连接到16个外部中断线。
     控制模块系统时钟的选择是在启动时进行,复位时内部48MHz的振荡器被选为默认的CPU时钟,随后可以选择外部的16MHz时钟;当检测到外部时钟失效时,它将被隔离,系统将自动地切换到内部的振荡器,如果使能了中断,软件可以接收到相应的中断。同样,在需要时可以采取对PLL时钟完全的中断管理(如当一个间接使用的外部振荡器失效时)。多个预分频器用于配置AHB的频率、高速APB(APB2和APB1)区域,AHB和高速APB的最高频率是96MHz。时钟树如下图所示:
时钟树.png
    蓝牙ATT服务特征值在“app_hogp.c”文件中添加,包括以小端模式存储的128位uuid。
  1. const BLE_CHAR AttCharList[] = {
  2. // ======  gatt =====  Do NOT Change!!
  3.     {TYPE_CHAR,0x03,ATT_CHAR_PROP_RD, 0x04,0,0x00,0x2a,UUID16_FORMAT},//name
  4.     //05-06 reserved
  5. // ======  device info =====    Do NOT Change if using the default!!!  
  6.     {TYPE_CHAR,0x08,ATT_CHAR_PROP_RD, 0x09,0,0x29,0x2a,UUID16_FORMAT},//manufacture
  7.     {TYPE_CHAR,0x0a,ATT_CHAR_PROP_RD, 0x0b,0,0x26,0x2a,UUID16_FORMAT},//firmware version
  8.     {TYPE_CHAR,0x0c,ATT_CHAR_PROP_RD, 0x0d,0,0x50,0x2a,UUID16_FORMAT},//PnPID
  9.     {TYPE_CHAR,0x0e,ATT_CHAR_PROP_RD, 0x0f,0,0x28,0x2a,UUID16_FORMAT},//sw version   
  10.    
  11.     // ======  HID =====
  12.     //    {TYPE_INC, 0x1a,},//include, hard code!!!
  13.     {TYPE_INC, 0x001a,0x2b,0x00, 0x2d,0x00, 0x0a,0xa0}, //hard code uuid-0aa0, I just share the memory
  14.     {TYPE_CHAR,0x1B,ATT_CHAR_PROP_RD|ATT_CHAR_PROP_W_NORSP,0x1c,0, 0x4e,0x2a,UUID16_FORMAT},//protocol mode
  15.     {TYPE_CHAR,0x1d,ATT_CHAR_PROP_W|ATT_CHAR_PROP_RD|ATT_CHAR_PROP_NTF, 0x1e,0,0x4d,0x2a,UUID16_FORMAT},//report
  16.     {TYPE_CFG, 0x1f,ATT_CHAR_PROP_RD|ATT_CHAR_PROP_W},//cfg
  17.     {TYPE_RpRef,0x20,ATT_CHAR_PROP_RD},//Report Reference
  18.    
  19.     {TYPE_CHAR,0x21,ATT_CHAR_PROP_RD, 0x22,0,0x4b,0x2a,UUID16_FORMAT},//report map
  20.     {TYPE_xRpRef,0x23,ATT_CHAR_PROP_RD},//External Report Reference
  21.    
  22.     {TYPE_CHAR,0x24,ATT_CHAR_PROP_W|ATT_CHAR_PROP_RD|ATT_CHAR_PROP_NTF,0x25,0,0x33,0x2a,UUID16_FORMAT},//boot mouse input report
  23.     {TYPE_CFG, 0x26,ATT_CHAR_PROP_RD|ATT_CHAR_PROP_W},//cfg
  24.    
  25.     {TYPE_CHAR,0x27,ATT_CHAR_PROP_RD,                      0x28,0,0x4a,0x2a,UUID16_FORMAT},//hid info
  26.     {TYPE_CHAR,0x29,ATT_CHAR_PROP_W_NORSP,                 0x2a,0,0x4c,0x2a,UUID16_FORMAT},//hid control point
  27.     // ======  0xa00a  ======    include uuid
  28.     {TYPE_CHAR,0x2c,ATT_CHAR_PROP_RD, 0x2d,0,0x0b,0x0a,UUID16_FORMAT},//
  29.    
  30.     // ======  battery service  ======   
  31.     {TYPE_CHAR,0x2f,ATT_CHAR_PROP_RD|ATT_CHAR_PROP_NTF,    0x30,0,0x19,0x29,UUID16_FORMAT},//battery level
  32.     {TYPE_CFG, 0x31,ATT_CHAR_PROP_RD|ATT_CHAR_PROP_W},//cfg
  33.    
  34.     // ======  scan prameter service  ======        
  35.     {TYPE_CHAR,0x33,ATT_CHAR_PROP_W_NORSP,    0x34,0,0x4f,0x2a,UUID16_FORMAT},//Scan Interval Window
  36.     {TYPE_CHAR,0x35,ATT_CHAR_PROP_NTF,    0x36,0,0x31,0x2a,UUID16_FORMAT},//Scan Refresh
  37.     {TYPE_CFG, 0x37,ATT_CHAR_PROP_RD|ATT_CHAR_PROP_W},//cfg
  38. };
HID的规范协议数据结构
  1. const u8 Hid_map[]= {
  2.     //first Id
  3.     0x05, 0x01, //standard keyboard    Usage Page(global)Generic Desktop Controls
  4.     0x09, 0x06, //Usage (local) Keyboard
  5.     0xA1, 0x01, //collection((Application)
  6.        
  7.     0x85, 0x01, //report ID
  8.     0x05, 0x07, //Keyboard/Keypad
  9.     0x19, 0xE0, //Usage Minimum
  10.     0x29, 0xE7, //Usage Maximum
  11.     0x15, 0,      //Logical Minimum
  12.     0x25, 1,      //Logical Maximum
  13.    
  14.     0x75, 1,       //Report Size(1 bit)
  15.     0x95, 8,       //Report Count(8)
  16.     0x81, 2,       //input(2) - variable absolute data
  17.    
  18.     0x95, 1,       //Report Count(1)
  19.     0x75, 0x08, //Report Size(8 bit)
  20.     0x81, 3,      //input(3) - variable absolute constant, for OEM data usage
  21.    
  22.     0x95, 5,    //Report Count(5)
  23.     0x75, 1,    //Report Size(1 bit)
  24.     5, 8,          //Usage Page(global)LED
  25.     0x19, 1,    //Usage Minimum
  26.     0x29, 5,    //Usage Maximum       
  27.     0x91, 2,    //output(2) - variable absolute data
  28.    
  29.     0x95, 1,    //Report Count(1)
  30.     0x75, 3,    //Report Size(3 bit)
  31.     0x91, 3,    //output(3) - variable absolute constant
  32.    
  33.     0x95, 6,     //Report Count(6)
  34.     0x75, 8,     //Report Size(8 bit)
  35.     0x15, 0,     //Logical Minimum
  36.     0x25, 0xff, //Logical Maximum
  37.     5, 7,           //Keyboard/Keypad
  38.     0x19, 0,     //Usage Minimum
  39.     0x29, 0xff, //Usage Maximum
  40.     0x81, 0,    //input(0) - array absolute data
  41.     0xc0,        //END collection
  42.    
  43.     // Second ID
  44.     0x05, 0x0c, //Consumer
  45.     0x09, 0x01, //Consumer Control
  46.     0xA1, 0x01, //collection
  47.     0x85, 0x02,//report ID
  48.    
  49.     0x15, 0x00,//Logical Minimum
  50.     0x25, 0x01,//Logical Maximum
  51.     0x75, 0x01,//Report Size(1 bit)
  52.     0x95, 0x1e,//Report Count(30)
  53.    
  54.     //first item start
  55.     0x09, 0x30, //power   
  56.     0x09, 0xb0, //play
  57.     0x09, 0xb1, //pause
  58.     0x09, 0xb2, //record
  59.     0x09, 0xb3, //FF
  60.     0x09, 0xb4, //FB   
  61.     0x09, 0xb5, //next     
  62.     0x09, 0xb6, //pre
  63.    
  64.     0x09, 0xb8, //reject
  65.     0x09, 0xb9, //random play   
  66.     0x09, 0xe2, //Mute   
  67.     0x09, 0xe9, //V+
  68.     0x09, 0xea, //V-
  69.     0x09, 0x95, //help   
  70.     0x0a, 0x24, 0x02, //AC back
  71.     0x0a, 0x25, 0x02, //AC forward
  72.    
  73.     0x0a, 0x26, 0x02, //AC stop
  74.     0x0a, 0x27, 0x02, //AC refresh
  75.     0x0a, 0x21, 0x02, //AC search
  76.     0x0a, 0x2a, 0x02, //AC bookmarks
  77.     0x0a, 0x23, 0x02, //AC Home
  78.     0x0a, 0x8a, 0x01, //AL email reader   
  79.     0x0a, 0x83, 0x01, //AL consumer Contrl Configuration
  80.     0x0a, 0x94, 0x01, //AL browser
  81.    
  82.     0x0a, 0x92, 0x01, //AL calculater
  83.     0x0a, 0x09, 0x02, //AC property
  84.     0x0a, 0x7f, 0x02, //AC view clock
  85.     0x0a, 0x33, 0x02, //scroll up
  86.     0x0a, 0x34, 0x02, //scroll down
  87.     0x0a, 0x1F, 0x02, //AC Find
  88.    
  89.     //end
  90.     0x81, 0x02,  //input(2) - variable absolute data
  91.     0x95, 0x01,  //Report Count(30)
  92.     0x75, 0x02,  //Report Size(2 bit)
  93.     0x81, 0x03,  //input(3) - variable absolute constant
  94.     0xc0,            //end collection   
  95. };
     手机拍照功能控制
  1. /***********************************************************************
  2. **function: NotifyApplePhoto
  3. **@brief    This function is apple photo hid photo capture, hard code
  4. **
  5. **@param    None.
  6. **
  7. **@return
  8. ************************************************************************/
  9. u8 NotifyApplePhoto(void)//apple photo hid photo capture, hard code
  10. {
  11.     u8 Keyarray[5] = {2,0,8,0,0}; //VolUp,hard code
  12.     sconn_notifydata(Keyarray,5);
  13.     Keyarray[2] = 0;
  14.     sconn_notifydata(Keyarray,5);
  15.     return 1;
  16. }
  17. /*******************************************************************
  18. **function: NotifyKey
  19. **@brief    This function is hid standard keyboard key, hardcode
  20. **
  21. **@param    KeyIdx
  22. **
  23. **@return                None.
  24. ********************************************************************/
  25. u8 NotifyKey(u8 KeyIdx)//hid standard keyboard key, hardcode
  26. {
  27.     u8 Keyarray[9] = {1,0,0,0,0,0,0,0,0};//0xa1
  28.     Keyarray[3] = KeyIdx;
  29.     sconn_notifydata(Keyarray,9);
  30.     Keyarray[3] = 0;
  31.     sconn_notifydata(Keyarray,9);
  32.     return 1;
  33. }
  34. /***************************************************************
  35. **function: gatt_user_send_notify_data_callback
  36. **@brief    This callback function can be used to actively send data to the Bluetooth module
  37. **          The protocol stack will callback (asynchronously) this function when the system allows it. It must not block! !!
  38. **@param    None.
  39. **
  40. **@return   None.
  41. ****************************************************************/
  42. void gatt_user_send_notify_data_callback(void)
  43. {
  44.         if(key_shutter==TRUE)
  45.         {
  46.               key_shutter=FALSE;
  47.               NotifyKey(0x28);
  48.         NotifyApplePhoto();       
  49.         }
  50. }
    根据原理图,我们可以知道K4连接到MCU的GPIOB11。
原理图.png
      工程编译完成后下载,自动重启
编译下载ok.png
      然后打开手机蓝牙,搜索到“MindMotion-Shutter”,并建立连接
连接蓝牙.jpg
      接着打开手机的相机应用,放在距离开发板10米以内的地方,此时再通过按下开发板中的K4键,即能完成拍照功能。
照片.jpg

       此次分享就到这里,后续再扩展其它功能啦,感谢各位网友来访,谢谢上海灵动微电子的赞助,面包社区提供的平台。
DS_MM32W3xxB_nc_V1.10_SC.pdf (1.28 MB, 下载次数: 3)