[STM32]STM32双机串口通信

上一篇的通信方案在发送端高强度通信下寄了,发现是函数HAL_UART_Transmit()的锅,一个函数居然能跑0.3s左右。。。于是打算选用DMA收发数据,但是DMA在接收数据时遇到一些玄学问题,于是改用DMA发送数据,串口IDLE中断接收数据的策略。

cubeMX配置

接收端部分

开启USART1,打开全局中断。

发射端部分

开启USART1,开启全局中断,打开TX的DMA通道,为normal模式,内存地址自增,并打开DMA_TX的中断。

代码部分

接收端

usart.c:

  1. /* USER CODE BEGIN 0 */
  2. #include "string.h"
  3. #include "main.h"
  4. uint8_t aRxBuffer;
  5. uint8_t Uart_RxBuff[256];
  6. uint8_t Uart_Rx_Cnt;
  7. uint8_t Uart_RxFlag;
  8. uint8_t cAlmStr[] = "Warning!\r\n";
  9. int rxUpdateFlag = 0;
  10. int startReadFlag = 0;
  11. /* USER CODE END 0 */
  12. /* USER CODE BEGIN 1 */
  13. void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
  14. {
  15. /* Prevent unused argument(s) compilation warning */
  16. UNUSED(huart);
  17. if(huart == &huart1 && rxUpdateFlag == 0)
  18. {
  19. if(Uart_Rx_Cnt >= 255) // 溢出判断
  20. {
  21. Uart_Rx_Cnt = 0;
  22. memset(Uart_RxBuff,0x00,sizeof(Uart_RxBuff));
  23. HAL_UART_Transmit(&huart1, (uint8_t *)&cAlmStr, sizeof(cAlmStr),0xFFFF);
  24. }
  25. else // 没有溢出
  26. {
  27. if(aRxBuffer == '@')
  28. {
  29. startReadFlag = 1;
  30. }
  31. if(startReadFlag == 1)
  32. {
  33. Uart_RxBuff[Uart_Rx_Cnt++] = aRxBuffer; // 接收数据转存
  34. if((Uart_RxBuff[Uart_Rx_Cnt-1] == 0x0A)&&(Uart_RxBuff[Uart_Rx_Cnt-2] == 0x0D)) //判断结束
  35. {
  36. startReadFlag = 0;
  37. rxUpdateFlag = 1; // 数据更新
  38. }
  39. }
  40. }
  41. }
  42. HAL_UART_Receive_IT(&huart1, (uint8_t *)&aRxBuffer, 1); //再开启接收中???
  43. }
  44. /* USER CODE END 1 */

usart.h:

  1. /* USER CODE BEGIN Prototypes */
  2. extern uint8_t aRxBuffer;
  3. extern uint8_t Uart_RxBuff[256];
  4. extern uint8_t Uart_Rx_Cnt;
  5. extern uint8_t Uart_RxFlag;
  6. extern int rxUpdateFlag;
  7. /* USER CODE END Prototypes */

main.c:

  1. /* USER CODE BEGIN Includes */
  2. #include "string.h"
  3. #include "stdio.h"
  4. /* USER CODE END Includes */
  5. /* USER CODE BEGIN PV */
  6. char rxStr[256];
  7. char drawBuffer1[256]; // 提取出的数据变量
  8. char drawBuffer2[256];
  9. char drawBuffer3[256];
  10. /* USER CODE END PV */
  11. /* USER CODE BEGIN PFP */
  12. //Not include 'start' and 'end'
  13. void get_Data(const char* str, char* dst, char start, char end)
  14. {
  15. int i = 0, j = 0;
  16. while(str[i++] != start && i<= 40);
  17. while(str[i] != end && i<= 40)
  18. {
  19. dst[j] = str[i];
  20. j++;
  21. i++;
  22. }
  23. dst[j] = '\0';
  24. }
  25. /* USER CODE END PFP */
  26. /* USER CODE BEGIN 2 */
  27. HAL_UART_Receive_IT(&huart1, (uint8_t *)&aRxBuffer, 1);
  28. /* USER CODE END 2 */
  29. /* USER CODE BEGIN 3 */
  30. if(rxUpdateFlag == 1) // 收到新数据,开始处理数据
  31. {
  32. strcpy(rxStr, (char *)Uart_RxBuff);
  33. //printf("%s\r\n", rxStr);
  34. // 处理数据
  35. get_Data(rxStr, drawBuffer1, 'a', 'b');
  36. get_Data(rxStr, drawBuffer2, 'b', 'c');
  37. get_Data(rxStr, drawBuffer3, 'c', 'd');
  38. // 清除标志位,缓存等
  39. memset(Uart_RxBuff,0x00,sizeof(Uart_RxBuff));
  40. rxUpdateFlag = 0;
  41. Uart_Rx_Cnt = 0;
  42. }
  43. /* USER CODE END 3 */

发射端

  • 记住,MX的代码生成完毕后一定要把MX_DMA_Init放到MX_UARTx_UART_Init之前

然后使用HAL_UART_Transmit_DMA函数发送即可。

注意,不要连续调用这个函数,因为DMA搬运数据也是需要时间的,需要判断DMA通道是否空闲再发送。

通信格式:“@axxxxbxxxxcxxxxdxxxx”(xxxx为数字)

