描述

以下两篇文章将是这一系列最后的两篇,将对全部的代码进行剖析

开发的时间并不多,有些写的并不是最优的实现,请多指教

代码

mian.c

添加的代码段就多了

增加头文件和一些变量定义

/* USER CODE BEGIN Includes */
#include "control.h"

#define RXBUFFERSIZE  256     
char info_buffer[RXBUFFERSIZE];   
uint8_t aRxBuffer;            
uint8_t Uart1_Rx_Cnt = 0;   

#define MAGNETIC_BUFFER_LEN 8
uint8_t magnetic_buffer[MAGNETIC_BUFFER_LEN];
uint8_t Uart3_Rx_Cnt = 0;

#define CARD_BUFFER_LEN 16
uint8_t card_buffer[CARD_BUFFER_LEN];
uint8_t Uart6_Rx_Cnt = 0;

#define ULTRASONIC_BUFFER_LEN 4
uint8_t ultrasonic_left_buffer[ULTRASONIC_BUFFER_LEN];
uint8_t ultrasonic_right_buffer[ULTRASONIC_BUFFER_LEN];

enum Motor_state g_motor;

struct Robot g_robot;
struct Command g_command;

#include "ws2812.h"
int direction = 6;
uint8_t g_value_r[LED_NUM] = {0x00};
uint8_t g_value_b[LED_NUM] = {0x00};
uint8_t g_value_g[LED_NUM] = {0x00};
/* USER CODE END Includes */

这部分代码一坨,我来总结一下干了什么事儿吧
机器人初始化、电机使能和失能等。这些代码在main函数之前的同级函数,会在main函数中进行调用

/* USER CODE BEGIN 0 */
int get_key_status(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
{
    if (HAL_GPIO_ReadPin(GPIOx, GPIO_Pin) == GPIO_PIN_SET)
    {
            while(HAL_GPIO_ReadPin(GPIOx, GPIO_Pin) == GPIO_PIN_SET);
            return 1;
    }
    else
    {
            return 0;
    }
}
int robot_init()
{
    g_robot.m_speed = MOTOR_SPEED_INITIAL;
    g_robot.m_motor_left_value = MOTOR_SPEED_INITIAL;
    g_robot.m_motor_right_value = MOTOR_SPEED_INITIAL;
    //g_robot.m_motor_right_value = -g_robot.m_motor_right_value ;
    g_robot.m_target = -1;
    g_robot.m_robot_status = READY;
    g_robot.m_direction = 1;

    g_robot.m_is_derailed = 0;
    g_robot.m_change_derailed_first = 0;
    g_robot.m_is_blocked = 0;
    g_robot.m_change_block_first = 0;

    g_robot.m_obstacle_left_distance = OBSTACLE_DISTANCE_MIN+1;
    g_robot.m_obstacle_right_distance = OBSTACLE_DISTANCE_MIN+1;

    for (int i = 0 ; i < OBSTACLE_SMOOTH_NUM ; i ++)
    {
        g_robot.m_obstacle_left_distance_memory[i] = OBSTACLE_DISTANCE_MIN +1;
        g_robot.m_obstacle_right_distance_memory[i] = OBSTACLE_DISTANCE_MIN +1;
    }
    g_robot.m_obstacle_left_distance_sum = (OBSTACLE_DISTANCE_MIN +1 )*OBSTACLE_SMOOTH_NUM;
    g_robot.m_obstacle_right_distance_sum = (OBSTACLE_DISTANCE_MIN +1 )*OBSTACLE_SMOOTH_NUM;

    g_motor = MOTOR_DISABLE; 
    return 0;
}

int robot_enable()
{
    if (g_motor == MOTOR_DISABLE)
    {
        HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_1);
        HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_2); 
        HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_1);
        HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_2); 
        g_motor = MOTOR_ENABLE;
        // printf("< robot > robot enable!\n");
    }
    else
    {
        //printf("< robot > already enable!\n");
    }
    return 0;
}

int robot_disable()
{
    if (g_motor == MOTOR_ENABLE)
    {
        HAL_TIM_PWM_Stop(&htim2,TIM_CHANNEL_1);
        HAL_TIM_PWM_Stop(&htim2,TIM_CHANNEL_2);
        HAL_TIM_PWM_Stop(&htim3,TIM_CHANNEL_1);
        HAL_TIM_PWM_Stop(&htim3,TIM_CHANNEL_2); 
        g_motor = MOTOR_DISABLE;
        // printf("< robot > robot disable!\n");
    }
    else
    {
        //printf("< robot > already disable!\n");
    }

    return 0;
}

