stm32之不定长接收
2024-08-24 09:28:04
使用STM32CUBE_MAX配置工程,可以简化编程工作量,但是这样我们会遇到一些麻烦,比如利用串口接收不知道长度的数据的时候,我们可能会无从下手,前段时间看到他人程序中的串口不定长接收,此次特意总结,包括3类芯片串口不定长配置。
STM32F103ZET6
配置工程:
- 选择USART1,配置波特率为115200,并开启串口中断,DMA中断
配置程序
- 在配置工程后,我们需要在工程中printf重定向函数fputc()和重写串口接收函数 UsartReceive_IDLE()代码如下:
// 在头文件中定义结构体
#define RX_LEN 1024 typedef struct
{
uint8_t RX_flag:; //IDLE receive flag
uint16_t RX_Size; //receive length
uint8_t RX_pData[RX_LEN]; //DMA receive buffer
}USART_RECEIVETYPE; void UsartReceive_IDLE(UART_HandleTypeDef *huart);
extern USART_RECEIVETYPE UsartType1;//定义结构体
USART_RECEIVETYPE UsartType1; // printf重定向
int fputc(int ch,FILE *f)
{
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, , 0xFFFF);
return ch;
} // USART不定长接收
void UsartReceive_IDLE(UART_HandleTypeDef *huart)
{
uint32_t temp; if((__HAL_UART_GET_FLAG(huart,UART_FLAG_IDLE) != RESET)) // Checks whether the specified UART idle flag is set or not.
{
__HAL_UART_CLEAR_IDLEFLAG(huart); // Clears the UART IDLE pending flag.
HAL_UART_DMAStop(huart); // Stops the DMA Transfer.
temp = huart->hdmarx->Instance->CNDTR; // Read DMA stream x number of data register
huart->hdmarx->Instance->CNDTR = ; // Clear DMA stream x number of data register
if(huart == &huart1) // Checks whitch USART
{
UsartType1.RX_Size = RX_LEN - temp;
UsartType1.RX_flag=; // Set RX_flag
HAL_UART_Receive_DMA(&huart1,UsartType1.RX_pData,RX_LEN); // start DMA interrupt and receives an amount of data in non blocking mode.
}
}
}配置完成后,需要在xxx_it.c中断函数中添加相应串口的UsartReceive_IDLE( ) 函数
/**
* @brief This function handles USART1 global interrupt.
*/
void USART1_IRQHandler(void)
{
/* USER CODE BEGIN USART1_IRQn 0 */
UsartReceive_IDLE(&huart1);
/* USER CODE END USART1_IRQn 0 */
HAL_UART_IRQHandler(&huart1);
/* USER CODE BEGIN USART1_IRQn 1 */ /* USER CODE END USART1_IRQn 1 */
}在主函数中需要开启DMA接收中断,和串口空闲中断,程序如下:
MX_GPIO_Init();
MX_DMA_Init();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */ HAL_UART_Receive_DMA(&huart1, UsartType1.RX_pData, RX_LEN); // Receives an amount of data in non blocking mode.
__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); // Enable the specified UART interrupt. printf("**************C print 重定向*************\r\n");
printf("**********USART_IDLE 不定长接收**********\r\n"); /* USER CODE END 2 */ /* Infinite loop */
/* USER CODE BEGIN WHILE */
while ()
{
if(UsartType1.RX_flag )
{
UsartType1.RX_flag = ;
HAL_UART_Transmit(&huart1, UsartType1.RX_pData, UsartType1.RX_Size, 0xffff);
}
}
运行结果
STM32F429IGT6 & STM32F767IGT6
配置工程:
- 工程配置与 STM32F103ZET6 相同。
配置程序:
- printf重定向函数fputc()和重写串口接收函数 UsartReceive_IDLE()代码如下:
// 在头文件中定义结构体
#define RX_LEN 1024 typedef struct
{
uint8_t RX_flag:; //IDLE receive flag
uint16_t RX_Size; //receive length
uint8_t RX_pData[RX_LEN]; //DMA receive buffer
}USART_RECEIVETYPE; void UsartReceive_IDLE(UART_HandleTypeDef *huart);
extern USART_RECEIVETYPE UsartTy// printf重定向// printf重定向
int fputc(int ch,FILE *f)
{
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, , 0xFFFF);
return ch;
} // USART不定长接收
void UsartReceive_IDLE(UART_HandleTypeDef *huart)
{
uint32_t temp; if((__HAL_UART_GET_FLAG(huart,UART_FLAG_IDLE) != RESET)) // Checks whether the specified UART idle flag is set or not.
{
__HAL_UART_CLEAR_IDLEFLAG(huart); // Clears the UART IDLE pending flag.
HAL_UART_DMAStop(huart); // Stops the DMA Transfer.
temp = huart->hdmarx->Instance->NDTR; // Read DMA stream x number of data register
huart->hdmarx->Instance->NDTR = ; // Clear DMA stream x number of data register
if(huart == &huart1) // Checks whitch USART
{
UsartType1.RX_Size = RX_LEN - temp;
UsartType1.RX_flag=; // Set RX_flag
HAL_UART_Receive_DMA(&huart1, UsartType1.RX_pData, RX_LEN); // start DMA interrupt and receives an amount of data in non blocking mode.
}
}
}在xxx_it.c中断函数中添加相应串口的UsartReceive_IDLE( ) 函数
/**
* @brief This function handles USART1 global interrupt.
*/
void USART1_IRQHandler(void)
{
/* USER CODE BEGIN USART1_IRQn 0 */
UsartReceive_IDLE(&huart1);
/* USER CODE END USART1_IRQn 0 */
HAL_UART_IRQHandler(&huart1);
/* USER CODE BEGIN USART1_IRQn 1 */ /* USER CODE END USART1_IRQn 1 */
}在主函数中需要开启DMA接收中断,和串口空闲中断,程序如下:
MX_GPIO_Init();
MX_DMA_Init();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */
HAL_UART_Receive_DMA(&huart1, UsartType1.RX_pData, RX_LEN);
__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); printf("**************C print 重定向*************\r\n");
printf("**********USART_IDLE 不定长接收**********\r\n");
/* USER CODE END 2 */ /* Infinite loop */
/* USER CODE BEGIN WHILE */
while ()
{
if(UsartType1.RX_flag)
{
HAL_UART_Transmit(&huart1, UsartType1.RX_pData, UsartType1.RX_Size, 0xff);
UsartType1.RX_flag = ;
} /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ }
运行结果:
最新文章
- magento后台使用POST表单时,要使用必要参数form_key才能正常通讯
- 从零开始攻略PHP(7)——面向对象(上)
- .NET面试题解析(00)-开篇来谈谈面试 &; 系列文章索引
- 1.6.4 Uploading Structured Data Store Data with the Data Import Handler
- echo、print、print_r、printf、sprintf、var_dump的区别比较
- Shell简介:什么是Shell,Shell命令的两种执行方式
- configure: error: Cannot find libmysqlclient under /usr Note that the MySQL client library is not bundled anymore! 报错解决
- OC 代理 协议 委托 数据源的概念
- nginx+webpy 出现 upstream timed out
- keybd_event 对应表
- Java - 数组排序 -- 浅析稳定性与复杂度
- BCrypt加密算法
- TZOJ :2731: 存钱计划(二)
- PHP深入浅出之命名空间(Namespace)的使用详解
- 《JavaScript Dom 编程艺术》读书笔记-第9章
- 叠加dgv中相同的行信息
- C++11 并发之std::thread std::mutex
- Ajax 上传文件(input file FormData)
- mybatis学习之路----批量更新数据两种方法效率对比
- 深浅拷贝 python