HAL库学习05---串口通信(三种方式轮询、中断、DMA)

一、原理介绍

串行通信的通讯方式可以分为两类:
1、同步通信,带时钟信号的传输,如SPI、IIC、USART
2、异步传输,不带时钟信号的传输,如UART、USART

UART通用异步收发器:UART口指的是一种物理接口形式(硬件)

在这里插入图片描述UART是异步,全双工串口总线。它比同步串口复杂很多。有两根线,一根TXD用于发送,一根RXD用于接收。
UART的串行数据传输不需要使用时钟信号来同步传输,而是依赖于发送设备和接收设备之间预定义的配置。(约定固定波特率) 对于发送设备和接收设备来说,两者的串行通信配置应该设置为完全相同。
在这里插入图片描述
起始位:表示数据传输的开始,电平逻辑为“0” 。 数据位:可能值有5、6、7、8、9,表示传输这几个bit 位数据。一般取值为8,因为一个ASCII 字符值为8 位。 奇偶校验位:用于接收方对接收到的数据进行校验,校验“1” 的位数为偶数(偶校验) 或奇数(奇校验),以此来校验数据传送的正确性,使用时不需要此位也可以。 停止位:表示一帧数据的结束。电平逻辑为“1”。 如果用通用IO口模拟UART总线,则需一个输入口,一个输出口。

USART是通用同步/异步收发器:其可选使用异步方式,那将和UART无区别,如果是同步,则需要多一根时钟线(USART_CK)

串口发送接收有三种模式:轮询、中断和 DMA
补充几个名词:
Asynchronous:异步通信
Synchronous : 同步通信
Single Wire (Half-Duplex) :单线/半双工

二、STM32和PC进行数据互发

1、扫描接收发送

(1)、选择USART
(2)、设置MODE为异步通信(Asynchronous)
引脚一般自动设置为PA9、PA10
在这里插入图片描述
首先要在main.c或者是usart.c中对printf()和scanf()进行重定义,方便使用
记得要在头文件中输入#include "stdio.h"

int fputc(int ch,FILE *f)
{
HAL_UART_Transmit (&huart1 ,(uint8_t *)&ch,1,HAL_MAX_DELAY );
return ch;
}
int fgetc(iFILE *f)
{
uint8_t ch=0;
HAL_UART_Receive (&huart1 ,&ch,1,HAL_MAX_DELAY );
return ch;
}

这样子就可以直接利用printf进行发送,打印

 while (1)
  {
    ch=getchar();
    HAL_UART_Transmit(&huart1,&ch,1,0);
  }

当然也可以用这种方式

uint8_t data[1];
while (1)
{
if(HAL_UART_Receive(&huart1,data,sizeof(data),HAL_MAX_DELAY)==HAL_OK){
		HAL_UART_Transmit (&huart1 ,data,sizeof(data),HAL_MAX_DELAY );
    }
}

1、中断接收发送

中断接收发送理解:原来的轮询方式是你一遍遍的询问前台你的外卖到了吗,在这期间你无法腾出时间去干其他事情,而中断则是外卖到了,前台告诉你,然后你去拿,在此期间你是可以做其他的事情的。
打开NVIC中断
在这里插入图片描述
补充一个函数:中断方式串口接收触发中断(接收完成)所调用的函数(void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart))用这个回调函数实现中断后的动作,
代码编写
在 main.c 中,while 循环前,串口初始化后,添加接收中断开启函数,这样在第一次接收到数据的时候才会触发中断,切记要添加该函数。

HAL_UART_Receive_IT(&huart1,(uint8_t*)data,sizeof(data));//data是自己定义的接收中断缓冲

在main.c下方添加中断回调函数,实现串口的发送和接收

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if(huart->Instance==USART1)
	{
		HAL_UART_Transmit_IT(&huart1,data,sizeof(data));//发送你输入的内容
		HAL_UART_Receive_IT(&huart1,(uint8_t*)data,sizeof(data));//打开下一次串口接收中断
		}
}

3、DAM接收发送

DMA接收发送理解:中断是外卖来了,前台打电话给你然后你去取,会有这样子一种情况就是你现在在干一些其他的紧急事情(比如说你在考试),这时候你就需要其他人帮你拿一下外卖,DMA就是充当这个角色
Cubemax中点击DMA中的ADD,添加RX通道和TX通道
在这里插入图片描述
代码编写
在 main.c 中,while 循环前,串口初始化后,添加DMA方式接收中断开启函数,这样在第一次接收到数据的时候才会触发中断,切记要添加该函数。

HAL_UART_Receive_DMA(&huart1,data,sizeof(data));//data是自己定义的接收中断缓冲

在main.c下方添加中断回调函数,实现串口的发送和接收

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if(huart->Instance==USART1)
	{
		HAL_UART_Transmit_DMA(&huart1,data,sizeof(data));
		HAL_UART_Receive_DMA(&huart1,data,sizeof(data));
	}
}

以上就是关于串口收发的三种方式了,不知道有没有写清楚,后面有更好的表述方式会重修修改的。

  • 4
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
STM32 HAL库中,可以使用DMA方式进行串口接收AD数据。可以使用函数HAL_UART_Receive_DMA来实现。该函数的参数包括UART句柄、接收数据缓冲区的指针和待接收数据的个数。通过调用该函数,可以在DMA方式下接收一定数量的数据。\[2\] 例如,可以使用以下代码来实现DMA方式下的串口接收AD数据: ```c uint8_t adData\[10\]; // 定义接收数据缓冲区 HAL_UART_Receive_DMA(&huart1, adData, 10); // 使用DMA方式接收10个字节的数据 ``` 在接收完成后,可以在DMA中断中调用串口接收中断回调函数HAL_UART_RxCpltCallback进行后续处理。在该回调函数中,可以对接收到的AD数据进行处理。\[2\] ```c void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { // 在这里进行接收数据的处理 // adData数组中存放了接收到的AD数据 } ``` 需要注意的是,在使用DMA方式进行串口接收时,需要配置DMA通道和DMA传输方向。具体的配置可以参考STM32 HAL库的相关文档和例程。 #### 引用[.reference_title] - *1* *2* *3* [[016] [STM32] 串口HAL库轮询中断DMA方式传输数据](https://blog.csdn.net/kouxi1/article/details/123876915)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值