int robot_run(int motor_left_value, int motor_right_value)
{
    robot_enable();

    if (g_robot.m_direction == 1)
    {
        __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, motor_left_value);
        __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_2, 0);
        __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, 0);
        __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, motor_right_value);
    }
    else
    {
        __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, 0);
        __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_2, abs(motor_left_value));
        __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, abs(motor_right_value));
        __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 0);
    }
    g_robot.m_robot_status = RUNNING;

    //printf("< robot > running! left speed: %d, right speed: %d, direction: %d\n", 
    //g_robot.m_motor_left_value, g_robot.m_motor_right_value, g_robot.m_direction);

    return 0;
}

int robot_speed_up(int value)
{
    g_robot.m_speed = g_robot.m_speed + value * g_robot.m_direction;
    if (abs(g_robot.m_speed) >= abs(MOTOR_SPEED_MAX))
    {
        g_robot.m_speed = MOTOR_SPEED_MAX * g_robot.m_direction;
    }
    if (abs(g_robot.m_speed) <= abs(MOTOR_SPEED_MIN))
    {
        g_robot.m_speed = MOTOR_SPEED_MIN * g_robot.m_direction;
    }
    return 0;
}

int robot_speed_down(int value)
{
    g_robot.m_speed = g_robot.m_speed - value * g_robot.m_direction;
    if (abs(g_robot.m_speed) >= abs(MOTOR_SPEED_MAX))
    {
        g_robot.m_speed = MOTOR_SPEED_MAX * g_robot.m_direction;
    }
    if (abs(g_robot.m_speed) <= abs(MOTOR_SPEED_MIN))
    {
        g_robot.m_speed = MOTOR_SPEED_MIN * g_robot.m_direction;
    }
    return 0;
}

int robot_direction_reverse()
{
    g_robot.m_direction = - g_robot.m_direction;
    g_robot.m_speed = -g_robot.m_speed;
    return 0;
}


// 检查机器人是否脱轨(磁传感器)
void check_derail(void)
{
    int j = 0;
    while(g_robot.m_magnetic_status_0_1[j] == 0 && j < MAGNETIC_BUFFER_LEN)
    {
        j++;
    }
    if (j == MAGNETIC_BUFFER_LEN) // 如果磁条传感器的所有通道值都为1
    {
        g_robot.m_is_derailed = 1; // 将机器人的脱轨状态变量赋值为1, 代表脱轨了
    }
    else
    {
        g_robot.m_is_derailed = 0; // 将机器人的脱轨状态变量赋值为0, 代表没有脱轨
    }
}

// 检查机器人是否被障碍物挡住(超声传感器)
void check_block(void)
{
    // 如果左右传感器的值,均小于距离 阈值
    if (g_robot.m_obstacle_left_distance < OBSTACLE_DISTANCE_MIN || g_robot.m_obstacle_right_distance < OBSTACLE_DISTANCE_MIN )
    {
        //g_robot.m_is_blocked = 1; // 将机器人的障碍状态变量赋值为1, 代表被障碍物阻塞
    }
    else
    {
        g_robot.m_is_blocked = 0; // 将机器人的障碍状态变量赋值为0, 代表没有障碍
    }
}

// 检查并更新机器人的状态
void check_robot_status(void)
{
    check_derail(); // 检查磁条传感器,确定脱轨状态变量m_is_blocked
    check_block(); // 检查超声传感器,确定障碍状态变量m_is_blocked

    // 状态机更新的原则
    // 脱轨后,将永远保持DERAILED,直到start命令改变m_change_derailed_first变量
    // 第一次阻塞后,记住之前的状态;当不在阻塞时,需要恢复到之前的状态

    if (g_robot.m_change_derailed_first == 0) // 之前一直是没有脱轨的状态
    {
        if (g_robot.m_is_derailed == 1) // 如果一旦脱轨了
        {
            g_robot.m_robot_status = DERAILED; // 机器人的状态设置为DERAILED
            g_robot.m_change_derailed_first = 1; // 将不会再进入最外层if函数(只有start命令可以改变此变量)
        }

        else  // 如果机器人没有脱轨
        {
            if (g_robot.m_is_blocked == 1 )    // 如果机器人前方有障碍物
            {
                if (g_robot.m_change_block_first == 0) // 如果这是第一次被挡住
                { 
                    g_robot.m_robot_status_last = g_robot.m_robot_status; // 需要记住被挡住前的状态(READY 或 RUNNING)
                    g_robot.m_change_block_first = 1; // 用m_change_block_first这个标志变量,确保只进入这个if函数一次,这样才能记住block前的状态
                }
                g_robot.m_robot_status = BLOCK; // 机器人的状态设置为BLOCK
            }
            else    // 如果机器人没有脱轨也没有被挡住
            {
                // 之前的状态为BLOCK,需要从阻塞状态中恢复时
                if (g_robot.m_change_block_first == 1) // 从block第一次恢复为之前的READY或RUNNING,只进入这个函数一次
                { 
                    HAL_Delay(2000);
                    g_robot.m_robot_status = g_robot.m_robot_status_last; 
                    g_robot.m_change_block_first = 0;
                }
                // 一直是正常状态,不需要做任何处理
                else
                {

                }
            }
        }
    }

}

