2025-10-17 4:56 AM
I want to deploy an ai custom model on the STM32H743. Are there any relevant tutorials or examples?
Solved! Go to Solution.
2025-10-23 1:39 AM
Thank you! The problem has been resolved; it appears to have been an issue with the clock configuration.
2025-10-17 5:03 AM - edited 2025-10-17 6:03 AM
Hello,
Is that what you are asking for: Deploying a deep learning model on NUCLEO-H753ZI?
2025-10-17 5:58 AM
Hi @llcc,
For STM32H743, the process to deploy a model is standard, so it is not as difficult as for the N6.
The only thing to do is to download the latest version of X Cube AI in CubeMX.
Then create a project, activate X Cube AI, select the application template.
Browse for your model in the X Cube AI interface, run a analyze to make sure that your model is being compiled correctly, then generate the code with cubeMX and that's it.
Have a good day,
Julian
2025-10-17 11:43 PM
Hi, Does the model deployed on the STM32H743 need to be quantized first like the n6, or can floating-point types be deployed directly? Additionally: After the deployment is completed, how should I pass the data to the model for inference and obtain the inference results? If using serial communication for data transmission, do I need to additionally configure the serial port and clock in CubeMX? Is there example code for specifically passing input samples via serial communication? Thanks!
2025-10-18 8:47 AM
But I want to customize my input and output the result through the serial port. How should I do this?Thanks!
2025-10-19 4:45 AM
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : main.c
* @brief : Main program body
******************************************************************************
* @attention
*
* Copyright (c) 2025 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 "app_x-cube-ai.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <string.h> // 用于 strlen()
#include <stdbool.h> // 添加bool类型支持
#include <stdio.h> // 添加sprintf支持
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
UART_HandleTypeDef huart3;
DMA_HandleTypeDef hdma_usart3_rx;
DMA_HandleTypeDef hdma_usart3_tx;
/* USER CODE BEGIN PV */
// 添加数据接收相关变量
/* 接收数据相关定义 */
#define DATA_SIZE 2048
static float input_data[DATA_SIZE]; // 存放接收后的float数据
static uint8_t uart_rx_buffer[DATA_SIZE * sizeof(float)];
static volatile uint32_t rx_index = 0;
static volatile bool receiving_data = false;
static volatile bool data_received = false;
static uint8_t rx_data; // 单字节缓存
static uint32_t last_printed = 0;
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MPU_Config(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
static void MX_USART3_UART_Init(void);
/* USER CODE BEGIN PFP */
void Start_Data_Reception(void);
void Process_Received_Data(void);
void Send_Ok_Response(void);
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MPU Configuration--------------------------------------------------------*/
MPU_Config();
/* Enable the CPU Cache */
/* Enable I-Cache---------------------------------------------------------*/
SCB_EnableICache();
/* Enable D-Cache---------------------------------------------------------*/
SCB_EnableDCache();
/* 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_DMA_Init();
MX_USART3_UART_Init();
MX_X_CUBE_AI_Init();
/* USER CODE BEGIN 2 */
// 开启字符接收中断
/* 打印提示并等待开始命令 */
char start_msg[] = "发送 'S' 开始数据传输\r\n";
HAL_UART_Transmit(&huart3, (uint8_t*)start_msg, strlen(start_msg), HAL_MAX_DELAY);
/* 启动单字节接收中断 */
HAL_UART_Receive_IT(&huart3, &rx_data, 1);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
MX_X_CUBE_AI_Process();
/* USER CODE BEGIN 3 */
uint32_t now = HAL_GetTick(); // 当前时间(毫秒)
/* === 如果当前没有在接收数据,则每隔3秒提醒一次 === */
if (!receiving_data && !data_received)
{
static uint32_t last_hint = 0;
if (now - last_hint > 3000) // 超过3秒
{
const char *msg = "发送 'S' 开始数据传输\r\n";
HAL_UART_Transmit(&huart3, (uint8_t*)msg, strlen(msg), HAL_MAX_DELAY);
last_hint = now;
}
}
if (receiving_data)
{
// 每接收512字节打印一次进度
if (rx_index / 512 != last_printed / 512)
{
char buf[50];
int len = sprintf(buf, "已接收: %lu/%lu 字节\r\n", rx_index, (uint32_t)(DATA_SIZE * sizeof(float)));
HAL_UART_Transmit(&huart3, (uint8_t*)buf, len, HAL_MAX_DELAY);
last_printed = rx_index;
}
}
if (data_received)
{
data_received = 0;
receiving_data = 0;
last_printed = 0;
HAL_UART_Transmit(&huart3, (uint8_t*)"数据接收完成,前16字节:\r\n", 28, HAL_MAX_DELAY);
char buf[8];
for (int i = 0; i < 16; i++)
{
int len = sprintf(buf, "%02X ", uart_rx_buffer[i]);
HAL_UART_Transmit(&huart3, (uint8_t*)buf, len, HAL_MAX_DELAY);
}
HAL_UART_Transmit(&huart3, (uint8_t*)"\r\n✅ 数据验证完成!\r\n", 26, HAL_MAX_DELAY);
// 等待下一次 'S' 指令
HAL_UART_Receive_IT(&huart3, &rx_data, 1);
}
}
/* USER CODE END 3 */
}
/**
* @brief System Clock Configuration
* @retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Supply configuration update enable
*/
HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY);
/** Configure the main internal regulator output voltage
*/
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE3);
while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {}
/** 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_BYPASS;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 5;
RCC_OscInitStruct.PLL.PLLN = 160;
RCC_OscInitStruct.PLL.PLLP = 2;
RCC_OscInitStruct.PLL.PLLQ = 2;
RCC_OscInitStruct.PLL.PLLR = 2;
RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_0;
RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;
RCC_OscInitStruct.PLL.PLLFRACN = 0;
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_CLOCKTYPE_D3PCLK1|RCC_CLOCKTYPE_D1PCLK1;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2;
RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2;
RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
{
Error_Handler();
}
}
/**
* @brief USART3 Initialization Function
* @PAram None
* @retval None
*/
static void MX_USART3_UART_Init(void)
{
/* USER CODE BEGIN USART3_Init 0 */
/* USER CODE END USART3_Init 0 */
/* USER CODE BEGIN USART3_Init 1 */
/* USER CODE END USART3_Init 1 */
huart3.Instance = USART3;
huart3.Init.BaudRate = 115200;
huart3.Init.WordLength = UART_WORDLENGTH_8B;
huart3.Init.StopBits = UART_STOPBITS_1;
huart3.Init.Parity = UART_PARITY_NONE;
huart3.Init.Mode = UART_MODE_TX_RX;
huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart3.Init.OverSampling = UART_OVERSAMPLING_16;
huart3.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
huart3.Init.ClockPrescaler = UART_PRESCALER_DIV1;
huart3.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
if (HAL_UART_Init(&huart3) != HAL_OK)
{
Error_Handler();
}
if (HAL_UARTEx_SetTxFifoThreshold(&huart3, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
{
Error_Handler();
}
if (HAL_UARTEx_SetRxFifoThreshold(&huart3, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
{
Error_Handler();
}
if (HAL_UARTEx_DisableFifoMode(&huart3) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN USART3_Init 2 */
/* USER CODE END USART3_Init 2 */
}
/**
* Enable DMA controller clock
*/
static void MX_DMA_Init(void)
{
/* DMA controller clock enable */
__HAL_RCC_DMA1_CLK_ENABLE();
/* DMA interrupt init */
/* DMA1_Stream0_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Stream0_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Stream0_IRQn);
/* DMA1_Stream1_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Stream1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Stream1_IRQn);
}
/**
* @brief GPIO Initialization Function
* @PAram None
* @retval None
*/
static void MX_GPIO_Init(void)
{
/* USER CODE BEGIN MX_GPIO_Init_1 */
/* USER CODE END MX_GPIO_Init_1 */
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOH_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/* USER CODE BEGIN MX_GPIO_Init_2 */
/* USER CODE END MX_GPIO_Init_2 */
}
/* USER CODE BEGIN 4 */
// 启动数据接收
void Start_Data_Reception(void)
{
rx_index = 0;
receiving_data = true;
data_received = false;
char ready_msg[] = "准备接收8192字节数据...\r\n";
HAL_UART_Transmit(&huart3, (uint8_t*)ready_msg, strlen(ready_msg), HAL_MAX_DELAY);
// 开始第一个字节接收
HAL_UART_Receive_IT(&huart3, &uart_rx_buffer[rx_index], 1);
}
// 处理接收到的数据
void Process_Received_Data(void)
{
char start_process_msg[] = "开始处理数据...\r\n";
HAL_UART_Transmit(&huart3, (uint8_t*)start_process_msg, strlen(start_process_msg), HAL_MAX_DELAY);
// 确保缓存数据最新
SCB_InvalidateDCache_by_Addr((uint32_t*)uart_rx_buffer, DATA_SIZE * sizeof(float));
memcpy(input_data, uart_rx_buffer, DATA_SIZE * sizeof(float));
// 调试:打印前3个float值
char debug_msg[100];
sprintf(debug_msg, "前3个数据: %.6f, %.6f, %.6f\r\n", input_data[0], input_data[1], input_data[2]);
HAL_UART_Transmit(&huart3, (uint8_t*)debug_msg, strlen(debug_msg), HAL_MAX_DELAY);
// 检查数据是否有效
if (input_data[0] == input_data[0]) { // 检查不是NaN
char valid_msg[] = "数据验证: 有效\r\n";
HAL_UART_Transmit(&huart3, (uint8_t*)valid_msg, strlen(valid_msg), HAL_MAX_DELAY);
} else {
char invalid_msg[] = "数据验证: 无效\r\n";
HAL_UART_Transmit(&huart3, (uint8_t*)invalid_msg, strlen(invalid_msg), HAL_MAX_DELAY);
}
}
// 发送OK响应
void Send_Ok_Response(void)
{
char response[] = "OK\r\n";
HAL_UART_Transmit(&huart3, (uint8_t*)response, strlen(response), HAL_MAX_DELAY);
}
// 修改原有的字符接收回调函数,添加数据接收逻辑
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if (huart->Instance == USART3)
{
if (receiving_data)
{
uart_rx_buffer[rx_index++] = rx_data;
// 继续接收下一个字节
if (rx_index < DATA_SIZE * sizeof(float))
{
HAL_UART_Receive_IT(&huart3, &rx_data, 1);
}
else
{
// 数据接收完成
receiving_data = false;
data_received = true;
}
}
else
{
// 判断是否收到 'S' 指令
if (rx_data == 'S')
{
rx_index = 0;
receiving_data = true;
data_received = false;
const char *msg = "准备接收8192字节数据...\r\n";
HAL_UART_Transmit(&huart3, (uint8_t*)msg, strlen(msg), HAL_MAX_DELAY);
HAL_UART_Receive_IT(&huart3, &rx_data, 1); // 开始接收第一个数据字节
}
else
{
// 未识别命令时继续等待
HAL_UART_Receive_IT(&huart3, &rx_data, 1);
}
}
}
}
/* USER CODE END 4 */
/* MPU Configuration */
void MPU_Config(void)
{
MPU_Region_InitTypeDef MPU_InitStruct = {0};
/* Disables the MPU */
HAL_MPU_Disable();
/** Initializes and configures the Region and the memory to be protected
*/
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER0;
MPU_InitStruct.BaseAddress = 0x0;
MPU_InitStruct.Size = MPU_REGION_SIZE_4GB;
MPU_InitStruct.SubRegionDisable = 0x87;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.AccessPermission = MPU_REGION_NO_ACCESS;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/* Enables the MPU */
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}
/**
* @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 */Now I have completed the serial port data reception (1, 1, 2048) and the model import and code generation of x_cube_ai, but I don't know how to pass the received data into the model for inference and output the results via the serial port. Could you please tell me the specific method? Thank you!
2025-10-19 9:42 PM
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : main.c
* @brief : Main program body
******************************************************************************
* @attention
*
* Copyright (c) 2025 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 "app_x-cube-ai.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <string.h> // 用于 strlen()
#include <stdbool.h> // 添加bool类型支持
#include "stdio.h"
#include "ai_platform.h"
#include "network.h"
#include "network_data.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
UART_HandleTypeDef huart2;
DMA_HandleTypeDef hdma_usart2_rx;
DMA_HandleTypeDef hdma_usart2_tx;
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MPU_Config(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
static void MX_USART2_UART_Init(void);
/* USER CODE BEGIN PFP */
void Start_Data_Reception(void);
void Process_Received_Data(void);
void Send_Ok_Response(void);
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
ai_handle network;
float aiInData[AI_NETWORK_IN_1_SIZE];
float aiOutData[AI_NETWORK_OUT_1_SIZE];
ai_u8 activations[AI_NETWORK_DATA_ACTIVATIONS_SIZE];
ai_buffer * ai_input;
ai_buffer * ai_output;
static void AI_Init(void);
static void AI_Run(float *pIn, float *pOut);
void PictureCharArrayToFloat(uint8_t *srcBuf,float *dstBuf,int len);
// 改成 float32 数据长度
#define ONE_FRAME_LEN (1 + 2048*4 + 2) // 1字节头 + 2048个float (4字节) + 2字节尾
#define UART_BUFF_LEN 9000 // 缓冲区要大于 ONE_FRAME_LEN
uint8_t uart_rx_buffer[UART_BUFF_LEN];
uint8_t uart_rx_byte = 0;
uint16_t uart_rx_length = 0;
volatile uint8_t goRunning = 0;
char message[]="hello";
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MPU Configuration--------------------------------------------------------*/
// MPU_Config();
/* Enable the CPU Cache */
/* Enable I-Cache---------------------------------------------------------*/
// SCB_EnableICache();
/* Enable D-Cache---------------------------------------------------------*/
// SCB_EnableDCache();
/* 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_DMA_Init();
MX_USART2_UART_Init();
/* USER CODE BEGIN 2 */
AI_Init();
memset(uart_rx_buffer, 0, UART_BUFF_LEN);
HAL_UART_Receive_IT(&huart2, (uint8_t *)&uart_rx_byte, 1);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
// MX_X_CUBE_AI_Process();
/* USER CODE BEGIN 3 */
Uart_send(message);
char str[10];
if (goRunning > 0)
{
if (uart_rx_length == ONE_FRAME_LEN) // 确保接收完整一帧
{
PictureCharArrayToFloat(uart_rx_buffer + 1, aiInData, 2048);
AI_Run(aiInData, aiOutData);
}
memset(uart_rx_buffer, 0, UART_BUFF_LEN);
goRunning = 0;
uart_rx_length = 0;
}
}
/* USER CODE END 3 */
}
/**
* @brief System Clock Configuration
* @retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Supply configuration update enable
*/
HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY);
/** Configure the main internal regulator output voltage
*/
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {}
/** 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_BYPASS;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 5;
RCC_OscInitStruct.PLL.PLLN = 160;
RCC_OscInitStruct.PLL.PLLP = 2;
RCC_OscInitStruct.PLL.PLLQ = 2;
RCC_OscInitStruct.PLL.PLLR = 2;
RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_2;
RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;
RCC_OscInitStruct.PLL.PLLFRACN = 0;
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_CLOCKTYPE_D3PCLK1|RCC_CLOCKTYPE_D1PCLK1;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2;
RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2;
RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
Error_Handler();
}
}
/**
* @brief USART2 Initialization Function
* @PAram None
* @retval None
*/
static void MX_USART2_UART_Init(void)
{
/* USER CODE BEGIN USART2_Init 0 */
/* USER CODE END USART2_Init 0 */
/* USER CODE BEGIN USART2_Init 1 */
/* USER CODE END USART2_Init 1 */
huart2.Instance = USART2;
huart2.Init.BaudRate = 115200;
huart2.Init.WordLength = UART_WORDLENGTH_8B;
huart2.Init.StopBits = UART_STOPBITS_1;
huart2.Init.Parity = UART_PARITY_NONE;
huart2.Init.Mode = UART_MODE_TX_RX;
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart2.Init.OverSampling = UART_OVERSAMPLING_16;
huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
huart2.Init.ClockPrescaler = UART_PRESCALER_DIV1;
huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
if (HAL_UART_Init(&huart2) != HAL_OK)
{
Error_Handler();
}
if (HAL_UARTEx_SetTxFifoThreshold(&huart2, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
{
Error_Handler();
}
if (HAL_UARTEx_SetRxFifoThreshold(&huart2, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
{
Error_Handler();
}
if (HAL_UARTEx_DisableFifoMode(&huart2) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN USART2_Init 2 */
/* USER CODE END USART2_Init 2 */
}
/**
* Enable DMA controller clock
*/
static void MX_DMA_Init(void)
{
/* DMA controller clock enable */
__HAL_RCC_DMA1_CLK_ENABLE();
/* DMA interrupt init */
/* DMA1_Stream0_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Stream0_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Stream0_IRQn);
/* DMA1_Stream1_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Stream1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Stream1_IRQn);
}
/**
* @brief GPIO Initialization Function
* @PAram None
* @retval None
*/
static void MX_GPIO_Init(void)
{
/* USER CODE BEGIN MX_GPIO_Init_1 */
/* USER CODE END MX_GPIO_Init_1 */
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOH_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/* USER CODE BEGIN MX_GPIO_Init_2 */
/* USER CODE END MX_GPIO_Init_2 */
}
/* USER CODE BEGIN 4 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle)
{
if (UartHandle->Instance == USART2) // 注意要判断是USART2
{
if(goRunning == 0)
{
if (uart_rx_length < UART_BUFF_LEN)
{
uart_rx_buffer[uart_rx_length++] = uart_rx_byte;
if (uart_rx_length >= ONE_FRAME_LEN)
goRunning = 1;
}
else
{
uart_rx_length = 0; // 缓冲溢出重置
}
}
HAL_UART_Receive_IT(&huart2, (uint8_t *)&uart_rx_byte, 1);
}
}
void Uart_send(char *str)
{
HAL_UART_Transmit(&huart2, (uint8_t *)str, strlen(str), 0xffff);
}
static void AI_Init(void)
{
ai_error err;
/* Create a local array with the addresses of the activations buffers */
const ai_handle act_addr[] = { activations };
/* Create an instance of the model */
err = ai_network_create_and_init(&network, act_addr, NULL);
if (err.type != AI_ERROR_NONE) {
printf("ai_network_create error - type=%d code=%d\r\n", err.type, err.code);
Error_Handler();
}
ai_input = ai_network_inputs_get(network, NULL);
ai_output = ai_network_outputs_get(network, NULL);
}
static void AI_Run(float *pIn, float *pOut)
{
ai_i32 batch;
ai_error err;
char logStr[100];
float maxVal = -9999;
int maxIndex = -1;
ai_input[0].data = AI_HANDLE_PTR(pIn);
ai_output[0].data = AI_HANDLE_PTR(pOut);
batch = ai_network_run(network, ai_input, ai_output);
if (batch != 1) {
err = ai_network_get_error(network);
sprintf(logStr, "AI Run Error: type=%d code=%d\r\n", err.type, err.code);
Uart_send(logStr);
Error_Handler();
}
// 输出4个结果
for (int i = 0; i < AI_NETWORK_OUT_1_SIZE; i++) {
sprintf(logStr, "Out[%d]=%.6f\r\n", i, pOut[i]);
Uart_send(logStr);
if (pOut[i] > maxVal) {
maxVal = pOut[i];
maxIndex = i;
}
}
sprintf(logStr, "Predict class: %d\r\n", maxIndex);
Uart_send(logStr);
}
void PictureCharArrayToFloat(uint8_t *srcBuf, float *dstBuf, int len)
{
memcpy(dstBuf, srcBuf, len * sizeof(float)); // 每个 float 4 字节
}
/* USER CODE END 4 */
/* MPU Configuration */
void MPU_Config(void)
{
MPU_Region_InitTypeDef MPU_InitStruct = {0};
/* Disables the MPU */
HAL_MPU_Disable();
/** Initializes and configures the Region and the memory to be protected
*/
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER0;
MPU_InitStruct.BaseAddress = 0x0;
MPU_InitStruct.Size = MPU_REGION_SIZE_4GB;
MPU_InitStruct.SubRegionDisable = 0x87;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.AccessPermission = MPU_REGION_NO_ACCESS;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/* Enables the MPU */
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}
/**
* @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 */Hello! I am trying to use the above code now, but the serial port is not returning any data. Moreover, when I use code that only configures the serial port, the serial port can send and receive data normally. However, once I add x-cube AI, it fails to return any content. Could you guide me on how to resolve this issue? Thank you!
2025-10-23 1:26 AM
HI , llcc
Please check settings , some variables are not automatically generated , like IO buffers variables
2025-10-23 1:39 AM
Thank you! The problem has been resolved; it appears to have been an issue with the clock configuration.