#include "HCBle.h" /** 接收任务 未处理好 提示: 虽然 BLE 以及 GPS都是DMA+ UART接收,但是它们都有所不同 BLE --- DMA + IDLE 中断 循环 DMA + 空闲中断触发处理 UART IDLE GPS --- DMA +固定长度 + TC中断 设置固定长度 DMA DMA传输完成中断 #{ "lat": 23.123456, "lon": 113.654321, "angle": 95.0 }\n **/ // 外部变量引入区 extern UART_HandleTypeDef huart4; extern DMA_HandleTypeDef handle_GPDMA1_Channel5; extern DMA_HandleTypeDef handle_GPDMA1_Channel4; /* 变量定义区 */ char HC_Send_Data[128]; uint8_t HC_Recevie[RX_DataSize]; // 蓝牙接收缓存 volatile uint16_t rx_index = 0; //作为接收字符串指针 volatile uint8_t data_received = 0; // 0 --- 未接收 1 --- 接收 uint8_t rx_data; //接收字符 // dma uint8_t uart_dma_rx_buf[UART_DMA_RX_BUF_SIZE]; RingBuffer ble_rx_ring = {0}; //初始化 MotorCommand cmd; LocationData current_location = {0}; float imu_angle = 0.0f; TX_EVENT_FLAGS_GROUP ble_event_flags; #define BLE_EVENT_DATA_READY 0x01 void HCBle_InitEventFlags(void) { tx_event_flags_create(&ble_event_flags, "BLE Events"); tx_event_flags_create(&system_events,"gps Events"); // tx_event_flags_create(&sensor_events,"Sensor Events"); } //初始化DMA接收函数 void HCBle_InitDMAReception(void) { HAL_UARTEx_ReceiveToIdle_IT(&huart4, uart_dma_rx_buf, UART_DMA_RX_BUF_SIZE); // HAL_UART_Receive_DMA(&huart4, uart_dma_rx_buf, UART_DMA_RX_BUF_SIZE); // HAL_UARTEx_ReceiveToIdle_DMA(&huart4, uart_dma_rx_buf, UART_DMA_RX_BUF_SIZE); // 只需要直接打开 串口空闲接收 // HAL_UARTEx_RxEventCallback --- 到时候会回调 } // 发送数据 void HCBle_SendData(char *p,...) { va_list ap; va_start(ap,p); vsprintf(HC_Send_Data,p,ap); va_end(ap); // 编译控制 #ifdef DEBUG_EN // 信息输出接口 HAL_UART_Transmit(&huart4,(uint8_t *)HC_Send_Data,strlen(HC_Send_Data),100); // HAL_UART_Transmi(&huart1,(uint8_t *)formatBuf,strlen(formatBuf),1); // 对于没有使用中断的串口发送,是需要加入一个阻塞的 #else HAL_UART_Transmit_DMA(&huart4, (uint8_t *)HC_Send_Data, strlen(HC_Send_Data)); #endif } // 对于发送数据 可以加入一个DMA // 我发现的问题 --- \n 被分开解析了 ,所以就一直进不了这个任务解析 void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size) { if (huart->Instance == UART4) { for (uint16_t i = 0; i < Size; i++) { uint8_t ch = uart_dma_rx_buf[i]; uint16_t next_head = (ble_rx_ring.head + 1) % RING_BUFFER_SIZE; if(next_head != ble_rx_ring.tail) { ble_rx_ring.buffer[ble_rx_ring.head] = ch; ble_rx_ring.head = next_head; } } tx_event_flags_set(&ble_event_flags, BLE_EVENT_DATA_READY, TX_OR); HAL_UARTEx_ReceiveToIdle_IT(&huart4, uart_dma_rx_buf, UART_DMA_RX_BUF_SIZE); } else if(huart->Instance == USART2) // gps的接收任务 { // // 根据 Size 拷贝接收到的数据 memcpy(GPS.GPS_Buffer,GPS_DMA_RX_BUF,Size); GPS.GPS_Buffer[Size] = '\0'; GPS.isGetData = 1; //数据接收标志位置为1 tx_event_flags_set(&system_events, EVENT_GPS_DATA_READY, TX_OR); //重新开启接收 HAL_UARTEx_ReceiveToIdle_IT(&huart2,GPS_DMA_RX_BUF,GPS_DMA_RX_BUF_LEN); // HAL_UARTEx_ReceiveToIdle_DMA(&huart2,GPS_DMA_RX_BUF,GPS_DMA_RX_BUF_LEN); } } // 已成功实现 Ble数值接收 void HCBle_ParseAndHandleFrame(const char *frame) { int left, right; float lat, lon, angle; if (sscanf(frame, "#{\"leftSpeed\":%d,\"rightSpeed\":%d}$", &left, &right) == 2) { cmd.LeftSpeed = left; cmd.RightSpeed = right; HCBle_SendData("left=%d, right=%d\r\n", cmd.LeftSpeed, cmd.RightSpeed); // HCBle_SendData("left=%d, right=%d\r\n", left, right); return; } HCBle_SendData("? 解析失败: %s\r\n", frame); } //为啥一直使用不了,就是一直再等待TX传输过来 // 在后台运行的一个线程;负责等待UART收到BLE数据后触发的事件,然后解析这些数据 void ble_rx_task_entry(ULONG thread_input) { HCBle_InitDMAReception(); ULONG actual_flags; static char json_buf[128]; static int idx = 0; static int parsing = 0; while (1) { tx_event_flags_get(&ble_event_flags, BLE_EVENT_DATA_READY, TX_OR_CLEAR, &actual_flags, TX_WAIT_FOREVER); while (ble_rx_ring.tail != ble_rx_ring.head) { char c = ble_rx_ring.buffer[ble_rx_ring.tail]; ble_rx_ring.tail = (ble_rx_ring.tail + 1) % RING_BUFFER_SIZE; if (!parsing) { if (c == '#') { parsing = 1; idx = 0; json_buf[idx++] = c; } continue; } if (idx < sizeof(json_buf) - 1) { json_buf[idx++] = c; if (c == '$') { json_buf[idx] = '\0'; HCBle_ParseAndHandleFrame(json_buf); parsing = 0; idx = 0; } } else { parsing = 0; idx = 0; } } } } // "#{\"lat\":%.6f,\"lon\":%.6f,\"angle\":%.2f}\n",23.123456, 113.654321, 95.0); // HCBle_SendData("#{\"lat\":%.6f,\"lon\":%.6f,\"angle\":%.2f}\n", // current_location.lat, current_location.lon, current_location.angle); void ble_tx_task_entry(ULONG thread_input) { BleMessage msg; while(1) { // HCBle_SendData("#{\"lat\":%.6f,\"lon\":%.6f,\"angle\":%.2f}\n",23.123456, 113.654321, 95.0); // tx_thread_sleep(500); if(tx_queue_receive(&ble_tx_queue,&msg,TX_WAIT_FOREVER) == TX_SUCCESS) { HCBle_SendData("#{\"lat\":%.6f,\"lon\":%.6f,\"angle\":%.1f}\n", msg.lat, msg.lon,0); } } }