[STM32]STM32双机串口通信
[STM32]STM32双机串口通信
上一篇的通信方案在发送端高强度通信下寄了,发现是函数HAL_UART_Transmit()的锅,一个函数居然能跑0.3s左右。。。于是打算选用DMA收发数据,但是DMA在接收数据时遇到一些玄学问题,于是改用DMA发送数据,串口IDLE中断接收数据的策略。
cubeMX配置
接收端部分
开启USART1,打开全局中断。
发射端部分
开启USART1,开启全局中断,打开TX的DMA通道,为normal模式,内存地址自增,并打开DMA_TX的中断。
代码部分
接收端
usart.c:
/* USER CODE BEGIN 0 */
#include "string.h"
#include "main.h"
uint8_t aRxBuffer;
uint8_t Uart_RxBuff[256];
uint8_t Uart_Rx_Cnt;
uint8_t Uart_RxFlag;
uint8_t cAlmStr[] = "Warning!\r\n";
int rxUpdateFlag = 0;
int startReadFlag = 0;
/* USER CODE END 0 */
/* USER CODE BEGIN 1 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(huart);
if(huart == &huart1 && rxUpdateFlag == 0)
{
if(Uart_Rx_Cnt >= 255) // 溢出判断
{
Uart_Rx_Cnt = 0;
memset(Uart_RxBuff,0x00,sizeof(Uart_RxBuff));
HAL_UART_Transmit(&huart1, (uint8_t *)&cAlmStr, sizeof(cAlmStr),0xFFFF);
}
else // 没有溢出
{
if(aRxBuffer == '@')
{
startReadFlag = 1;
}
if(startReadFlag == 1)
{
Uart_RxBuff[Uart_Rx_Cnt++] = aRxBuffer; // 接收数据转存
if((Uart_RxBuff[Uart_Rx_Cnt-1] == 0x0A)&&(Uart_RxBuff[Uart_Rx_Cnt-2] == 0x0D)) //判断结束
{
startReadFlag = 0;
rxUpdateFlag = 1; // 数据更新
}
}
}
}
HAL_UART_Receive_IT(&huart1, (uint8_t *)&aRxBuffer, 1); //再开启接收中???
}
/* USER CODE END 1 */
usart.h:
/* USER CODE BEGIN Prototypes */
extern uint8_t aRxBuffer;
extern uint8_t Uart_RxBuff[256];
extern uint8_t Uart_Rx_Cnt;
extern uint8_t Uart_RxFlag;
extern int rxUpdateFlag;
/* USER CODE END Prototypes */
main.c:
/* USER CODE BEGIN Includes */
#include "string.h"
#include "stdio.h"
/* USER CODE END Includes */
/* USER CODE BEGIN PV */
char rxStr[256];
char drawBuffer1[256]; // 提取出的数据变量
char drawBuffer2[256];
char drawBuffer3[256];
/* USER CODE END PV */
/* USER CODE BEGIN PFP */
//Not include 'start' and 'end'
void get_Data(const char* str, char* dst, char start, char end)
{
int i = 0, j = 0;
while(str[i++] != start && i<= 40);
while(str[i] != end && i<= 40)
{
dst[j] = str[i];
j++;
i++;
}
dst[j] = '\0';
}
/* USER CODE END PFP */
/* USER CODE BEGIN 2 */
HAL_UART_Receive_IT(&huart1, (uint8_t *)&aRxBuffer, 1);
/* USER CODE END 2 */
/* USER CODE BEGIN 3 */
if(rxUpdateFlag == 1) // 收到新数据,开始处理数据
{
strcpy(rxStr, (char *)Uart_RxBuff);
//printf("%s\r\n", rxStr);
// 处理数据
get_Data(rxStr, drawBuffer1, 'a', 'b');
get_Data(rxStr, drawBuffer2, 'b', 'c');
get_Data(rxStr, drawBuffer3, 'c', 'd');
// 清除标志位,缓存等
memset(Uart_RxBuff,0x00,sizeof(Uart_RxBuff));
rxUpdateFlag = 0;
Uart_Rx_Cnt = 0;
}
/* USER CODE END 3 */
发射端
- 记住,MX的代码生成完毕后一定要把MX_DMA_Init放到MX_UARTx_UART_Init之前
然后使用HAL_UART_Transmit_DMA函数发送即可。
注意,不要连续调用这个函数,因为DMA搬运数据也是需要时间的,需要判断DMA通道是否空闲再发送。
通信格式:“@axxxxbxxxxcxxxxdxxxx”(xxxx为数字)
[STM32]STM32双机串口通信的更多相关文章
- 嵌入式02 STM32 实验07 串口通信
STM32串口通信(F1系列包含3个USART和2个UART) 一.单片机与PC机串行通信研究目的和意义: 单片机自诞生以来以其性能稳定,价格低廉.功能强大.在智能仪器.工业装备以及日用电子消费产品中 ...
- stm32中的串口通信你了解多少
在基础实验成功的基础上,对串口的调试方法进行实践.硬件代码顺利完成之后,对日后调试需要用到的printf重定义进行调试,固定在自己的库函数中. b) 初始化函数定义: void USART_Confi ...
- stm32 hal库串口通信资料汇集
串口的发送接收函数:HAL_UART_Transmit();串口轮询模式发送,使用超时管理机制.HAL_UART_Receive();串口轮询模式发送,使用超时管理机制.HAL_UART_Transm ...
- stm32与三菱PLC通信
一.三菱PLC通讯概要 三菱PLC FX系列通信结构如下图所示: 三菱PLC FX系列的通信规格如下图所示: 三菱PLC FX系列一般有以下几种通信模块,以FX2N为例: FX2N-232-BD ...
- (三)stm32之串口通信DMA传输完成中断
一.DMA功能简介 首先唠叨一下DMA的基本概念,DMA的出现大大减轻了CPU的工作量.在硬件系统中,主要由CPU(内核).外设.内存(SRAM).总线等结构组成,数据经常要在内存和外设之间,外设和外 ...
- STM32学习笔记:【004】USART串口通信
版本:STM32F429 Hal库v1.10 串口通信能够实现两块电路之间不同的通信,在开发中作为打印调试也是一门利器(printf重定向). 补充一点小知识: 1. weak修饰符修饰的函数,说明这 ...
- Stm32串口通信(USART)
Stm32串口通信(UART) 串口通信的分类 串口通信三种传递方式 串口通信的通信方式 串行通信的方式: 异步通信:它用一个起始位表示字符的开始,用停止位表示字符的结束.其每帧的格式如下: 在一帧格 ...
- STM32 串口通信使用奇偶校验
STM32串口通信如果使用奇偶校验,需要设置数据位长度为9bit USART_InitStructure.USART_BaudRate = 9600; USART_InitStructure.USAR ...
- stm32串口通信实验,一点笔记
第一次深入学习stm32,花了好长时间才看懂代码(主要是C语言学习不够深入),又花了段时间自己敲了一遍,然后比对教程,了解了利用中断来串口通信的设置方法. 板子是探索版f407,本实验工程把正点原子库 ...
- STM32串口通信UART使用
STM32串口通信UART使用 uart使用的过程为: 1. 使能GPIO口和UART对应的总线时钟 2. 配置GPIO口的输出模式 3. 配置uart口相关的基本信息 4. 使能uart口的相关的中 ...
随机推荐
- ABC 317 A - G
ABC 317 A - G 代码去 Atcoder 全部提交搜索 Std_Code 查看代码 懒人专用 A $ p_i $ 升序,找最小的 $ i $ 满足 $ p_i + h \ge x $ 直接枚 ...
- Build 和 Compile 区别
- CentOS7.5上卸载Oracle19c
最近遇到一个麻烦的事情,由于公司开发的数据库备份容灾系统,对于备份容灾的数据库必须使用LVM(pv.vg.lv),所以之前安装的Oracle19C 必须卸载掉,然后使用空白磁盘通过parted.fdi ...
- 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]\) ...
- Springboot+Bootstrap实现增删改查实战
说明 最近有朋友问我有没有Springboot+Bootstrap实现增删改查的DEMO,当时没有,现在他来了! 实现效果 代码地址 https://gitee.com/indexman/bootst ...
- P4141 消失之物题解(写给每一位与我一样的新手玩家)
消失之物 传送门: P4141 消失之物 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 思路 暴力稳了 但是 hack tle了 这时候我们要想办法优化 这是一个回退背包问题 首先 ...
- 硬件开发笔记(十四):RK3568底板电路LVDS模块、MIPI模块电路分析、LVDS硬件接口、MIPI硬件接口详解
前言 本篇继续分析底板原理图mipi/lvds屏幕电路原理图.硬件接口详解. LVDS与MIPI的区别 液晶屏有RGB TTL.LVDS.MIPI.HDMI接口,这些接口区别于信号的类型( ...
- 【LeetCode哈希表#5】四数相加II(map)
四数相加II 力扣题目链接(opens new window) 给定四个包含整数的数组列表 A , B , C , D ,计算有多少个元组 (i, j, k, l) ,使得 A[i] + B[j] + ...
- 详解SSL证书系列(3)如何选择SSL证书
我们知道了在网站部署 SSL 证书后,不管是对网站本身还是对网站的用户都能够带来许多好处.那么随着 HTTPS的普及,市面上也出现了各种不同的 SSL 证书.并且由于 SSL 证书的多样性,很多人对于 ...
- 【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.错误,但是如 ...