【STM32串口通信】

这篇具有很好参考价值的文章主要介绍了【STM32串口通信】。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


学习计划

  • 每天更新STM32学习笔记

一、串口通信知识点

  • 串口通信的数据按顺序传输,其数据包由发送设备通过自身的 TXD 接口传输到接收设备的 RXD 接口,故串口通信至少需要两根线(GND和一根信号线)来实现单工通信。若要实现全双工通信,则要三根线(GND和两根信号线)。
  • 串口通信的数据包由起始位、数据位(5~8位)、校验位(奇\偶\无校验位)以及停止位组成,通信双方的数据包格式要约定一致才能正常收发数据。
  • 串口通信速率:波特率,单位Bits/s。
  • UART只用于异步通信;USART用于同步/异步通信。若为同步通信,则要加一根时钟线。

嵌入式中的通讯协议——UART、I2C、SPI、DMA

二、硬件部分

1.所需硬件

STM32F407ZGT6相关开发板、USB转TTL、STLINK下载器

2.部分硬件连接

USB转TTL-----------STM32
RXD-------------------PA9
TXD-------------------PA10

STLINK--------------STM32
SWCLK--------------PA14
SWDIO--------------PA13

三、阻塞式

0、串口阻塞式发送和接收概念

串口阻塞发送:发送一段数据,在没有发送完所有数据之前,一直停留在此发送函数(可设定阻塞时间),这个过程中会阻塞别的程序运行;

1、STM32CUBEMX配置

在STM32CUBEMX中配置时钟树、选择系统调试方式后,STM32CUBEMX入门
配置串口参数:异步,115200,8,NONE,1。
stm32串口接收,学习STM32,stm32,单片机,嵌入式硬件

2、编写阻塞式串口发送与接收代码

生成代码后,在main.c文件-while死循环前添加代码:

//阻塞式发送
HAL_UART_Transmit(&huart1, (uint8_t *)"HELLO", 5, 20);
//写在while死循环前只发送一次HELLO

在main.c文件-while死循环中添加代码:

//阻塞式接收
uint8_t rev[5];
HAL_UART_Receive(&huart1 ,rev, 3, 0xFFFF);//接收:串口1句柄、接收区首地址、接收的字节数、超时时间ms	
HAL_UART_Transmit(&huart1, rev, 3, 0xFFFF);//接收到的数据,发送回去,验证是否发送成功
		

stm32串口接收,学习STM32,stm32,单片机,嵌入式硬件

3、学习小技巧

编写阻塞式串口发送代码在学习的过程中可以通过左侧Functions栏,找到所需函数。
如需要串口发送函数:
stm32串口接收,学习STM32,stm32,单片机,嵌入式硬件

4、程序编译与下载

编译成功后,连接好STLINK下载器,点击下载。
stm32串口接收,学习STM32,stm32,单片机,嵌入式硬件

5、程序验证

连接USB转TTL模块,打开XCOM软件。
stm32串口接收,学习STM32,stm32,单片机,嵌入式硬件
程序验证成功!

6、重定向printf和scanf

为了简写,需要重定向printf和scanf。但是printf()这个函数是格式化输出到屏幕的,scanf()函数又是格式化输入(从屏幕),并不能输出到串口助手中,所以需要进行重定向。

  • 6.1、首先我们需要在keil集成开发环境中勾选STM32官方的微库(MicroLib是针对以C语言编写的基于ARM嵌入式应用程序的高度优化的库)。
    stm32串口接收,学习STM32,stm32,单片机,嵌入式硬件

  • 6.2、引用标准库的头文件

#include <stdio.h>//引用标准库的头文件,重定义printf,scanf
  • 6.3、添加重定向代码
//因为printf内部就是调用fputc进行单个字符输出,
//所以重定向printf就将单个字符以串口的形式发送出去。
int fputc(int c,FILE *f)//重定向printf
{
   uint8_t ch[1]={c};
   HAL_UART_Transmit(&huart1,(uint8_t *)&ch,1,0xFFFF);
   return c;
}
int fgetc(FILE *stream)//重定向scanf
{
   uint8_t ch[1];
   HAL_UART_Receive(&huart1, ch, 1, 0xFFFF);
   return ch[0];
}

stm32串口接收,学习STM32,stm32,单片机,嵌入式硬件

  • 6.4、使用printf和scanf函数实现阻塞式串口发送与接收
printf("ABC%d",123);//写在while死循环前,只发送一次ABC123
int i=0;
scanf("%d",&i);//用scanf接收数据,scanf通过回车判断结束的,所以接收的字节数要+2 \r\n 
printf("%d\r\n",i);//接收到的数据,用printf发送回去,验证是否发送成功

stm32串口接收,学习STM32,stm32,单片机,嵌入式硬件

  • 6.5、程序验证
    stm32串口接收,学习STM32,stm32,单片机,嵌入式硬件

三、中断式

0、串口中断式发送和接收概念

串口中断发送:送数据的过程在中断中进行,这个中断实际上是发送数据寄存器空的中断。

