基于中断/DMA的串口通信

1.DMA

1.1DMA的基本介绍

直接存储器访问(Direct Memory Access),简称DMA。DMA是CPU一个用于数据从一个地址空间到另一地址空间“搬运”(拷贝)的组件,数据拷贝过程不需CPU干预,数据拷贝结束则通知CPU处理。因此,大量数据拷贝时,使用DMA可以释放CPU资源。DMA数据拷贝过程,典型的有:
·内存—>内存,内存间拷贝
·外设—>内存,如uart、spi、i2c等总线接收数据过程
·内存—>外设,如uart、spi、i2c等总线发送数据过程
因此:转移数据(尤其是转移大量数据)是可以不需要CPU参与。比如希望外设A的数据拷贝到外设B,只要给两种外设提供一条数据通路,直接让数据由A拷贝到B 不经过CPU的处理,
在这里插入图片描述

DMA就是基于以上设想设计的,它的作用就是解决大量数据转移过度消耗CPU资源的问题。有了DMA使CPU更专注于更加实用的操作–计算、控制等。

1.2DMA传输参数

我们知道,数据传输,首先需要的是1 数据的源地址 2 数据传输位置的目标地址 ,3 传递数据多少的数据传输量 ,4 进行多少次传输的传输模式 DMA所需要的核心参数,便是这四个。

当用户将参数设置好,主要涉及源地址、目标地址、传输数据量这三个,DMA控制器就会启动数据传输,当剩余传输数据量为0时 达到传输终点,结束DMA传输 ,当然,DMA 还有循环传输模式 当到达传输终点时会重新启动DMA传输。
  
也就是说只要剩余传输数据量不是0,而且DMA是启动状态,那么就会发生数据传输。
在这里插入图片描述

1.3DMA的主要特征

每个通道都直接连接专用的硬件DMA请求,每个通道都同样支持软件触发。这些功能通过软件来配置:
1、在同一个DMA模块上,多个请求间的优先权可以通过软件编程设置(共有四级:很高、高、中等和低),优先权设置相等时由硬件决定(请求0优先于请求1,依此类推);
2、独立数据源和目标数据区的传输宽度(字节、半字、全字),模拟打包和拆包的过程。源和目标地址必须按数据传输宽度对齐;
3、支持循环的缓冲器管理;
4、每个通道都有3个事件标志(DMA半传输、DMA传输完成和DMA传输出错),这3个事件标志逻辑或成为一个单独的中断请求;
5、存储器和存储器间的传输、外设和存储器、存储器和外设之间的传输;
闪存、SRAM、外设的SRAM、APB1、APB2和AHB外设均可作为访问的源和目标;
6、可编程的数据传输数目:最大为65535。
DMA传输
DMA传输时外设对DMA控制器发出请求。
DMA控制器收到请求,触发DMA工作。
DMA控制器从AHB外设获取ADC采集的数据,存储到DMA通道中
DMA控制器的DMA总线与总线矩阵协调,使用AHB把外设ADC采集的数据经由DMA通道存放到SRAM中,这个数据的传输过程中,完全不需要内核的参与,也就是不需要CPU的参与。

2.实验过程

2.1创建工程

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.2 添加代码

添加头文件

#include "stdio.h"
#include "string.h"

添加变量

uint8_t RxBuffer[LENGTH]; //字符缓冲区,LENGTH定义为4
uint8_t RxFlag = 0;//是否接受到stop
uint8_t ch;//额外字符't'的缓冲区
uint8_t flag = 1;//是否需要继续接收额外字符

添加while循环

while (1)
  {
    /* USER CODE END WHILE */
	  if(RxFlag == 0){
		  HAL_UART_Transmit(&huart1,(uint8_t*)"hello windows!\r\n",16,0xffff);
		  HAL_Delay(1000);
	  }
    /* USER CODE BEGIN 3 */
  }

添加中断接收回调函数

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){
	if(huart->Instance == USART1&&strcmp((char *)RxBuffer,"stop")==0){
		RxFlag = 1;
		HAL_UART_Receive_IT(huart, (uint8_t*)&RxBuffer, LENGTH);
	}else if(huart->Instance == USART1&&strcmp((char *)RxBuffer,"star")==0&&flag==1){
		flag = 0;
		HAL_UART_Receive_IT(huart, (uint8_t*)&ch, 1);
	}
	if(huart->Instance == USART1 && ch == 't' && flag == 0){
		RxFlag = 0;
		flag = 1;
		ch = '0';
		HAL_UART_Receive_IT(huart, (uint8_t*)&RxBuffer, LENGTH);
	}
}

3.结果

在这里插入图片描述
在这里插入图片描述

4.波形图

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值