// 处理灯光的颜色,确保灯光颜色与机器人状态完全一致
void process_led()
{
    if (g_robot.m_robot_status == READY) // 青色:机器人准备就绪,或者正常停下
    {
        for (uint8_t i = 0 ; i < LED_NUM; i++)
        {
            g_value_r[i] = 0x00; g_value_g[i] = 0xFF; g_value_b[i] = 0xFF;
        }
    }
    else if (g_robot.m_robot_status == BLOCK) // 黄色:机器人被障碍阻塞
    {
        for (uint8_t i = 0 ; i < LED_NUM; i++)
        {
            g_value_r[i] = 0xFF; g_value_g[i] = 0xFF; g_value_b[i] = 0x00;
        }
    }
    else if (g_robot.m_robot_status == RUNNING) // 绿色:机器人正在运动
    {
        for (uint8_t i = 0 ; i < LED_NUM; i++)
        {
            g_value_r[i] = 0x00; g_value_g[i] = 0xFF; g_value_b[i] = 0x00;
        }
    }
    else if (g_robot.m_robot_status == DERAILED) // 红色:机器人脱轨
    {
        for (uint8_t i = 0 ; i < LED_NUM; i++)
        {
            g_value_r[i] = 0xFF; g_value_g[i] = 0x00; g_value_b[i] = 0x00;
        }
    }
    // 设置灯的颜色
    for (uint8_t i = 0 ; i < LED_NUM; i++)
    {
        led_set(i, g_value_r[i], g_value_g[i], g_value_b[i]);
    }
    // 开灯
    led_on();
}

// 机器人开机的灯光效果
void led_turnon(void)
{
    int j = 51;
    int k_min = 50;
    int k_max = 52;
    int phase = 1;
    while (j > 22)
    {
        for (uint8_t i = 0 ; i < LED_NUM; i++)
        {
            g_value_r[i] = 0x00; 

            if (phase == 1)
            {    
                if ( i < k_max && i > k_min)
                { 
                    g_value_g[i] = 0xFF;g_value_b[i] = 0xFF;
                }
                else
                {
                    g_value_g[i] = 0x00;g_value_b[i] = 0x00;
                }

            }
            if (phase == 2)
            {    
                if ( i > k_max || i < k_min)
                { 
                    g_value_g[i] = 0xFF;g_value_b[i] = 0xFF;
                }
                else
                {
                    g_value_g[i] = 0x00;g_value_b[i] = 0x00;
                }

            }

            led_set(i, g_value_r[i], g_value_g[i], g_value_b[i]);
        }
        j++;
        HAL_Delay(100);
        led_on();

        if (k_max == 60)
        {
            phase = 2;
            k_max = k_min;
            k_min = -1;
        }

        if (phase == 1)
        {
            k_max = k_max + 1;
            k_min = k_min - 1;
        }
        else if (phase == 2)
        {
            k_max = k_max - 1;
            k_min = k_min + 1;
        }

        if ( k_min > 22 && phase == 2 )
        {
            break;
        }
    }
}
/* USER CODE END 0 */

开机后运行一次

 /* USER CODE BEGIN 2 */
    HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_1);
    HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_2);

    HAL_UART_Receive_IT(&huart1, (uint8_t *)&aRxBuffer, 1);
    HAL_UART_Receive_IT(&huart2, magnetic_buffer, MAGNETIC_BUFFER_LEN);
    HAL_UART_Receive_IT(&huart3, card_buffer, CARD_BUFFER_LEN);
    HAL_UART_Receive_IT(&huart4, ultrasonic_left_buffer, ULTRASONIC_BUFFER_LEN);
    HAL_UART_Receive_IT(&huart5, ultrasonic_right_buffer, ULTRASONIC_BUFFER_LEN);

    robot_init();
    printf("hello FUXI ROBOT!\n");

    led_init();
    led_turnon(); // turn  , because magnetic module donnot send message to our brain 

    printf("FUXI ROBOT IS READY!\n");
  /* USER CODE END 2 */