1、STM32CUBEMX配置更新

在阻塞式STM32CUBEMX配置上进行更新,再重新生成代码,自己写的阻塞式代码删除,学习中断式:
stm32串口接收,学习STM32,stm32,单片机,嵌入式硬件

2、编写中断式串口发送与接收代码

    //main函数中,在while循环前
  	
	//中断式发送
	HAL_UART_Transmit_IT(&huart1, (uint8_t *)"HELLO", 5);//调用次函数,每发完一个字节就会进入一次中断,	在中断中,HAL库会自动触发下一个中断,直到发送完数据

	//中断式接收
  //uint8_t rev[5];//不能定义局部变量,要定义全局变量,因有可能在接收到数据时,改局部变量已经被销毁了。
	HAL_UART_Receive_IT(&huart1 ,rev, 3);//当接收完数据时,会直接进入接收回调函数,要在接收回调函数中写发送代码,实现与阻塞式一样的效果	
//接收回调函数,写在main.c文件中
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	HAL_UART_Transmit_IT(&huart1, rev, 3);//接收到的数据,发送回去,验证是否发送成功
	HAL_UART_Receive_IT(&huart1 ,rev, 3);//开启下一次接收中断
}
uint8_t rev[5];//全局变量

stm32串口接收,学习STM32,stm32,单片机,嵌入式硬件
stm32串口接收,学习STM32,stm32,单片机,嵌入式硬件

3、程序验证

stm32串口接收,学习STM32,stm32,单片机,嵌入式硬件

四、DMA

0、DMA概念

DMA传输是将数据从一个地址空间复制到另一个地址空间,提供在外设和存储器之间或者存储器和存储器之间的高速数据传输。无须CPU的干预,通过DMA数据可以快速地移动。这就节省了CPU的资源来做其他操作。

1、STM32CUBEMX配置更新

在中断式STM32CUBEMX配置上进行更新:
stm32串口接收,学习STM32,stm32,单片机,嵌入式硬件
USART1-DMA Setting-选择发送和接收,再重新生成代码:
stm32串口接收,学习STM32,stm32,单片机,嵌入式硬件

2、编写DMA式不定长串口发送与接收代码

//在main.h中创建串口接收结构体
#define RX_BUF_MAX_LEN 512
typedef struct
{
	uint8_t rx_buff[RX_BUF_MAX_LEN];//缓存区
	uint16_t len;		//接收长度
}USRAT_RX;
//在stm32xxxx_it.c中定义结构体变量
/* USER CODE BEGIN PV */
USRAT_RX usart1_rx;//首先定义一个结构体变量
/* USER CODE END PV */
//在stm32xxxx_it.c中找到串口1中断服务函数,编写不定长串口收发程序
void USART1_IRQHandler(void)//串口1中断服务函数,当串口1产生任何中断都会进入此函数
{
  /* USER CODE BEGIN USART1_IRQn 0 */
 if(__HAL_UART_CLEAR_FLAG(&huart1,UART_FLAG_IDLE) != RESET)//如果空闲中断不为0 RESET,表示此时触发了空闲中断,收到一帧数据
 {
		__HAL_UART_CLEAR_IDLEFLAG(&huart1); //清除空闲中断		
		HAL_UART_DMAStop(&huart1);//停止串口1的DMA传输	 
		usart1_rx.len = RX_BUF_MAX_LEN - __HAL_DMA_GET_COUNTER(huart1.hdmarx);	//计算接收到的数据长度:要接收到的字节数总数-剩余数=实际接收数
				
	  HAL_UART_Transmit_DMA(&huart1,usart1_rx.rx_buff,usart1_rx.len);
	  HAL_UART_Receive_DMA(&huart1,usart1_rx.rx_buff,RX_BUF_MAX_LEN);	
		
 }
  /* USER CODE END USART1_IRQn 0 */
  HAL_UART_IRQHandler(&huart1);
  /* USER CODE BEGIN USART1_IRQn 1 */
  /* USER CODE END USART1_IRQn 1 */
}
//在main.c中声明结构体变量
extern USRAT_RX usart1_rx;
//在main.c中添加string.h头文件,编写串口结构体初始化函数
#include <string.h>//使用memset函数,需引用此头文件

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
void Clear_Usart(USRAT_RX *usart_rx)		
//初始化(清空)串口结构体
{
	memset((uint8_t*)usart_rx,0,sizeof(USRAT_RX)); 
}
/* USER CODE END 0 */
//在main.c中while循环前
  /* USER CODE BEGIN 2 */
	Clear_Usart(&usart1_rx); //初始化串口结构体
  __HAL_UART_ENABLE_IT(&huart1,UART_IT_IDLE);	//使能串口1的空闲中断,由于HAL库没有提供空闲函数的回调函数,所以要在串口中断服务函数中添加代码
  HAL_UART_Receive_DMA(&huart1,usart1_rx.rx_buff,RX_BUF_MAX_LEN);	//打开DMA传输模式

  /* USER CODE END 2 */

3、程序验证

