STM2G031-使用STM32CubeIDE进行串口通信实验(串口收发、接收不定长数据)_stm32 multiprocessor communication-程序员宅基地

技术标签: STM32  

STM2G031-使用STM32CubeIDE进行串口通信实验

一、基础配置

模式选择 : 配置为异步模式Asynchronous

  • Asynchronous : 异步, 整个过程,不会阻碍发送者的工作。
  • Synchronous : 同步, 同步信息一旦发送,发送者必须等到应答,才能继续后续的行为。
  • Single Wire : 单总线, 半双工。
  • Multiprocessor Communication:多机通信
    在这里插入图片描述
    基本参数配置: 参数配置里面主要关注一下基本参数配置,其他的一些配置默认即可。
  • 波特率:可以根据实际情况进行选择
  • 字长:一般选择8位即可
  • 奇偶校验:一般选择无
  • 停止位:1位
    在这里插入图片描述

二、printf 重定向

在 Private includes 中引入头文件:

#include <stdio.h>

在 USER CODE BEGIN PD 添加下面代码:

#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch,FILE *F)
#endif

PUTCHAR_PROTOTYPE
{
    
	HAL_UART_Transmit(&huart2, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
	return ch;
}

使用printf输出浮点数:
Project–>Properties–>C/C++ Build–>Settings–>MCU settings,如下图所示,勾选上即可。
在这里插入图片描述

实验一:通过串口发送数据

  • 基本配置
    在这里插入图片描述
  • 添加代码:
/* USER CODE BEGIN Includes */
#include <stdio.h>
/* USER CODE END Includes */

/* USER CODE BEGIN PD */
#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch,FILE *F)
#endif

PUTCHAR_PROTOTYPE
{
    
	HAL_UART_Transmit(&huart2, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
	return ch;
}
/* USER CODE END PD */

/* USER CODE BEGIN 3 */
	HAL_Delay(500);
	printf("Hello World!\r\n");
}
/* USER CODE END 3 */

  • 实验现象:
    打开串口调试助手,即可看将以500ms为周期输出Hello World!
    在这里插入图片描述

实验二:接收数据

  • 基本配置:注意需要开启串口中断
    在这里插入图片描述
    在这里插入图片描述
  • 添加代码:
/* USER CODE BEGIN Includes */
#include <stdio.h>
/* USER CODE END Includes */

/* USER CODE BEGIN PD */
#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch,FILE *F)
#endif

PUTCHAR_PROTOTYPE
{
    
	HAL_UART_Transmit(&huart2, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
	return ch;
}
/* USER CODE END PD */

/* USER CODE BEGIN PV */
uint8_t RxBuff[1];		// 用来接收串口2发送的数据
/* USER CODE END PV */

/* USER CODE BEGIN 2 */
HAL_UART_Receive_IT(&huart2, RxBuff, 1);
/* USER CODE END 2 */

/* USER CODE BEGIN 4 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    

	if(huart->Instance == USART2)	// 判断是由哪个串口触发的中断
	{
    
		HAL_UART_Transmit(&huart2,RxBuff,1,100);	// 接收到数据马上使用串口2发送出去
		HAL_UART_Receive_IT(&huart2,RxBuff,1);		// 重新使能串口2接收中断
	}
}
/* USER CODE END 4 */

实验现象: 将串口接收到的数据,又通过该串口发送回去
在这里插入图片描述

实验三:串口接收不定长数据(定时器方式实现)

  • 基本配置:
    关于定时器的配置,在这里使用通用定时器3。如下图所示,配置一下时钟,内部时钟我们配置为64Mhz,定时器1ms产生一次中断(可以根据实际情况增大时间)。
    定时器的配置主要有两个:定时时间与是否重装定时器。
    定时频率 = 定时器时钟 / (预分频 +1) /(计数值 + 1 ) Hz。
    定时时间 = 1 / 定时频率 s。
    在这里插入图片描述
    在这里插入图片描述在这里插入图片描述
    在这里插入图片描述
    添加代码:
/* USER CODE BEGIN Includes */
#include <stdio.h>
#include <string.h>
/* USER CODE END Includes */

/* USER CODE BEGIN PD */
#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch,FILE *F)
#endif

PUTCHAR_PROTOTYPE
{
    
	HAL_UART_Transmit(&huart2, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
	return ch;
}
/* USER CODE END PD */

/* USER CODE BEGIN PV */
uint8_t RxBuff[1];      //进入中断接收数据的数组
uint8_t DataBuff[100]; //保存接收到的数据的数组
int RxLine=0;           //接收到的数据长度
int Rx_flag=0;					//接受到数据标志
/* USER CODE END PV */

/* USER CODE BEGIN 0 */
void printf_usart(void)
{
    
	printf("length=%d\r\n",RxLine);
	DataBuff[RxLine] = '\0';
		printf("Rxdata:%s\r\n",DataBuff);
	memset(DataBuff,0,sizeof(DataBuff));  //清空缓存数组
	//memset()作用:可以方便的清空一个结构类型的变量或数组。
	//例句:memset(aTxbuffer,0,sizeof(aTxbuffer))  用memset清空aTxbuffer。
	RxLine=0;  //清空接收长度
}
/* USER CODE END 0 */

  /* USER CODE BEGIN 2 */
  HAL_UART_Receive_IT(&huart2,  (uint8_t *)RxBuff, 1);
  HAL_TIM_Base_Start_IT(&htim3);//开启定时器
  /* USER CODE END 2 */
/* USER CODE BEGIN 4 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    

	if(huart->Instance == USART2)	// 判断是由哪个串口触发的中�?
	{
    
		RxLine++;                      //每接收到一个数据,进入回调数据长度加1
		DataBuff[RxLine-1]=RxBuff[0];  //把每次接收到的数据保存到缓存数组
		Rx_flag=1;
		if(RxBuff[0]==0xff)            //接收结束标志位,这个数据可以自定义,根据实际需求,这里只做示例使用,不一定是0xff
		{
    
			printf_usart();
		}
		RxBuff[0]=0;
		HAL_UART_Receive_IT(&huart2, (uint8_t *)RxBuff, 1); //每接收一个数据,就打开一次串口中断接收,否则只会接收一个数据就停止接收
		__HAL_TIM_SET_COUNTER(&htim3, 1); // 计数清零,从头开始计
	}
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){
    

    if (htim->Instance == TIM3){
    	// 判断是由哪个定时器触发的中断
    	if(Rx_flag==1)
		{
    
			printf_usart();
			Rx_flag=0;
		}
    }
}
/* USER CODE END 4 */

实验四:串口接收不定长数据(DMA方式实现)

  • 基本原理:
    DMA方式接收不定长数据要用到IDLE空闲中断,

空闲中断是接受数据后出现一个 byte 的高电平 (空闲) 状态, 就会触发空闲中断. 并不是空闲就会一直中断,准确的说应该是上升沿(停止位)后一个 byte,如果一直是低电平是不会触发空闲中断的(会触发 break中断)。所以为了减少误进入串口空闲中断,串口 RX 的 IO 管脚一定设置成 Pull-up<上拉模式>,串口空闲中断只是接收的数据时触发,发送时不触发。

说明白一点,就是我们在发送数据的时候,是一直在发送,不会有一帧这么长的空闲,当发送数据结束后,就会产生空闲中断,所以,可以通过空间中断来判断数据是否接收完成。

  • 优势:

相较于上面用定时器实现的方式,这种方法不需要一直产生中断,而占用cpu的资源,也省去了一个定时器。

目前使用DMA和空闲中断的方式,不知道遇到了什么问题,就是看不到现象…参考了很多资料,暂时还没实现,具体错误不知道出在哪里了,找了一天的错误了,快吐了,以后再说吧…

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_43715171/article/details/113754863

智能推荐

win10和ubuntu的pyCharm配置python解释器_ubuntu conda环境文件夹中没有python.exe-程序员宅基地

文章浏览阅读2.5k次。ubuntu配置python3.6文件---新建项目---选择需要的python版本(基本解释器python3.6)创建---新建Python文件test01.py打开设置添加系统Python解释器,点齿轮--添加--系统解释器 选择python3 点击确定点击添加配置点击 “+” -> Python选定脚本路径点击确定,配置完成..._ubuntu conda环境文件夹中没有python.exe

StringUtils工具类常用方法汇总(判空、转换、移除、替换、反转)_stringutils.remove-程序员宅基地

文章浏览阅读4.9k次,点赞8次,收藏26次。Apache commons lang3包下的StringUtils工具类中封装了一些字符串操作的方法,非常实用,使用起来也非常方便。最近自己也经常在项目中使用到了里面的一些方法,在这里将常用的方法总结了一下,方便以后查阅,大家有兴趣也可以看一下。  首先需要说明的一点是,StringUtils类在操作字符串时,即使操作的为null值也是安全的,不会报NullPointerException,这一..._stringutils.remove

html如何做点击按钮左侧展开收起,如何使用CSS3 实现侧边栏展开收起动画-程序员宅基地

文章浏览阅读1.2k次。@keyframes规则用于创建动画。@keyframes 中规定某项 CSS 样式,就能创建由当前样式逐渐改为新样式的动画效果@keyframes 中创建动画时,请把它捆绑到某个选择器,否则不会产生动画效果。通过规定至少以下两项 CSS3 动画属性,即可将动画绑定到选择器:规定动画的名称规定动画的时长animationanimation 属性是一个简写属性,用于设置动画属性:animation-..._keyframes向左展开动画

python游戏程序代码大全_童年游戏,Python一行代码就能实现!-程序员宅基地

文章浏览阅读2.5k次。大家好,儿童节到了,虽然秃头程序员没有头发,但是童心还是一直都在的,今天就分享一个私藏的GitHub项目——free-python-games,一行代码就能进入使用Python开发的小游戏快乐玩耍!安装与使用安装当然也很简单一行代码就可以pip install freegames由于该项目中的所有游戏均是基于Python内置模块Turtle制作,所以没有太多依赖,安装不会有困难。安装完之后我们可以..._童年游戏代码大全

Eclipse中项目Src看不到.Java文件_eclipse导入的项目src下没java-程序员宅基地

文章浏览阅读5.2k次。Eclipse中项目Src看不到.Java文件需要从Java切换到java EE 工作空间_eclipse导入的项目src下没java

Linux C函数之文件及目录函数(全)_c语言 getwd-程序员宅基地

文章浏览阅读677次。转载地址:http://blog.sina.com.cn/s/blog_695e489c01013ldd.html【转】Linux C函数之文件及目录函数(全)(2012-03-30 17:17:37)转载▼标签:杂谈分类: c语言学习chdir, chmod, chown, chroot_c语言 getwd

随便推点

python生成唯一Id的几种方法_python并发生成唯一数据-程序员宅基地

文章浏览阅读2w次,点赞2次,收藏4次。# coding:utf-8import randomdef createRandomString(len): print ('wet'.center(10,'*')) raw = "" range1 = range(58, 65) # between 0~9 and A~Z range2 = range(91, 97) # between A~Z and a~..._python并发生成唯一数据

Maven1-配置及创建JavaSE项目_maven 创建javase工程-程序员宅基地

文章浏览阅读431次。一、Maven简介项目构建工具(不只是管理jar包),项目设计和编码由程序员来做,它做不了;而编译,运行,测试,打包,部署,jar管理它都能做Apache提供,Java开发的,运行Maven要有基本的java开发工具包Maven仓库:存储jar包本地仓库:当前本地电脑远程仓库:局域网中的服务器中央仓库:远程服务器有远程仓库:本地连接远程,远程仓库中有就下载到本地,没有就去连中央仓库,中央仓库下载到远程,远程再下载到本地,适合团队开发,远程仓库可以连接多个本地仓库,所以很多公_maven 创建javase工程

【转载】FPGA配置方式_quartus烧录-程序员宅基地

文章浏览阅读6.3k次,点赞2次,收藏31次。【概要】FPGA配置方式首先介绍下AS、PS、JTAG三种模式的区别。AS模式: 主动串行配置模式。将.pof文件烧写到flash(掉电不丢失)芯片,FPGA器件每次上电时,作为主控制器从配置器件flash(EPCS)主动读取程序文件并存放至FPGA内部的配置存储器(configure RAM),实现逻辑运作,该方法适用于不需要经常升级的场合,一次性读取程序文件;PS..._quartus烧录

GitHub集成Circle CI(附 Circle CI 配置示例文件)_circleci building status github-程序员宅基地

文章浏览阅读1.6k次。文章目录GitHub 集成Circle CICI(持续集成) 简单解释CI 工具Circle的使用将GitHub项目授权给 Circle CI书写 config.yml文件测试 Circle CI 配置文件是否生效备注写在最后GitHub 集成Circle CICI(持续集成) 简单解释CI 即 Continuous Integration. 当代码提交上来有变动的时候,在merge之前自动进行一些流程,如:代码风格检查、单元测试是否通过等。当被merge之后,又会自动进行一些流程,如:自动打包、_circleci building status github

matlab题目如何在一个圆形区域进行三维作图_meshgrid ,边界是圆-程序员宅基地

文章浏览阅读3.2k次,点赞3次,收藏7次。不废话上图[r,t]=meshgrid(0:0.1:2,0:0.02:2*pi);x=r.*cos(t);y=r.*sin(t);z=x.^2+y.^2;mesh(x,y,z)其实在数学上使用了一个圆的参数方程来实现绘制区域为圆形的效果在这个区域上面是一个碗状图形_meshgrid ,边界是圆

jwt token注销_如何用SpringBoot集成JWT实现token验证及token注销?一招教会你-程序员宅基地

文章浏览阅读763次。Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).定义了一种简洁的,自包含的方法用于通信双方之间以JSON对象的形式安全的传递信息。因为数字签名的存在,这些信息是可信的,JWT 可以使用HMAC算法或者是RSA的公私秘钥对进行签名。JWT 请求流程这里还要注意:光理论是不够的。在此顺便送大家十套20..._springboot jwt 注销登陆