STM32F401玩了这么久,USB、蓝牙、姿态融合、现在做一个空中体感鼠标,作为一个阶段性总结
也把当时的项目做完吧
【CANNON申请】空中蓝牙飞鼠
https://bbs.elecfans.com/jishu_542842_1_1.html
整体的方案如下
对电脑采用USB(Device)HID Mouse 实际免驱USB 鼠标
相关链接
【CANNON试用体验】USB接口问题分析与解决
https://bbs.elecfans.com/jishu_548235_1_1.html
【CANNON试用体验】USB HID 鼠标
https://bbs.elecfans.com/jishu_550015_1_1.html
空中传输是采用蓝牙4.1 模块一 BLUE Central(Client) 、模块二BLUE Peripheral(Server)
相关链接
【CANNON试用体验】BlueNRG-MS蓝牙4.1
https://bbs.elecfans.com/jishu_553253_1_1.html
【CANNON试用体验】BlueNRG-MS蓝牙4.1驱动程序
https://bbs.elecfans.com/jishu_553274_1_1.html
体感(姿态融合算法)
相关连接
【CANNON试用体验】传感器——LSM6DS3 加速度计 陀螺仪
https://bbs.elecfans.com/jishu_550022_1_1.html
【CANNON试用体验】6DOF姿态融合算法
https://bbs.elecfans.com/jishu_550360_1_1.html
相关关键代码
- #include "sensor_service.h"
- #include "sensor_user.h"
- /** @addtogroup X-CUBE-BLE1_Applications
- * @{
- */
- /** @addtogroup SensorDemo
- * @{
- */
- /** @defgroup SENSOR_SERVICE
- * @{
- */
- /** @defgroup SENSOR_SERVICE_Private_Variables
- * @{
- */
- /* Private variables ---------------------------------------------------------*/
- #include "bluenrg_sdk_api.h"
- uint16_t tx_handle,rx_handle;/*用于Central (client) 记录UUID的句柄
- rx_handle Central (client) 发送 Peripheral (server) RXCharHandle 接收
- tx_handle Central (client) 接收 Peripheral (server) TXCharHandle 发送
- */
- uint16_t sampleServHandle, TXCharHandle, RXCharHandle;
- volatile uint8_t start_read_tx_char_handle = FALSE;
- volatile uint8_t start_read_rx_char_handle = FALSE;
- volatile uint8_t end_read_tx_char_handle = FALSE;
- volatile uint8_t end_read_rx_char_handle = FALSE;
- #ifdef THROUGHPUT_TEST
- uint8_t throughput_test = 1; /* enable the test for the estimation of the throughput */
- #else
- uint8_t throughput_test = 0; /* disable the test for the estimation of the throughput */
- #endif
- #define NUM_PACKETS 500 // Only used for throughput test (define THROUGHPUT_TEST)
- /**
- * @}
- */
- /** @defgroup SENSOR_SERVICE_Private_Macros
- * @{
- */
- /* Private macros ------------------------------------------------------------*/
- #define COPY_UUID_128(uuid_struct, uuid_15, uuid_14, uuid_13, uuid_12, uuid_11, uuid_10, uuid_9, uuid_8, uuid_7, uuid_6, uuid_5, uuid_4, uuid_3, uuid_2, uuid_1, uuid_0)
- do {
- uuid_struct[0] = uuid_0; uuid_struct[1] = uuid_1; uuid_struct[2] = uuid_2; uuid_struct[3] = uuid_3;
- uuid_struct[4] = uuid_4; uuid_struct[5] = uuid_5; uuid_struct[6] = uuid_6; uuid_struct[7] = uuid_7;
- uuid_struct[8] = uuid_8; uuid_struct[9] = uuid_9; uuid_struct[10] = uuid_10; uuid_struct[11] = uuid_11;
- uuid_struct[12] = uuid_12; uuid_struct[13] = uuid_13; uuid_struct[14] = uuid_14; uuid_struct[15] = uuid_15;
- }while(0)
- /*
- UUIDs:
- D973F2E0-B19E-11E2-9E96-0800200C9A66
- D973F2E1-B19E-11E2-9E96-0800200C9A66
- D973F2E2-B19E-11E2-9E96-0800200C9A66
- */
- #define COPY_TXRX_SERVICE_UUID(uuid_struct) COPY_UUID_128(uuid_struct,0x66,0x9a,0x0c,0x20,0x00,0x08,0x96,0x9e,0xe2,0x11,0x9e,0xb1,0xe0,0xf2,0x73,0xd9)
- #define COPY_TX_CHAR_UUID(uuid_struct) COPY_UUID_128(uuid_struct,0x66,0x9a,0x0c,0x20,0x00,0x08,0x96,0x9e,0xe2,0x11,0x9e,0xb1,0xe1,0xf2,0x73,0xd9)
- #define COPY_RX_CHAR_UUID(uuid_struct) COPY_UUID_128(uuid_struct,0x66,0x9a,0x0c,0x20,0x00,0x08,0x96,0x9e,0xe2,0x11,0x9e,0xb1,0xe2,0xf2,0x73,0xd9)
- /* Store Value into a buffer in Little Endian Format */
- #define STORE_LE_16(buf, val) ( ((buf)[0] = (uint8_t) (val) ) ,
- ((buf)[1] = (uint8_t) (val>>8) ) )
- /**
- * @}
- */
- /** @defgroup SENSOR_SERVICE_Exported_Functions
- * @{
- */
- /*
- * @brief Add TXRX service using a vendor specific profile.
- * @param None
- * @retval Status
- */
- tBleStatus Add_TXRX_Service(void)
- {
- tBleStatus ret;
- uint8_t uuid[16];
- COPY_TXRX_SERVICE_UUID(uuid);
- ret = aci_gatt_add_serv(UUID_TYPE_128, uuid, PRIMARY_SERVICE, 7, &sampleServHandle); /* original is 9?? */
- if (ret != BLE_STATUS_SUCCESS) goto fail;
- COPY_TX_CHAR_UUID(uuid);
- ret = aci_gatt_add_char(sampleServHandle, UUID_TYPE_128, uuid, 20, CHAR_PROP_NOTIFY, ATTR_PERMISSION_NONE, GATT_DONT_NOTIFY_EVENTS,16, 1, &TXCharHandle);
- if (ret != BLE_STATUS_SUCCESS) goto fail;
- COPY_RX_CHAR_UUID(uuid);
- ret = aci_gatt_add_char(sampleServHandle, UUID_TYPE_128, uuid, 20, CHAR_PROP_WRITE|CHAR_PROP_WRITE_WITHOUT_RESP, ATTR_PERMISSION_NONE, GATT_NOTIFY_ATTRIBUTE_WRITE,16, 1, &RXCharHandle);
- if (ret != BLE_STATUS_SUCCESS) goto fail;
- PRINTF("Sample Service added.nTX Char Handle %04X, RX Char Handle %04Xn", TXCharHandle, RXCharHandle);
- return BLE_STATUS_SUCCESS;
- fail:
- PRINTF("Error while adding Sample Service.n");
- return BLE_STATUS_ERROR ;
- }
- /**
- * @brief Discovery TX characteristic handle by UUID 128 bits
- * @param None
- * @retval None
- */
- void startReadTXCharHandle(void)
- {
- /*Central (client)*/
- /*Central (client) 发出 aci_gatt_disc_charac_by_uuid
- When the procedure is completed, a [url=home.php?mod=space&uid=1352397]@ref[/url] EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated.
- Before procedure completion the response packets are given through @ref EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP event.
- 从EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP 得到 UUID 对应的handle
- */
- if (!start_read_tx_char_handle) {
- PRINTF("Start reading TX Char Handlen");
- uint8_t uuid[16];
- COPY_TX_CHAR_UUID(uuid);
- aci_gatt_disc_charac_by_uuid(connection_handle, 0x0001, 0xFFFF, UUID_TYPE_128, uuid);
- start_read_tx_char_handle = TRUE;
- }
- }
- /**
- * @brief Discovery RX characteristic handle by UUID 128 bits
- * @param None
- * @retval None
- */
- void startReadRXCharHandle(void)
- {
- /*Central (client)*/
- if (!start_read_rx_char_handle) {
- PRINTF("Start reading RX Char Handlen");
- uint8_t uuid[16];
- //const uint8_t charUuid128_RX[16] = {0x66,0x9a,0x0c,0x20,0x00,0x08,0x96,0x9e,0xe2,0x11,0x9e,0xb1,0xe2,0xf2,0x73,0xd9};
- COPY_RX_CHAR_UUID(uuid);
- aci_gatt_disc_charac_by_uuid(connection_handle, 0x0001, 0xFFFF, UUID_TYPE_128, uuid);
- start_read_rx_char_handle = TRUE;
- }
- }
- /**
- * @brief This function is used to receive data related to the sample service
- * (received over the air from the remote board).
- * @param data_buffer : pointer to store in received data
- * @param Nb_bytes : number of bytes to be received
- * @retval None
- */
- void receiveData(uint8_t* data_buffer, uint8_t Nb_bytes)
- {
- BSP_LED_Toggle(LED2);
- for(int i = 0; i < Nb_bytes; i++) {
- PRINTF("%c", data_buffer[i]);
- }
- Mouse_Report_Send(data_buffer);
- }
- /**
- * @brief This function is used to send data related to the sample service
- * (to be sent over the air to the remote board).
- * @param data_buffer : pointer to data to be sent
- * @param Nb_bytes : number of bytes to send
- * @retval None
- */
- void sendData(uint8_t* data_buffer, uint8_t Nb_bytes)
- {
- if(BLE_Role == SERVER) {
- if (throughput_test) {
- //uint8_t test_end = FALSE;
- //uint32_t packets = 0;
- do {
- uint8_t data[20] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F',0,0,0,0};
- static uint32_t packets = 0;
- static tClockTime time, time2;
- HOST_TO_LE_32(data+16, packets);
- if(packets==0) {
- PRINTF("Test startn");
- time = Clock_Time();
- }
- struct timer t;
- Timer_Set(&t, CLOCK_SECOND*10);
- while(aci_gatt_update_char_value(sampleServHandle, TXCharHandle, 0, 20, data)==BLE_STATUS_INSUFFICIENT_RESOURCES) {
- // Radio is busy (buffer full).
- //PRINTF("Radio is busy (buffer full)n");
- if(Timer_Expired(&t)) {
- break;
- }
- }
- packets++;
- if(packets != 0 && packets%NUM_PACKETS == 0) {
- time2 = Clock_Time();
- tClockTime diff = time2-time;
- PRINTF("%d packets. Elapsed time: %d ms. App throughput: %d kbps.n", NUM_PACKETS, diff, (int)((float)NUM_PACKETS*20*8/diff));
- time = Clock_Time();
- //test_end = TRUE;
- }
- } while(1/*!test_end*/);
- } else {
- aci_gatt_update_char_value(sampleServHandle,TXCharHandle, 0, Nb_bytes, data_buffer);
- }
- } else {
- /*Central (client)*/
- aci_gatt_write_without_response(connection_handle, rx_handle+1, Nb_bytes, data_buffer);
- }
- }
- /******************************************************************************
- bluenrg_sdk_api.c 移植函数
- ******************************************************************************/
- #include "bluenrg_sdk_api.h"
- tBleStatus ble_device_user_add_service(void)
- {
- /**<
- 添加用户UUID 被 ble_device_init调用
- */
-
- ret = Add_TXRX_Service();
- if(ret == BLE_STATUS_SUCCESS)
- PRINTF("TXRX service added successfully.n");
- else
- PRINTF("Error while adding TXRX service.n");
- /* USER CODE END */
- if(ret != BLE_STATUS_SUCCESS) {
- PRINTF("Error while adding service.n");
- return BLE_STATUS_ERROR ;
- }
- PRINTF("Service added successfully.n");
- return BLE_STATUS_SUCCESS;
- }
- void ble_user_process(void)
- {
- /* 用户任务 一般多用于 Central (client) 获取 Peripheral (server) 的uuid 对应的 handle
- */
- if(BLE_Role == CLIENT) {
- /* Start TX handle Characteristic dynamic discovery if not yet done */
- if (connected && !end_read_tx_char_handle) {
- startReadTXCharHandle();
- }
- /* Start RX handle Characteristic dynamic discovery if not yet done */
- else if (connected && !end_read_rx_char_handle) {
- startReadRXCharHandle();
- }
- if(connected && end_read_tx_char_handle && end_read_rx_char_handle && !notification_enabled) {
- BSP_LED_Off(LED2); //end of the connection and chars discovery phase
- enableNotification();
- }
- }
- }
- void ble_on_disconnect_cb(uint8_t reason)
- {
- /**<
- HCI_Event_CB 调用 GAP DisconnectionComplete Callback funciton
- 断开连接事件
- 当原来连接的BLE设备断开后,系统会触发该事件
- 该函数内部用于处理BLE设备断开后需要执行的任务
- */
- connected = FALSE;
- PRINTF("Disconnectedrn");
- /* Make the device connectable again. */
- set_connectable = TRUE;
- notification_enabled = FALSE;
- /* USER CODE BEGIN */
- start_read_tx_char_handle = FALSE;
- start_read_rx_char_handle = FALSE;
- end_read_tx_char_handle = FALSE;
- end_read_rx_char_handle = FALSE;
- /* USER CODE END */
- /* Make the device connectable again. */
- //ble_device_start_advertising();//because set_connectable = TRUE; ble_process while auto advertising
- }
- void ble_on_gatt_notification_cb(uint16_t attr_handle, uint8_t attr_len, uint8_t *attr_value)
- {
- /* This event is generated when a notification is received from the server */
- /* server 修改UUID 才会被调用 */
- /* USER CODE BEGIN */
- if (throughput_test && BLE_Role == CLIENT) {
- static tClockTime time, time2;
- static uint32_t packets=0;
- static uint32_t n_packet1, n_packet2, lost_packets = 0;
- if(attr_handle == tx_handle+1) {
- if(packets==0) {
- PRINTF("Test startn");
- time = Clock_Time();
- n_packet1 = LE_TO_HOST_32(attr_value+16) - 1;
- }
- n_packet2 = LE_TO_HOST_32(attr_value+16);
- if(n_packet2 != n_packet1 + 1) {
- lost_packets += n_packet2-(n_packet1+1);
- }
- n_packet1 = n_packet2;
- packets++;
- //PRINTF("packet %dn", packets);
- if(packets != 0 && packets%NUM_PACKETS == 0) {
- time2 = Clock_Time();
- tClockTime diff = time2-time;
- PRINTF("%d packets. Elapsed time: %d ms. App throughput: %d kbps.n", NUM_PACKETS, diff, (int)((float)NUM_PACKETS*20*8/diff));
- if(lost_packets) {
- PRINTF("%d lost packet(s)n", lost_packets);
- }
- time = Clock_Time();
- lost_packets=0;
- }
- }
- } else if(BLE_Role == CLIENT) {
- if(attr_handle == tx_handle+1) {
- receiveData(attr_value, attr_len);
- }
- }
- /* USER CODE END */
- }
- void ble_on_gatt_dis_read_char_by_uuid_resp_cb(evt_gatt_disc_read_char_by_uuid_resp *resp)
- {
- /*Central (client)*/
- /*
- This event can be generated during a "Discover Characteristics By UUID" procedure or a "Read using Characteristic UUID" procedure.
- */
- /* USER CODE BEGIN */
- //evt_gatt_disc_read_char_by_uuid_resp *resp = (void*)blue_evt->data;
- PRINTF("The Handle for Discover Characteristics By UUID %04Xn", resp->attr_handle);
- if (start_read_tx_char_handle && !end_read_tx_char_handle) {
- tx_handle = resp->attr_handle;
- PRINTF("TX Char Handle %04Xn", tx_handle);
- } else if (start_read_rx_char_handle && !end_read_rx_char_handle) {
- rx_handle = resp->attr_handle;
- PRINTF("RX Char Handle %04Xn", rx_handle);
- }
- /* USER CODE END */
- }
- void ble_on_gatt_procedure_complete_cb( evt_gatt_procedure_complete *pr)
- {
- /*
- This event is generated when a GATT client procedure completes either with error or successfully.
- */
- /* USER CODE BEGIN */
- PRINTF("The Handle for a GATT client procedure completes %04Xn", pr->conn_handle);
- if (start_read_tx_char_handle && !end_read_tx_char_handle) {
- end_read_tx_char_handle = TRUE;
- } else if (start_read_rx_char_handle && !end_read_rx_char_handle) {
- end_read_rx_char_handle = TRUE;
- }
- /* USER CODE END */
- }
- /******************************************************************************
- 其他任务函数
- ******************************************************************************/
- void ble_user_tx_data_process(void)
- {
- /* Check if the user has pushed the button */
- if(connected && notification_enabled) {
- AHRS_output AHRSOutput;
- uint8_t data[4] = {0,0,0,0};
- int8_t * px = (int8_t *)(&data[1]);
- int8_t * py = (int8_t *)(&data[2]);
- Motion_Getdata(&AHRSOutput);
- * px = (((int8_t)AHRSOutput.Roll)/5)*4;
- * py = (((int8_t)AHRSOutput.Pitch)/5)*3;
- if(BSP_PB_GetState(BUTTON_KEY) == RESET)
- data[0]=0x01;/* 按键 0bit 左; 1bit 中; 2bit 右*/
- sendData(data, sizeof(data));
- //BSP_LED_Toggle(LED2); // toggle the LED2 locally.
- // If uncommented be sure BSP_LED_Init(LED2) is
- // called in main().
- // E.g. it can be enabled for debugging.
- }
- }
复制代码
原地址 :http://blog.sina.com.cn/s/blog_7e7fa4c80102wayr.html
QQ:1696933323
其他相关贴子
【CANNON试用体验】bootloader烧写flash
https://bbs.elecfans.com/jishu_546760_1_1.html
【CANNON试用体验】传感器——LPS25H气压计
https://bbs.elecfans.com/jishu_545921_1_1.html
【CANNON试用体验】传感器——HTS221温湿度计
https://bbs.elecfans.com/jishu_545452_1_1.html
【CANNON试用体验】硬件 吐槽
https://bbs.elecfans.com/jishu_545318_1_1.html
【CANNON试用体验】[求助]STM32F401 +SDIO+DMA 4bit 卡死
https://bbs.elecfans.com/jishu_547745_1_1.html
SDIO 读写SD卡的问题,还是没有解决,希望高手们指点一下
|