stm32串口接收,学习STM32,stm32,单片机,嵌入式硬件


参考文章

嵌入式中的通讯协议——UART、I2C、SPI、DMA
STM32F4_HAL库_串口阻塞/中断/DMA三种方式发送数据的配置
【STM32】 DMA原理,步骤超细详解,一文看懂DMA
STM32串口DMA模式发送接收数据并控制LED灯
【STM32F4+CubeMX零基础快速入门】串口收发全攻略文章来源地址https://www.toymoban.com/news/detail-759119.html

到了这里,关于【STM32串口通信】的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • STM32单片机(九)USART串口----第三节:USART串口实战练习(串口发送)

    ❤️ 专栏简介:本专栏记录了从零学习单片机的过程,其中包括51单片机和STM32单片机两部分;建议先学习51单片机,其是STM32等高级单片机的基础;这样再学习STM32时才能融会贯通。 ☀️ 专栏适用人群 :适用于想要从零基础开始学习入门单片机,且有一定C语言基础的的童鞋

    2024年02月10日
    浏览(59)
  • 使用标准库和HAL库的STM32单片机进行串口通信/解决因例程为HAL库的传感器,而其他模块都是标准库,需要将数据用串口传送给标准库的单片机的相关问题

    (本文使用STM32F103C8T6,在CubeMX里演示用的是RBT6,但实际上引脚是一样的)         本文 着重解决一个大工程中,某些传感器的例程是HAL库的,而其他模块(或算法)都是标准库,导致难以移植的问题。 本文的解决方法是:使用一片单片机用HAL库(CubeMX)配置例程,然后

    2024年02月06日
    浏览(65)
  • 【STM32】单片机模式配置&FlyMcu串口下载固件&STLINK Utility

    目录 1 单片机模式配置 1.1 存储器映像 1.2 启动配置 1.3 启动模式选择 1.4 硬件展示 1.4.1 BOOT引脚配置: 1.4.2 USB转TTL 2 FlyMcu串口下载固件         2.1软件配置方式         2.2 选项字节 3 STLINK Utility 3.1 简介 3.2 下载程序流程 通过 设置选择管脚 ,对应到各种启动模式的不

    2024年01月20日
    浏览(64)
  • c51单片机串口通信(中断方式接收数据)(单片机--单片机通信)示例代码 附proteus图

         单片机一般采用中断方式接受数据,这样便于及时处理 其中发送数据段采用的是查询方式,接收端采用了中断方式, 要注意的地方有: 在中断处理函数int_0()内,处理数据前要先关闭中断,否则中断可能会不断传过来, EA=0; 然后退出中断处理函数前恢复中断处理能力:

    2024年02月13日
    浏览(65)
  • STM32单片机初学4-IIC通信(软件模拟)

    IIC ( Inter-Integrated Circuit )又称I2C(习惯读“I方C”),是 IIC Bus简称,中文名为 集成电路总线 ,它是一种串行通信总线,使用多主从架构,由飞利浦公司在1980年代为了让主板、嵌入式系统或手机用以连接低速周边设备而发展。适用于IC间的短距离数据传输。 最初的IIC通信速

    2024年02月05日
    浏览(76)
  • 使用DMA传输实现单片机高效串口转发——以STM32系列为例

    Date Author Version Note 2023.08.06 Dog Tao V1.0 1. 完成了文档的撰写。 2023.08.23 Dog Tao V1.1 1. 增加了STM32F103-USART2的DMA传输配置示例。 2. 增加了STM32F103与F407单片机的DMA控制器介绍并更改了第一章节的结构。 应用场景 在许多现实应用场景中,例如工业自动化控制、嵌入式通信设备等领域,

    2024年02月14日
    浏览(53)
  • 基于STM32单片机BOOTLOADER通过串口升级程序IAP——APP方案

                            此方法前提是你得有一个EEPROM         我用的单片机是STM32F103ZET6 , 此单片机FLASH容量为512KB; 在此单片机里面FLASH的起始地址是0X8000000,BOOT作为引导加载程序一般都是从这个地址开始,单片机一上点默认会从这个地址开始运行,所以将自己

    2024年02月04日
    浏览(63)
  • openmv识别物体并与单片机通信(STM32)

    感光元件 寻找色块 find_blobs函数:此函数参数较多,一般只用第一个参数就可以找到需要的色块。thresholds是颜色的阈值,是一个列表,这个列表可以有多个颜色阈值。 一个颜色阈值的结构是这样的: 画图 x,y:是坐标 size:是两侧的尺寸 color:画十字的颜色 rect_tuple 的格式是

    2023年04月08日
    浏览(54)
  • STM32F407单片机HAL库CAN2不能接收数据解决方法

      最近在使用stm32F407的片子调试can通信,直接在正点原子的代码上修改调试,调试can1的时候,基本没啥问题,收发都正常,使用查询模式和中断模式都可以。但是当修改到can2的时候,可以正常发送数据,但是中断函数始终进不去。折腾了一两个小时终于搞定了。下面将解

    2024年02月16日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包