| | |
| | | * Macro * |
| | | *******************************************************************************/ |
| | | // 全局状态标志 |
| | | volatile uint8_t g_bt_configured = 0; // 配置完成标志 |
| | | volatile uint8_t g_bt_paired = 0; // 配对完成标志 |
| | | volatile uint8_t g_bt_at_moded = 0; // AT_MODE |
| | | |
| | | static BT_RevState bt_state = BT_STATE_IDLE; |
| | | static char bt_buffer[50]; // 接收缓冲区 |
| | | static u8 bt_index = 0; // 当前接收位置 |
| | | |
| | | static HIDO_UINT8 l_au8BTUartRxBuf[BT_UART_RX_BUF_SIZE]; |
| | | static HIDO_UINT8 l_au8BTUartTxBuf[BT_UART_TX_BUF_SIZE]; |
| | |
| | | /******************************************************************************* |
| | | * Local Variable * |
| | | *******************************************************************************/ |
| | | // 配置函数声明 |
| | | static HIDO_UINT8 ConfigBluetoothMasterSlave(void); |
| | | static void Bluetooth_Config_Slave(void); |
| | | |
| | | // 映射函数:将 [-100,100] 映射到 [1000,2000] |
| | | static uint32_t Map(int16_t input, int16_t in_min, int16_t in_max, uint32_t out_min, uint32_t out_max) { |
| | | return (input - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; |
| | | } |
| | | // 设置电机 PWM(前进/后退) |
| | | static void Set_Motor_PWM(int16_t speed) { |
| | | uint32_t pulse = Map(speed, -100, 100, 1000, 2000); // -100~100 → 1000~2000 |
| | | __HAL_TIM_SetCompare(&MOTOR_TIM, MOTOR_CHANNEL, pulse); |
| | | } |
| | | |
| | | // 设置转向 PWM(左转/右转) |
| | | static void Set_Steering_PWM(int16_t steer) { |
| | | uint32_t pulse = Map(steer, -100, 100, 1000, 2000); // -100~100 → 1000~2000 |
| | | __HAL_TIM_SetCompare(&STEERING_TIM, STEERING_CHANNEL, pulse); |
| | | } |
| | | |
| | | |
| | | /******************************************************************************* |
| | |
| | | |
| | | } |
| | | |
| | | static void BTUsartParseDataHandler(uint8_t data) |
| | | /** |
| | | * @brief 启动 UART6 接收(启用 IDLE 中断 + DMA) |
| | | */ |
| | | void UART6_StartReceive(void) |
| | | { |
| | | switch (bt_state) |
| | | { |
| | | case BT_STATE_IDLE: |
| | | if(data!=NULL) |
| | | { |
| | | bt_state=BT_STATE_RECEIVING; |
| | | } |
| | | break; |
| | | case BT_STATE_RECEIVING: |
| | | bt_buffer[bt_index++] = data; |
| | | if (bt_index >2 && bt_buffer[bt_index-2] == '\r' && bt_buffer[bt_index-1] == '\n') { |
| | | // 检测到完整结束符 "\r\n" |
| | | bt_buffer[bt_index] = '\0'; // 添加字符串终止符 |
| | | bt_index = 0; // 重置缓冲区 |
| | | bt_state = BT_STATE_COMPLETE; |
| | | } |
| | | break; |
| | | // 清除标志位,防止上电误触发 |
| | | __HAL_UART_CLEAR_IDLEFLAG(&huart6); |
| | | |
| | | case BT_STATE_COMPLETE: |
| | | // 状态机错误,重置状态 |
| | | bt_state = BT_STATE_IDLE; |
| | | break; |
| | | } |
| | | // 使能 IDLE 中断 |
| | | __HAL_UART_ENABLE_IT(&huart6, UART_IT_IDLE); |
| | | |
| | | // 启动 DMA 接收(循环模式) |
| | | HAL_UART_Receive_DMA(&huart6, uart6_dma_rxbuf, UART6_DMA_RX_BUF_SIZE); |
| | | } |
| | | |
| | | |
| | | // 蓝牙配置函数实现 |
| | | static HIDO_UINT8 BT_Enter_ATmode(void) |
| | | |
| | | /** |
| | | * @brief 发送字符串 |
| | | */ |
| | | void UART6_SendString(const char *str) |
| | | { |
| | | HIDO_UINT8 u8RecvChar = 0; |
| | | //DBG_SerialPutString("AT+ENAT\r\n"); |
| | | Uart_Send(UART_ID_BT, (HIDO_UINT8 *) "AT+ENAT\r\n", strlen("AT+ENAT\r\n")); |
| | | while (Uart_GetChar(UART_ID_BT, &u8RecvChar) == HIDO_OK) |
| | | { |
| | | BTUsartParseDataHandler(u8RecvChar); |
| | | |
| | | // 如果数据接收完成,处理数据帧 |
| | | if (bt_state == BT_STATE_COMPLETE) |
| | | { |
| | | if(0==strcmp(bt_buffer,"\r\nOK\r\n")) |
| | | { |
| | | memset(bt_buffer, 0, 50); |
| | | bt_state = BT_STATE_IDLE; |
| | | g_bt_at_moded=1; |
| | | return BT_CONFIG_SUCCESS; |
| | | } |
| | | } |
| | | } |
| | | return BT_CONFIG_FAIL; |
| | | HAL_UART_Transmit_DMA(&huart6, (uint8_t *)str, strlen(str)); |
| | | } |
| | | |
| | | // 蓝牙断开连接 |
| | | void BT_DisConnect(void) |
| | | |
| | | /** |
| | | * @brief 发送数据数组 |
| | | */ |
| | | void UART6_SendArray(uint8_t *data, uint16_t len) |
| | | { |
| | | HIDO_UINT8 u8RecvChar = 0; |
| | | //DBG_SerialPutString("AT+ENAT\r\n"); |
| | | Uart_Send(UART_ID_BT, (HIDO_UINT8 *) "AT+ENAT\r\n", strlen("AT+ENAT\r\n")); |
| | | // delay_ms(10); |
| | | Uart_Send(UART_ID_BT, (HIDO_UINT8 *) "AT+LENC\r\n", strlen("AT+LENC\r\n")); |
| | | // delay_ms(10); |
| | | Uart_Send(UART_ID_BT, (HIDO_UINT8 *) "AT+EXAT\r\n", strlen("AT+EXAT\r\n")); |
| | | HAL_UART_Transmit_DMA(&huart6, data, len); |
| | | } |
| | | |
| | | // 蓝牙配置函数实现 |
| | | static HIDO_UINT8 BT_Get_SLaveMode(void) |
| | | |
| | | void Joystick_Process(Joystick_t *joy) |
| | | { |
| | | HIDO_UINT8 u8RecvChar = 0; |
| | | // DBG_SerialPutString("AT+ROLE\r\n"); |
| | | while (Uart_GetChar(UART_ID_BT, &u8RecvChar) == HIDO_OK) |
| | | { |
| | | BTUsartParseDataHandler(u8RecvChar); |
| | | |
| | | // 如果数据接收完成,处理数据帧 |
| | | if (bt_state == BT_STATE_COMPLETE) |
| | | { |
| | | if(0==strcmp(bt_buffer,"LAVE\r\n")) |
| | | { |
| | | memset(bt_buffer, 0, 50); |
| | | bt_state = BT_STATE_IDLE; |
| | | g_bt_configured=1; |
| | | // DBG_SerialPutString(" AT+REST\r\n");//退出指令并进入透传模式 |
| | | return BT_CONFIG_SUCCESS; |
| | | } |
| | | } |
| | | } |
| | | return BT_CONFIG_FAIL; |
| | | } |
| | | |
| | | // 蓝牙配置函数实现 |
| | | static HIDO_UINT8 BT_wait_PairMode(void) |
| | | |
| | | { |
| | | HIDO_UINT8 u8RecvChar = 0; |
| | | while (Uart_GetChar(UART_ID_BT, &u8RecvChar) == HIDO_OK) |
| | | { |
| | | BTUsartParseDataHandler(u8RecvChar); |
| | | |
| | | // 如果数据接收完成,处理数据帧 |
| | | if (bt_state == BT_STATE_COMPLETE) |
| | | { |
| | | if(0==strcmp(bt_buffer,"AT+LED1\r\n")) |
| | | { |
| | | memset(bt_buffer, 0, 50); |
| | | bt_state = BT_STATE_IDLE; |
| | | g_bt_paired = 1; |
| | | return BT_CONFIG_SUCCESS; |
| | | } |
| | | } |
| | | } |
| | | return BT_CONFIG_FAIL; |
| | | } |
| | | |
| | | // 蓝牙配置函数实现 |
| | | static HIDO_UINT8 BT_connect_status(void) |
| | | |
| | | { |
| | | HIDO_UINT8 u8RecvChar = 0; |
| | | // DBG_SerialPutString("AT+CONN\r\n"); |
| | | while (Uart_GetChar(UART_ID_BT, &u8RecvChar) == HIDO_OK) |
| | | { |
| | | BTUsartParseDataHandler(u8RecvChar); |
| | | |
| | | // 如果数据接收完成,处理数据帧 |
| | | if (bt_state == BT_STATE_COMPLETE) |
| | | { |
| | | if(0==strcmp(bt_buffer,"1\r\n")) |
| | | { |
| | | memset(bt_buffer, 0, 50); |
| | | bt_state = BT_STATE_IDLE; |
| | | g_bt_paired = 1; |
| | | return BT_CONFIG_SUCCESS; |
| | | } |
| | | } |
| | | } |
| | | return BT_CONFIG_FAIL; |
| | | } |
| | | |
| | | |
| | | // 蓝牙任务处理函数//DBG_SerialPutString("AT+SLAV\r\n");//配置从机 |
| | | static void Bluetooth_Config_Slave(void) |
| | | { |
| | | if(g_bt_configured==0) |
| | | { |
| | | if(g_bt_at_moded==0) |
| | | { |
| | | BT_Enter_ATmode(); |
| | | } |
| | | else |
| | | { |
| | | if(BT_Get_SLaveMode()) |
| | | { |
| | | g_bt_configured=1; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 主处理函数 |
| | | void Joystick_Process(Joystick_t *joy) { |
| | | // 提取 y1 控制前进/后退 |
| | | int16_t motor_val = joy->y1; // -100 ~ +100 |
| | | Set_Motor_PWM(motor_val); |
| | |
| | | // 提取 x2 控制转向 |
| | | int16_t steering_val = joy->x2; // -100 ~ +100 |
| | | Set_Steering_PWM(steering_val); |
| | | |
| | | } |
| | | |
| | | // 示例输入: "[joystick,-22,-2,0,0]" |
| | | void Parse_Joystick_Data(char *data) { |
| | | void Parse_Joystick_Data(char *data) |
| | | { |
| | | Joystick_t joy = {0}; |
| | | |
| | | if (strstr(data, "joystick") == NULL) return; |
| | | |
| | | // 跳过 "[joystick," |
| | | char *ptr = strstr(data, "joystick"); |
| | | |
| | | if (!ptr) return; |
| | | |
| | | ptr += 10; // 跳过 "joystick," |
| | | |
| | | // 解析四个整数 |
| | | char *end; |
| | | joy.x1 = strtol(ptr, &end, 10); |
| | | |
| | | if (end == ptr) return; |
| | | |
| | | ptr = end + 1; |
| | | |
| | | joy.y1 = strtol(ptr, &end, 10); |
| | | |
| | | if (end == ptr) return; |
| | | |
| | | ptr = end + 1; |
| | | |
| | | joy.x2 = strtol(ptr, &end, 10); |
| | | |
| | | if (end == ptr) return; |
| | | |
| | | ptr = end + 1; |
| | | |
| | | joy.y2 = strtol(ptr, &end, 10); |
| | |
| | | *******************************************************************************/ |
| | | HIDO_VOID BT_Poll(void) |
| | | { |
| | | if (uart6_dma_recv_len>0)//HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_13) == GPIO_PIN_RESET |
| | | { |
| | | if (uart6_dma_recv_end_flag == 1) //接收完成标志 |
| | | { |
| | | Uart_Send(UART_ID_DBG, (HIDO_UINT8 *)uart6_dma_rxbuf,uart6_dma_recv_len); |
| | | // 解析数据 |
| | | static HIDO_UINT8 l_uart6_dma_rxbuf[100]; |
| | | if (uart6_dma_recv_len > 0) //HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_13) == GPIO_PIN_RESET |
| | | { |
| | | if (uart6_dma_recv_end_flag == 1) //接收完成标志 |
| | | { |
| | | HIDO_UtilSnprintf((HIDO_CHAR *)l_uart6_dma_rxbuf, sizeof(l_uart6_dma_rxbuf), "buff=%s\r\n", uart6_dma_rxbuf); |
| | | Uart_Send(UART_ID_DBG, (HIDO_UINT8 *)l_uart6_dma_rxbuf, strlen(l_uart6_dma_rxbuf)); |
| | | // 解析数据 |
| | | Parse_Joystick_Data(uart6_dma_rxbuf); |
| | | } |
| | | uart6_dma_recv_len = 0;//清除计数 |
| | | } |
| | | |
| | | uart6_dma_recv_len = 0;//清除计数 |
| | | uart6_dma_recv_end_flag = 0;//清除接收结束标志位 |
| | | memset(uart6_dma_rxbuf, 0, UART6_DMA_RX_BUF_SIZE); |
| | | __HAL_UART_CLEAR_IDLEFLAG(&huart6); |
| | | HAL_UART_Receive_DMA(&huart6, uart6_dma_rxbuf, UART6_DMA_RX_BUF_SIZE); //重新打开DMA接收 |
| | | } |
| | | #if 0 |
| | | else if(0==g_com_map[BT_SLAVE_STATUS]) |
| | | { |
| | | // DBG_SerialPutString("AT+ENAT\r\n"); |
| | | //delay_ms(10); |
| | | DBG_SerialPutString("AT+SLAV\r\n"); |
| | | g_com_map[BT_SLAVE_STATUS]=1; |
| | | save_com_map_to_flash(); |
| | | } |
| | | #endif |
| | | } |
| | | } |
| | | |
| | | } |
| | | |