使用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 */ }

运行结果:

stm32之不定长接收的更多相关文章

  1. STM32 HAL库使用中断实现串口接收不定长数据

    以前用DMA实现接收不定长数据,DMA的方法接收串口助手的数据,全部没问题,不过如果接收模块返回的数据,而这些数据如果包含回车换行的话就会停止接收,例如接收:AT\r\nOK\r\n,就只能接收到AT ...

  2. STM32串口接收不定长数据原理与源程序(转)

    今天说一下STM32单片机的接收不定长度字节数据的方法.由于STM32单片机带IDLE中断,所以利用这个中断,可以接收不定长字节的数据,由于STM32属于ARM单片机,所以这篇文章的方法也适合其他的A ...

  3. STM32使用串口1配合DMA接收不定长数据,减轻CPU载荷

    STM32使用串口1配合DMA接收不定长数据,减轻CPU载荷 http://www.openedv.com/thread-63849-1-1.html 实现思路:采 用STM32F103的串口1,并配 ...

  4. STM32之串口DMA接收不定长数据

    STM32之串口DMA接收不定长数据 引言 在使用stm32或者其他单片机的时候,会经常使用到串口通讯,那么如何有效地接收数据呢?假如这段数据是不定长的有如何高效接收呢? 同学A:数据来了就会进入串口 ...

  5. Stm32使用串口空闲中断,基于队列来接收不定长、不定时数据

    串口持续地接收不定长.不定时的数据,把每一帧数据缓存下来且灵活地利用内存空间,下面提供一种方式供参考.原理是利用串口空闲中断和DMA,每当对方发来一帧完整的数据后,串口接收开始空闲,触发中断,在中断处 ...

  6. STM32 HAL库利用DMA实现串口不定长度接收方法

    参考:https://blog.csdn.net/u014470361/article/details/79206352 我这里使用的芯片是 F1 系列的,主要是利用 DMA 数据传输方式实现的,在配 ...

  7. 关于socket客户端接收不定长数据的解决方案

    #!/usr/bin/env python3.5 # -*-coding:utf8-*- """ 本实例客户端用于不断接收不定长数据,存储到变量res "&qu ...

  8. Python3的tcp socket接收不定长数据包接收到的数据不全。

    Python Socket API参考出处:http://blog.csdn.net/xiangpingli/article/details/47706707 使用socket.recv(pack_l ...

  9. 详解Python函数参数定义及传参(必备参数、关键字参数、默认可省略参数、可变不定长参数、*args、**kwargs)

    详解Python函数参数定义及传参(必备参数.关键字参数.默认可省略参数.可变不定长参数.*args.**kwargs) Python函数参数传参的种类   Python中函数参数定义及调用函数时传参 ...

随机推荐

  1. 磊哥评测之数据库:腾讯云MongoDB vs自建

    本文由云+社区发表 作者:磊哥 上期文章我们聊到了redis.这期我们来说说另一个网红nosql数据库:MongoDB.有这么一个介绍MongoDB的说法是:MongoDB是非关系数据库当中功能最丰富 ...

  2. Docker中安装WordPress

    前言 虚拟化技术风靡一时,还不层在生产环境中实践.只能是闭门造车,自己玩一玩了,接触了一下docker最简单的命令,这才自己搭建一个wordpress玩一玩. 安装wordpress之前先把本机的do ...

  3. Spring框架浅析

    一.一个简单的示例 1.引入依赖和配置 pom.xml <?xml version="1.0" encoding="UTF-8"?> <pro ...

  4. Fiddler无法正常抓取谷歌等浏览器的请求_解决方案

    1-先了解Fiddler工作原理: 正常情况下,fiddler是可以抓chrome的请求的. fiddler会自动给浏览器设置一个代理127.0.0.1端口8888,并且记忆浏览器的代理设置,所有的请 ...

  5. C# 跨进程 设置窗口owner

    窗口间跨进程通信 1. 发送方 public const int WM_InsertChart_Completed = 0x00AA; //查找窗口 [DllImport("User32.d ...

  6. 微信公众平台设置URL和Token接收接口事件推送

    最近做对接微信闪开发票-微信发票名片,里面有个接收用户提交抬头接口是微信推送事件到公众号后台,该事件将发送至开发者填写的URL(登录公众平台进入[开发者中心设置]). 开发者可通过事件推送完成数据统计 ...

  7. MySql 双主多从配置指导

    MySql 双主多从配置指导 一.背景 互联网项目为了数据的可靠性和架构的可拓展性经常会用到双主多从的数据库,来实现数据的备份.负载均衡和突发状况时数据库切换. 二.思路 配置两台数据库A.B互为主从 ...

  8. ES6 Module export与import复合使用

    export与import复合使用 基本语法 export {...} from '文件'; 等价于 import {...} from "文件": export {...} 先加 ...

  9. i的二次幂求和

    \(i^2\)求和 老祖宗告诉我们\(\sum_{i=1}^n i^2 = \frac{n(n+1)(2n+1)}{6}\) 但是这玩意儿是怎么出来的呢?感觉网上用立方差证明的思路太low了,今天偶然 ...

  10. CTSC 2018酱油记

    Day0 5.5 花了一上午的时间把codechef div2的前四题切了,又在zbq老司机的指导下把第五题切了 中午12:00 gryz电竞组从机房出发,临走的时候看到很多学长挺恋恋不舍的,毕竟可能 ...