一、功能介绍

项目名:基于STM32的智能配送机器人控制系统设计
项目编号:mcu-1268
单片机类型:STM32F103C8T6
具体功能:
1、通过RFID刷卡确认送餐坐标,当选择好坐标后,通过重量检测模块检测餐盘是否放在小车上,如果放在小车上,则开始送餐
2、通过一对红外循迹管进行循迹,在循迹过程中,通过超声波检测前方障碍物,当检测到障碍物距离小于设置最小值时,自动停车,并声光报警提醒,直到障碍物移除
3、通过另一个红外循迹管检测此时到达几号坐标,如果当前坐标是设置坐标,则小车停止,并语言播报“请取餐”,当拿走餐盘后,小车自动返回原点(另一个红外循迹管检测是否到达原点)
4、通过OLED显示测量的当前送餐情况“送餐中“”已送达“距离前方障碍物的距离;
5、通过4G模块将监测的数据上传到云平台然后下发到手机端,可以选择送餐的位置;
6、路线:6个定点,送一次回来一次

二、资料总览

实物资料

请添加图片描述

仿真资料

请添加图片描述

三、部分资料展示

1、实物展示

供电接口:TYPE-C
板子类型:PCB集成板,两层板(上下层覆铜接地)
器件类型:元器件基本上为插针式,个别芯片会使用贴片式。
在这里插入图片描述

2、仿真展示

仿真软件版本:proteus8.17
电路连线方式:网络标号连线方式
注意:部分实物元器件仿真中没有,仿真中会用其他工作原理相似的元件代替,这样可能导致实物程序和仿真程序不一样
在这里插入图片描述

3、原理图展示

软件版本:AD2013
电路连线方式:网络标号连线方式
注意:原理图只是画出了模块的引脚图,而并不是模块的内部结构图
在这里插入图片描述

4、PCB图展示

由原理图导出,两层板,上下覆铜接地。
在这里插入图片描述

5、系统框图

绘制软件:VISIO
在这里插入图片描述

6、软件设计流程

绘制软件:VISIO
在这里插入图片描述

7、部分程序展示

软件版本:keil5

/* USER CODE BEGIN Header */

/**********************************
作者:单片机俱乐部
网站:https://www.mcuclub.cn/
**********************************/

/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2024 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

#include "stdio.h"
#include "string.h"

#include "./DELAY/delay.h"
#include "./HC-SR04/hc-sr04.h"
#include "./MOTOR/motor.h"
#include "./HX711/hx711.h"
#include "./RFID/rfid.h"
#include "./4G/4g.h"
#include "./OLED/oled.h"


/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
	
uint8_t huart2_tx_buf[100];
#define Huart2_Send_Str(...)  HAL_UART_Transmit(&huart2,huart2_tx_buf,sprintf((char *)huart2_tx_buf,__VA_ARGS__),0xffff)		//重定义串口2发送函数


/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */

uint8_t key_num = 0;										//按键键值
uint16_t time_num = 0;									//计时值
char display_buf[32] = {0};							//显示数组

extern uint8_t air_4g_rx_buf[1024];			//4g接收数组
extern uint8_t air_4g_rx_finish;				//4g接收完成标志位

uint8_t flag_begin_5s = 0;							//5s计时开始标志位
uint8_t flag_finish_5s = 0;;						//5s计时完成标志位


#define SPEED_YK	    8  							//遥控速度
#define SPEED_XJ	    8  							//循迹速度

uint16_t motor_speed = SPEED_YK;				//直流电机速度值
uint8_t flag_control = 0;							  //控制标志位
uint8_t flag_direction = 0;							//方向标志位

extern uint8_t flag_speed_control;			//速度控制标志位

uint16_t distance_value = 0;						//距离值
uint16_t distance_max = 60;							//距离最大值
uint16_t distance_min = 30;							//距离最小值