在main函数中不断循环的部分

/* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
        // 磁条传感器及超声传感器,都需要在while循环中打开串口接收,否则数据只可以收到一次(暂时不懂为什么这样)
        HAL_UART_Receive_IT(&huart2, magnetic_buffer, MAGNETIC_BUFFER_LEN);
        HAL_UART_Receive_IT(&huart4, ultrasonic_left_buffer, ULTRASONIC_BUFFER_LEN);
        HAL_UART_Receive_IT(&huart5, ultrasonic_right_buffer, ULTRASONIC_BUFFER_LEN);

        // 主循环中不停的检查机器人的状态
        check_robot_status();

        // 灯根据机器人的状态及时改变
        process_led();

  }
  /* USER CODE END 3 */

用于处理各个传感器信息中断的代码

/* USER CODE BEGIN 4 */
int robot_walk_forward(){return 0;};
int robot_walk_rear(){return 0;};
int robot_walk_left(){return 0;};
int robot_walk_right(){return 0;};

int process_magnetic(uint8_t magnetic_buffer[MAGNETIC_BUFFER_LEN])
{
    uint8_t magnetic_value = magnetic_buffer[5];

    struct Robot r;
    r = translate_magnetic_2_motor(g_robot, magnetic_value);

    g_robot.m_motor_left_value = r.m_motor_left_value;
    g_robot.m_motor_right_value = r.m_motor_right_value;
    g_robot.m_magnetic_value = r.m_magnetic_value;
    for (int i = 0 ; i < MAGNETIC_BUFFER_LEN; i++)
    {
        g_robot.m_magnetic_status_0_1[i] = r.m_magnetic_status_0_1[i];
    }

    if (g_robot.m_robot_status == RUNNING )
    {
        robot_run(r.m_motor_left_value, r.m_motor_right_value);
    }
    else if (g_robot.m_robot_status == DERAILED || g_robot.m_robot_status == BLOCK)
    {
        robot_disable();
    }


    return 0;
}

int process_card(int card_id)
{
    if (card_id == g_robot.m_target)
    {
        printf("< robot > arrived target %d!\n", card_id);
        g_robot.m_target = -1;
        g_robot.m_robot_status = READY;
        robot_disable();
    }
    else
    {
        printf("< robot > arrived at %d!\n", card_id);
    }
    printf("< robot > state: %d, speed: %d, target: %d, left: %d, right: %d, direction:%d\n",  
        g_robot.m_robot_status, 
        g_robot.m_speed, 
        g_robot.m_target,
        g_robot.m_motor_left_value,
        g_robot.m_motor_right_value,
        g_robot.m_direction
    );
    return 0;
}

void process_ultrasonic(int channel)
{
    int left_mean, right_mean;
    if ( channel == 0)
    {
        //printf("left distance: %d!\n", g_robot.m_obstacle_left_distance);

        left_mean = (g_robot.m_obstacle_left_distance_sum + g_robot.m_obstacle_left_distance - g_robot.m_obstacle_left_distance_memory[0]) / OBSTACLE_SMOOTH_NUM;
        for (int i = 0 ; i < OBSTACLE_SMOOTH_NUM -1 ; i++)
        {
            g_robot.m_obstacle_left_distance_memory[i] = g_robot.m_obstacle_left_distance_memory[i+1];
        }
        g_robot.m_obstacle_left_distance_memory[OBSTACLE_SMOOTH_NUM-1] = g_robot.m_obstacle_left_distance;

    }
    else
    {
        //printf("right distance: %d!\n", g_robot.m_obstacle_right_distance);
        left_mean = (g_robot.m_obstacle_right_distance_sum + g_robot.m_obstacle_right_distance - g_robot.m_obstacle_right_distance_memory[0]) / OBSTACLE_SMOOTH_NUM;
        for (int i = 0 ; i < OBSTACLE_SMOOTH_NUM -1 ; i++)
        {
            g_robot.m_obstacle_right_distance_memory[i] = g_robot.m_obstacle_right_distance_memory[i+1];
        }
        g_robot.m_obstacle_right_distance_memory[OBSTACLE_SMOOTH_NUM-1] = g_robot.m_obstacle_right_distance;

    }

    if ( left_mean< OBSTACLE_DISTANCE_MIN || right_mean < OBSTACLE_DISTANCE_MIN )
    {
        //g_robot.m_is_blocked = 1;
    }
    else
    {
        g_robot.m_is_blocked = 0;
    }    

}

