Files
ManGoWalk_STM32/fun/HCBle.c
2025-07-08 23:30:16 +08:00

221 lines
5.7 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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;
BleMessage 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;
// 这里先加入
target_rpm_L = map_speed_to_rpm(cmd.LeftSpeed);
target_rpm_R = map_speed_to_rpm(cmd.RightSpeed);
HCBle_SendData("left=%d, right=%d\r\n", cmd.LeftSpeed, cmd.RightSpeed);
// HCBle_SendData("left=%d, right=%d\r\n", left, right);
DriveBOTH(cmd.LeftSpeed,cmd.RightSpeed); //驱动电机
// DriveBOTH(cmd.LeftSpeed,cmd.RightSpeed);
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,msg.angle);
}
tx_thread_sleep(100);
}
}