uint8_t rfid_cmd = 0;										//RFID操作指令
uint8_t rfid_step = 0;									//RFID状态步骤
uint8_t RFID_ID[4];											//RFID ID信息
uint8_t const RFID_DefKey[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
uint8_t RFID_RwBuf[16];									//RFID数据
uint16_t rfid_time = 0;									//RFID状态显示时间

uint8_t flag_maopi = 0;									//毛皮标志位
uint32_t weight_maopi = 0;							//毛皮重量
uint32_t weight_value = 0;							//去皮重量

uint16_t flag_zh = 0;										//桌号
uint16_t flag_zh_jl = 0;								//桌号记录值

uint8_t flag_jd = 0;										//计点
uint8_t flag_zt = 0;										//状态


/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */

void Monitor_Function(void);						//监测函数
void Display_Function(void);						//显示函数
void Manage_Function(void);							//处理函数


/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */


/**********************************
函数名:监测函数
传参值:无
返回值:无
**********************************/
void Monitor_Function(void)
{
	if(time_num % 100 == 0)
	{
		distance_value = Hcsr04_GetDistance(30);		//获取距离值
		
		if(flag_maopi < 3)
		{
			weight_maopi = Hx711_Get_Maopi();
			flag_maopi++;
		}
		else
		{
			weight_value = Hx711_Get_Weight(weight_maopi);
			if(weight_value < 10)
			{
				weight_value = 0;
			}
		}
		
		switch(rfid_cmd)
		{
			case 0:                         							//寻卡,成功后Temp数组为卡类型
				if(RFID_PcdRequest(0x52, RFID_ID) == MI_OK)
				{
					rfid_cmd = 1;
				}
				else
				{
					if(RFID_PcdRequest(0x52, RFID_ID) == MI_OK)
						rfid_cmd = 1;
					else
					{
						RFID_PcdHalt();
						rfid_cmd = 0;
					}
				}
			break;

			case 1:                         							//防冲突,RFID_ID数组数据为卡序列号
				if(RFID_PcdAnticoll(RFID_ID) == MI_OK)
				{
					rfid_cmd = 2;
				}
				else
				{
					RFID_PcdHalt();
					rfid_cmd = 0;
				}
			break;

			case 2:                         							//选择卡
				if(RFID_PcdSelect(RFID_ID) == MI_OK)
				{
					rfid_cmd = 3;
				}
				else
				{
					RFID_PcdHalt();
					rfid_cmd = 0;
				}
			break;

			case 3:                         							//校验卡
				if(RFID_PcdAuthState(0x60, 10, (unsigned char *)RFID_DefKey, RFID_ID) == MI_OK)
				{
					if(RFID_PcdRead(10, RFID_RwBuf) == MI_OK)
					{
						if(RFID_RwBuf[0] == 0x01)							//卡1
						{
							flag_zh = 1;
							flag_control = 5;
							
							rfid_step = 0xfa;
						}
						else if(RFID_RwBuf[0] == 0x02)				//卡2
						{
							flag_zh = 2;
							flag_control = 5;
							
							rfid_step = 0xfa;
						}
						else if(RFID_RwBuf[0] == 0x03)				//卡3
						{
							flag_zh = 3;
							flag_control = 5;
							
							rfid_step = 0xfa;
						}
						else if(RFID_RwBuf[0] == 0x04)				//卡4
						{
							flag_zh = 4;
							flag_control = 5;
							
							rfid_step = 0xfa;
						}
						else if(RFID_RwBuf[0] == 0x05)				//卡5
						{
							flag_zh = 5;
							flag_control = 5;
							
							rfid_step = 0xfa;
						}
						else if(RFID_RwBuf[0] == 0x06)				//卡6
						{
							flag_zh = 6;
							flag_control = 5;
							
							rfid_step = 0xfa;
						}
						else      														//无效卡
						{
							rfid_step = 0xfb; 
						}
					}
					
					rfid_time = 1;
				}
				else  																		//终止卡操作
				{
					RFID_PcdHalt();
					rfid_cmd = 0;
				}
			break;
		}
	}
	
	Air_4G_GetData();																//获取4G下发数据
}

/**********************************
函数名:显示函数
传参值:无
返回值:无
**********************************/
void Display_Function(void)
{
	if(time_num % 100 == 0)
	{
		Oled_ShowCHinese(1,0,"距离:");										//显示距离
		sprintf(display_buf,"%dcm  ",distance_value);	
		Oled_ShowString(1,6,display_buf);
		
		if(flag_zh != 0)																	//显示状态
		{
			if(weight_value != 0)
			{
				if(flag_zh_jl < flag_zh)
				{
					Oled_ShowCHinese(2,0,"状态:送餐中");
					flag_zt = 1;
				}
				else
				{
					Oled_ShowCHinese(2,0,"状态:已送达");
					flag_zt = 2;
				}
			}
			else
			{
				if(flag_zh_jl > 0)
				{
					Oled_ShowCHinese(2,0,"状态:返回中");
					flag_zt = 3;
				}
				else
				{
					Oled_ShowCHinese(2,0,"状态:等待中");
					flag_zt = 0;
				}
			}
		}
		else
		{
			Oled_ShowCHinese(2,0,"状态:等待中");
			flag_zt = 0;
		}
		
		Oled_ShowCHinese(3,0,"桌号:");											//显示桌号
		sprintf(display_buf,"%d  ",flag_zh);
		Oled_ShowString(3,6,display_buf);
		
		
		
		Oled_ShowCHinese(4,0,"重量:");											//显示重量
		sprintf(display_buf,"%dg  ",weight_value);
		Oled_ShowString(4,6,display_buf);
	}
}


/**********************************
函数名:处理函数
传参值:无
返回值:无
**********************************/
void Manage_Function(void)
{
	switch(flag_control)
	{
		case 0:				//停止
			motor_speed = SPEED_YK;
		
			flag_direction = 0;

			ALERT = 0;
		break;
		
		case 1:				//前进
			motor_speed = SPEED_YK;
		
			if(distance_value < distance_min)     				//当检测到障碍物距离小于最小值,右转避开障碍物
			{
				flag_direction = 4;	
				
				ALERT = 0;
			}
			else if(distance_value < distance_max)				//当检测到障碍物距离小于最大值大于最小值时,声光报警提醒
			{
				flag_direction = 1;	
				
				if(time_num % 200 == 0)
				{
					ALERT = !ALERT;
				}
			}		
			else																					//当检测到障碍物距离大于最大值时,取消声光报警,小车正常行驶
			{
				flag_direction = 1;	
				
				ALERT = 0;
			}
		break;
		
		case 2:				//后退
			motor_speed = SPEED_YK;
		
			flag_direction = 2;
		
			ALERT = 0;
		break;
		
		case 3:				//左转
			motor_speed = SPEED_YK;
		
			flag_direction = 3;
		
			ALERT = 0;
		break;
		
		case 4:				//右转
			motor_speed = SPEED_YK;
		
			flag_direction = 4;
		
			ALERT = 0;
		break;
		
		case 5:				//循迹模式
			motor_speed = SPEED_XJ;
		
			if(flag_zh != 0)																		//选择点位置
			{
				if(weight_value != 0)															//有重量
				{
					if(flag_zh_jl < flag_zh)												//还没到达指定地点
					{
						if(distance_value < distance_min)    					//当检测到障碍物距离小于最小值,小车停止,并声光报警
						{
							flag_direction = 0;	
							
							if(time_num % 200 == 0)
							{
								ALERT = !ALERT;
							}
						}
						else																					//否则,取消声光报警
						{
							if(IR_L == 1)                   						//如果左红外对管检测到黑线,小车左转
							{			
								flag_direction = 3;
							}
							else if(IR_R == 1)                 					//如果右红外对管检测到黑线,小车右转
							{
								flag_direction = 4;
							}
							else																				//否则,小车正常行驶	
							{
								flag_direction = 1;
							}
							
							ALERT = 0;
						}
						
						if(IR_P == 1)																	//检测到一个点,记录值+1
						{
							Delay_ms(10);
							if(IR_P == 1)
							{
								if(flag_jd == 0)
								{
									flag_zh_jl++;
									flag_jd = 1;
								}
							}
						}
						else
						{
							flag_jd = 0;
						}
					}
					else																						//到达指定地点,语音播报
					{
						flag_direction = 0;	
						
						if(time_num % 1500 == 0)
						{
							Huart2_Send_Str(" 请取餐");
						}
					}
				}
				else																							//重量为0
				{
					if(flag_zh_jl > 0)															//返回途中
					{
						if(distance_value < distance_min)    					//当检测到障碍物距离小于最小值,小车停止,并声光报警
						{
							flag_direction = 0;	
							
							if(time_num % 200 == 0)
							{
								ALERT = !ALERT;
							}
						}
						else																					//否则,取消声光报警
						{
							if(IR_L == 1)                   						//如果左红外对管检测到黑线,小车左转
							{			
								flag_direction = 3;
							}
							else if(IR_R == 1)                 					//如果右红外对管检测到黑线,小车右转
							{
								flag_direction = 4;
							}
							else																				//否则,小车正常行驶	
							{
								flag_direction = 1;
							}
							
							ALERT = 0;
						}
						
						if(IR_B == 1)																	//到达起始点,停车
						{
							Delay_ms(10);
							if(IR_B == 1)
							{
								if(flag_zh_jl > 0)
								{
									flag_zh = 0;
									flag_zh_jl = 0;
								}
							}
						}
					}
					else
					{
						flag_direction = 0;	
				
						ALERT = 0;
					}
				}
			}
			else
			{
				flag_direction = 0;	
				
				ALERT = 0;
			}
		break;
		
		default:
			
		break;
	}
	
	if(flag_finish_5s == 1)											//5秒上传一次数据
  {
    flag_begin_5s = 0;
    Air_4G_SendData();
    flag_begin_5s = 1;
  }
}

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{

  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_TIM1_Init();
  MX_USART1_UART_Init();
  MX_TIM2_Init();
  MX_USART2_UART_Init();
  /* USER CODE BEGIN 2 */

	Delay_Init();													//延时初始化
	HC_SR04_Init();												//HC_SR04初始化
	Motor_Init();													//电机初始化
	Hx711_Init();													//HX711初始化
	RFID_Init();													//RFID初始化
	Oled_Init();													//OLED初始化
	Oled_Clear_All();											//OLED清全屏函数
	
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
	
	HAL_TIM_Base_Start_IT(&htim1);				//启动定时器
	
	HAL_UARTEx_ReceiveToIdle_IT(&HUART_4G, air_4g_rx_buf, sizeof(air_4g_rx_buf) / sizeof(air_4g_rx_buf[0]));		//获取串口接收数据
	
	Oled_ShowString(1,7,"4G");
	Oled_ShowCHinese(2, 2, "初始化中");
	Air_4G_Init();												//4G初始化
	Oled_ShowString(3,4,"........");
	Air_4G_MQTT_Init();										//MQTT初始化
	Delay_ms(500);
	Oled_ShowString(4,4,"........");
	Delay_ms(500);
	Air_4G_SendData();										//数据上报初始状态
  flag_begin_5s = 1;										//开启定时
  Oled_Clear_All();											//清屏
	
  while (1)
  {
		Monitor_Function();									//监测函数
		Display_Function();									//显示函数
		Manage_Function();									//处理函数
		
		if(time_num % 100 == 0)							//指示灯闪烁
		{
			SYSTEM_LED = !SYSTEM_LED;
		}
		
		Delay_ms(1);												//计时
		time_num++;
		if(time_num >= 6000)
		{
			time_num = 0;
		}


    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
}

/* USER CODE BEGIN 4 */


/**********************************
函数名:定时器中断回调函数
传参值:无
返回值:无
**********************************/
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	static uint16_t motor_zhiliu_count = 0;
	static uint16_t time_count_5s = 0;

	if(htim->Instance == htim1.Instance)		//定时器1触发中断
	{
		if(flag_begin_5s == 1)
		{
			time_count_5s++;
			
			if(time_count_5s >= 5000)						//5s计时
			{
				time_count_5s = 0;
				flag_finish_5s = 1;
			}
		}
		else
		{
			time_count_5s = 0;
			flag_finish_5s = 0;
		}
		
		if(rfid_time != 0)										//RFID提示信息计时
		{
			rfid_time++;
		}
		if(rfid_time >= 2000)
		{
			rfid_time = 0;
			rfid_step = 0;
			rfid_cmd = 0;
		}
		
		motor_zhiliu_count++;
		if(motor_zhiliu_count >= 100)
		{
			motor_zhiliu_count = 0;
		}
		
		switch(flag_direction)
		{
			case 0:						//停止
				MOTOR1_IN0 = 0;
				MOTOR1_IN1 = 0;
				MOTOR1_IN2 = 0;
				MOTOR1_IN3 = 0;
			
				MOTOR2_IN0 = 0;
				MOTOR2_IN1 = 0;
				MOTOR2_IN2 = 0;
				MOTOR2_IN3 = 0;
			break;
			
			case 1:						//前
				if(motor_zhiliu_count < motor_speed)
				{
					MOTOR1_IN0 = 1;
					MOTOR1_IN1 = 0;
					MOTOR1_IN2 = 1;
					MOTOR1_IN3 = 0;
				
					MOTOR2_IN0 = 0;
					MOTOR2_IN1 = 1;
					MOTOR2_IN2 = 0;
					MOTOR2_IN3 = 1;
				}
				else
				{
					MOTOR1_IN0 = 0;
					MOTOR1_IN1 = 0;
					MOTOR1_IN2 = 0;
					MOTOR1_IN3 = 0;
					
					MOTOR2_IN0 = 0;
					MOTOR2_IN1 = 0;
					MOTOR2_IN2 = 0;
					MOTOR2_IN3 = 0;
				}
			break;
				
			case 2:						//后
				if(motor_zhiliu_count < motor_speed)
				{
					MOTOR1_IN0 = 0;
					MOTOR1_IN1 = 1;
					MOTOR1_IN2 = 0;
					MOTOR1_IN3 = 1;
				
					MOTOR2_IN0 = 1;
					MOTOR2_IN1 = 0;
					MOTOR2_IN2 = 1;
					MOTOR2_IN3 = 0;
				}
				else
				{
					MOTOR1_IN0 = 0;
					MOTOR1_IN1 = 0;
					MOTOR1_IN2 = 0;
					MOTOR1_IN3 = 0;
					
					MOTOR2_IN0 = 0;
					MOTOR2_IN1 = 0;
					MOTOR2_IN2 = 0;
					MOTOR2_IN3 = 0;
				}
			break;
			
			case 3:						//左
				if(motor_zhiliu_count < motor_speed)
				{
					MOTOR1_IN0 = 0;
					MOTOR1_IN1 = 1;
					MOTOR1_IN2 = 0;
					MOTOR1_IN3 = 1;
				
					MOTOR2_IN0 = 0;
					MOTOR2_IN1 = 1;
					MOTOR2_IN2 = 0;
					MOTOR2_IN3 = 1;
				}
				else
				{
					MOTOR1_IN0 = 0;
					MOTOR1_IN1 = 0;
					MOTOR1_IN2 = 0;
					MOTOR1_IN3 = 0;
					
					MOTOR2_IN0 = 0;
					MOTOR2_IN1 = 0;
					MOTOR2_IN2 = 0;
					MOTOR2_IN3 = 0;
				}
			break;

			case 4:						//右
				if(motor_zhiliu_count < motor_speed)
				{
					MOTOR1_IN0 = 1;
					MOTOR1_IN1 = 0;
					MOTOR1_IN2 = 1;
					MOTOR1_IN3 = 0;
				
					MOTOR2_IN0 = 1;
					MOTOR2_IN1 = 0;
					MOTOR2_IN2 = 1;
					MOTOR2_IN3 = 0;
				}
				else
				{
					MOTOR1_IN0 = 0;
					MOTOR1_IN1 = 0;
					MOTOR1_IN2 = 0;
					MOTOR1_IN3 = 0;
					
					MOTOR2_IN0 = 0;
					MOTOR2_IN1 = 0;
					MOTOR2_IN2 = 0;
					MOTOR2_IN3 = 0;
				}
			break;

			default:
			break;
		}
	}
}

/**********************************
函数名:串口事件回调函数
传参值:huart:串口号		Size:数据大小
返回值:无
**********************************/
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
	if(huart->Instance == HUART_4G.Instance)				//4g串口触发中断
	{
		HAL_UARTEx_ReceiveToIdle_IT(&HUART_4G, air_4g_rx_buf, sizeof(air_4g_rx_buf) / sizeof(air_4g_rx_buf[0]));
		air_4g_rx_finish = 1;
	}
}

/**********************************
函数名:串口错误回调函数
传参值:huart:串口号
返回值:无
**********************************/
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
{
	HAL_UART_DeInit(huart);
	HAL_UART_Init(huart);
	
	if(huart->Instance == HUART_4G.Instance)
	{
		HAL_UARTEx_ReceiveToIdle_IT(&HUART_4G, air_4g_rx_buf, sizeof(air_4g_rx_buf) / sizeof(air_4g_rx_buf[0]));
		air_4g_rx_finish = 1;
	}
}

/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