[STM32]STM32双机串口通信的更多相关文章

  1. 嵌入式02 STM32 实验07 串口通信

    STM32串口通信(F1系列包含3个USART和2个UART) 一.单片机与PC机串行通信研究目的和意义: 单片机自诞生以来以其性能稳定,价格低廉.功能强大.在智能仪器.工业装备以及日用电子消费产品中 ...

  2. stm32中的串口通信你了解多少

    在基础实验成功的基础上,对串口的调试方法进行实践.硬件代码顺利完成之后,对日后调试需要用到的printf重定义进行调试,固定在自己的库函数中. b) 初始化函数定义: void USART_Confi ...

  3. stm32 hal库串口通信资料汇集

    串口的发送接收函数:HAL_UART_Transmit();串口轮询模式发送,使用超时管理机制.HAL_UART_Receive();串口轮询模式发送,使用超时管理机制.HAL_UART_Transm ...

  4. stm32与三菱PLC通信

    一.三菱PLC通讯概要   三菱PLC FX系列通信结构如下图所示: 三菱PLC FX系列的通信规格如下图所示: 三菱PLC FX系列一般有以下几种通信模块,以FX2N为例: FX2N-232-BD ...

  5. (三)stm32之串口通信DMA传输完成中断

    一.DMA功能简介 首先唠叨一下DMA的基本概念,DMA的出现大大减轻了CPU的工作量.在硬件系统中,主要由CPU(内核).外设.内存(SRAM).总线等结构组成,数据经常要在内存和外设之间,外设和外 ...

  6. STM32学习笔记:【004】USART串口通信

    版本:STM32F429 Hal库v1.10 串口通信能够实现两块电路之间不同的通信,在开发中作为打印调试也是一门利器(printf重定向). 补充一点小知识: 1. weak修饰符修饰的函数,说明这 ...

  7. Stm32串口通信(USART)

    Stm32串口通信(UART) 串口通信的分类 串口通信三种传递方式 串口通信的通信方式 串行通信的方式: 异步通信:它用一个起始位表示字符的开始,用停止位表示字符的结束.其每帧的格式如下: 在一帧格 ...

  8. STM32 串口通信使用奇偶校验

    STM32串口通信如果使用奇偶校验,需要设置数据位长度为9bit USART_InitStructure.USART_BaudRate = 9600; USART_InitStructure.USAR ...

  9. stm32串口通信实验,一点笔记

    第一次深入学习stm32,花了好长时间才看懂代码(主要是C语言学习不够深入),又花了段时间自己敲了一遍,然后比对教程,了解了利用中断来串口通信的设置方法. 板子是探索版f407,本实验工程把正点原子库 ...

  10. STM32串口通信UART使用

    STM32串口通信UART使用 uart使用的过程为: 1. 使能GPIO口和UART对应的总线时钟 2. 配置GPIO口的输出模式 3. 配置uart口相关的基本信息 4. 使能uart口的相关的中 ...

随机推荐

  1. ABC 317 A - G

    ABC 317 A - G 代码去 Atcoder 全部提交搜索 Std_Code 查看代码 懒人专用 A $ p_i $ 升序,找最小的 $ i $ 满足 $ p_i + h \ge x $ 直接枚 ...

  2. Build 和 Compile 区别

  3. CentOS7.5上卸载Oracle19c

    最近遇到一个麻烦的事情,由于公司开发的数据库备份容灾系统,对于备份容灾的数据库必须使用LVM(pv.vg.lv),所以之前安装的Oracle19C 必须卸载掉,然后使用空白磁盘通过parted.fdi ...

  4. NC50454 A Simple Problem with Integers

    题目链接 题目 题目描述 给定数列 \(a[1],a[2], \dots,a[n]\) ,你需要依次进行q个操作,操作有两类: 1 l r x:给定l,r,x,对于所有 \(i \in[l,r]\) ...

  5. Springboot+Bootstrap实现增删改查实战

    说明 最近有朋友问我有没有Springboot+Bootstrap实现增删改查的DEMO,当时没有,现在他来了! 实现效果 代码地址 https://gitee.com/indexman/bootst ...

  6. P4141 消失之物题解(写给每一位与我一样的新手玩家)

    消失之物 传送门: P4141 消失之物 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 思路 暴力稳了 但是 hack tle了 这时候我们要想办法优化 这是一个回退背包问题 首先 ...

  7. 硬件开发笔记(十四):RK3568底板电路LVDS模块、MIPI模块电路分析、LVDS硬件接口、MIPI硬件接口详解

    前言   本篇继续分析底板原理图mipi/lvds屏幕电路原理图.硬件接口详解.   LVDS与MIPI的区别   液晶屏有RGB TTL.LVDS.MIPI.HDMI接口,这些接口区别于信号的类型( ...

  8. 【LeetCode哈希表#5】四数相加II(map)

    四数相加II 力扣题目链接(opens new window) 给定四个包含整数的数组列表 A , B , C , D ,计算有多少个元组 (i, j, k, l) ,使得 A[i] + B[j] + ...

  9. 详解SSL证书系列(3)如何选择SSL证书

    我们知道了在网站部署 SSL 证书后,不管是对网站本身还是对网站的用户都能够带来许多好处.那么随着 HTTPS的普及,市面上也出现了各种不同的 SSL 证书.并且由于 SSL 证书的多样性,很多人对于 ...

  10. 【Azure App Service for Windows】 PHP应用出现500 : The page cannot be displayed because an internal server error has occurred. 错误

    问题描述 PHP应用突然遇见了500 The page cannot be displayed because an internal server error has occurred.错误,但是如 ...