int process_command(char info_buffer[256])
{
    g_command = translate_infor_2_command(info_buffer);

    switch (g_command.m_command_kind)
    {
        // 如果命令是"start"
        case RUN:            
            // 首先检查机器人的状态
            check_robot_status();

            // "start"是最高级的控制指令,会忽视机器人的状态,只会考虑当前机器人是否脱轨或阻塞
            // 机器人脱轨后,必须下发start命令,否则机器人的状态将一直保持为DERAILED,没有其他命令可以改变这个状态
            // 如果机器人此时没有脱轨,也没有被障碍物阻塞
            if (g_robot.m_is_derailed != 1 && g_robot.m_is_blocked != 1 ) // no block, no derailed, 
            {
                // 可以让机器人开始运动
                robot_run(g_robot.m_motor_left_value, g_robot.m_motor_right_value);
                // 机器人的状态需要被设置成RUNNING
                g_robot.m_robot_status = RUNNING;
                g_robot.m_change_derailed_first = 0; 
                printf("< answer >< OK >[ start ]\n");
            }
            else if (g_robot.m_is_derailed == 1)
            {
                printf("< answer >< OK >[ cannot start ]: robot is derailed!\n");
            }
            else if (g_robot.m_is_blocked == 1)
            {
                printf("< answer >< OK >[ cannot start ]: robot is blocked!\n");
            }
            break;
        case STOP:
            if (g_robot.m_robot_status != DERAILED )
            {
                printf("< answer >< OK >[ stop ]\n");
                robot_disable();
                g_robot.m_robot_status = READY;
            }
            else
            {
                printf("< answer >< OK >[ already stop]: robot is derailed!\n");
            }

            break;
        case SET_SPEED:
            g_robot.m_speed = g_command.m_command_value; // speed can +/-
            printf("< answer >< OK >[ set ][ speed ]: %d\n", g_robot.m_speed );
            g_robot.m_motor_left_value = g_robot.m_speed;
            g_robot.m_motor_right_value = g_robot.m_speed;
            //g_robot.m_motor_right_value = - g_robot.m_motor_right_value;
            if (g_robot.m_robot_status == RUNNING) // + no collision + no obstacle
            {
                if (g_robot.m_speed < 0)
                {
                    g_robot.m_direction = -1;
                }
                else
                {
                    g_robot.m_direction = 1;
                }
                robot_run(g_robot.m_motor_left_value, g_robot.m_motor_right_value);
            }
            break;
        case SET_TARGET:
            check_robot_status();
            // 如果机器人当前的状态,不是脱轨,也不是阻塞
            if (g_robot.m_robot_status != DERAILED && g_robot.m_robot_status != BLOCK )
            {
                g_robot.m_target = g_command.m_command_value;
                printf("< answer >< OK >[ set ][ target ]: go to %d\n", g_robot.m_target);    
                robot_run(g_robot.m_motor_left_value, g_robot.m_motor_right_value);
                g_robot.m_robot_status = RUNNING;
            }
            else if (g_robot.m_robot_status == DERAILED )
            {
                printf("< answer >< OK >[ cannot set ][ target ]: %d, robot is derailed!\n", g_robot.m_target);    
            }
            else if (g_robot.m_robot_status == BLOCK)
            {
                printf("< answer >< OK >[ cannot set ][ target ]: %d, robot is blocked!\n", g_robot.m_target);    
            }
            break;
        case CHARGE:        
            check_robot_status();
        // 如果机器人当前的状态,不是脱轨,也不是阻塞
            if (g_robot.m_robot_status != DERAILED && g_robot.m_robot_status != BLOCK )
            {
                g_robot.m_target = g_command.m_command_value;
                printf("< answer >< OK >[ charge ]\n");
                robot_run(g_robot.m_motor_left_value, g_robot.m_motor_right_value);
                g_robot.m_robot_status = RUNNING;
            }
            else if (g_robot.m_robot_status == DERAILED )
            {
                printf("< answer >< OK >[ cannot charge ] robot is derailed!\n");    
            }
            else if (g_robot.m_robot_status == BLOCK)
            {
                printf("< answer >< OK >[ cannot charge ] robot is blocked!\n");    
            }

            break;
        case WALK_FORWARD:
            printf("< answer >< OK >[ walk ][ forward ]\n");
            robot_walk_forward();
            robot_disable();
            g_robot.m_robot_status = READY;
            break;
        case WALK_REAR:
            printf("< answer >< OK >[ walk ][ rear ]\n");
            robot_walk_rear();
            robot_disable();
            g_robot.m_robot_status = READY;
            break;
        case WALK_LEFT:
            printf("< answer >< OK >[ walk ][ left ]\n");
            robot_walk_left();
            robot_disable();
            g_robot.m_robot_status = READY;
            break;
        case WALK_RIGHT:
            printf("< answer >< OK >[ walk ][ right ]\n");
            robot_walk_right();
            robot_disable();
            g_robot.m_robot_status = READY;
            break;
        case QUERY_ALL:
            query(g_robot, g_command, g_motor, 0);
            break;
        case QUERY_STATUS:
            query(g_robot, g_command, g_motor, 1);
            break;
        case QUERY_SPEED:
            query(g_robot, g_command, g_motor, 2);
            break;
        case QUERY_TARGET:
            query(g_robot, g_command, g_motor, 3);
            break;
        case COMMAND_ERROR:
            break;
    }
    printf("< robot > state: %d, speed: %d, target: %d, left: %d, right: %d, direction:%d\n",  
        g_robot.m_robot_status, 
        g_robot.m_speed, 
        g_robot.m_target,
        g_robot.m_motor_left_value,
        g_robot.m_motor_right_value,
        g_robot.m_direction
    );
    return 0;
}




void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    UNUSED(huart);
    if (huart == &huart1)
    {

        if(Uart1_Rx_Cnt >= 255)
        {
            Uart1_Rx_Cnt = 0;
            memset(info_buffer,0x00,sizeof(info_buffer));
            HAL_UART_Transmit(&huart1, (uint8_t *)"Data overflow!", 10,0xFFFF);     
        }
        else
        {
            info_buffer[Uart1_Rx_Cnt++] = aRxBuffer;

            if(info_buffer[Uart1_Rx_Cnt-3] == ';' && info_buffer[Uart1_Rx_Cnt-2] == 0x0D && info_buffer[Uart1_Rx_Cnt-1] == 0x0A)
            {        
                process_command(info_buffer);

                Uart1_Rx_Cnt = 0;
                memset(info_buffer,0x00,sizeof(info_buffer)); 
            }
        }
        HAL_UART_Receive_IT(&huart1, (uint8_t *)&aRxBuffer, 1); 

    }
    if (huart == &huart2)
    {
        process_magnetic(magnetic_buffer);
        HAL_UART_Receive_IT(&huart2, magnetic_buffer, MAGNETIC_BUFFER_LEN);
    }
    if (huart == &huart3)
    {
        uint8_t card_id = card_buffer[15];
        process_card(card_id);
        HAL_UART_Receive_IT(&huart3, card_buffer, CARD_BUFFER_LEN);         
    }

    if (huart == &huart4)
    {
        uint8_t distance_high = ultrasonic_left_buffer[1];
        uint8_t distance_low = ultrasonic_left_buffer[2];
        uint8_t distance = distance_high * 256 + distance_low;
        g_robot.m_obstacle_left_distance = distance;

        process_ultrasonic(0);
        HAL_UART_Receive_IT(&huart4, ultrasonic_left_buffer, ULTRASONIC_BUFFER_LEN);
    }
    if (huart == &huart5)
    {
        uint8_t distance_high = ultrasonic_right_buffer[1];
        uint8_t distance_low = ultrasonic_right_buffer[2];
        uint8_t distance = distance_high * 256 + distance_low;
        g_robot.m_obstacle_right_distance = distance;    

        process_ultrasonic(1);
        HAL_UART_Receive_IT(&huart5, ultrasonic_right_buffer, ULTRASONIC_BUFFER_LEN);
    }
}
/* USER CODE END 4 */

这些代码都有注释,命名也是较为清晰的,对代码不做过多的解释。

总结

至此我们完成了一个磁条机器人的开发工作。我们也顺利的结束这一专栏吧。
之后我想会写一些关于AMR的知识和算法,敬请期待

写的不容易,欢迎各位朋友点赞并加关注,谢谢!