【STM32+HAL+Proteus】系列学习教程---串口USART(DMA 方式)定长,不定长收发。

实现目标

1、利用UART实现上位机PC与下位机开发板之间的数据通信

2、学会STM32CubeMX软件关于UART的DMA模式配置

3、具体目标:1、实现串口定长收发数据通信;2、串口不定长收发数据通信


一、DMA简介

1、什么是DMA?

DMA(Direct Memory Access)直接内存访问,是一种数据传输方法。利用DMA控制器,将数据直接从一个地址空间复制到另一个地址空间。。

优点:在创建完DMA通道后,它会在合适的时机自动将数据转移,不占用CPU进行转移,且在转移完成后触发一次中断表明转移完成。

2、STM32F103的DMA

        STM32F1系列的MCU有两个DMA控制器(DMA2只存在于大容量产品中),DMA1有7个通道,DMA2有5个通道,每个通道专门用来管理来自于一个或者多个外设对存储器的访问请求。还有一个仲裁器来协调各个DMA请求的优先权。

二、原理图设计

三、STM32CubeMX 配置

1.USART1  DMA模式配置

USART1的参数配置如下,波特率115200,传输数据长度为8 Bit,奇偶检验无,停止位1.其他参数默认

使能USART1中断,串口使用DMA方式必须开启中断,否则程序发送一次数据后,不能判断DMA传输是否完成,串口会一直处于busy状态。

点击Add, 增加USART1_RX和USART1_TX,参数默认。

DMA参数配置:

(1)发送选择 DMA1 Stream 4通道,方向从存储器到外设,优先级为低。

(2)接收选择 DMA1 Stream 5通道,方向从外设到存储器。

(3)mode设置:Normal: 表单次传输,传输一次后终止传输; Circular:表示循环传输,传输完成后又重新开始继续传输,不断循环永不停止。

(4)Data Width:串口数据发送寄存器只能存储8bit,每次发送一个字节,所以数据长度选择Byte。

四、程序设计1(串口定长收发数据通信

1、定义一个数组

/* USER CODE BEGIN PM */

uint8_t Txbuf[] = "好好学习STM32+HAL+PROTUES 系列教程\r\n";
unsigned char rx[16];

/* USER CODE END PM */

2、开机串口DMA发送Txbuf[]数据

  /* USER CODE BEGIN 2 */
    HAL_UART_Transmit_DMA(&huart1, (uint8_t *)Txbuf, sizeof(Txbuf));
    HAL_UART_Receive_DMA(&huart1,rx,sizeof(rx));	
    HAL_Delay(500);	
  /* USER CODE END 2 */

3、接收回调函数,将接收到的数据反发回到上位机

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if(huart == &huart1){ //  将上位机发来的数据完整的返回回去
		HAL_UART_Transmit_DMA(&huart1,rx,sizeof(rx));
		HAL_UART_Receive_DMA(&huart1,rx,sizeof(rx));
	}
}

4、实验现象

说明:由于用16进制显示模式,开机汉字全部显示为16进制。功能:上位机输入定长度(16个字节)的 数字,都能正确的返回显示。

五、程序设计2(串口不定长收发数据通信

1、定义一个数组

/* USER CODE BEGIN PM */

uint8_t Txbuf[] = "好好学习STM32+HAL+PROTUES 系列教程\r\n";
unsigned char rx[16];

/* USER CODE END PM */

2、开机串口DMA发送Txbuf[]数据

  /* USER CODE BEGIN 2 */
		HAL_UART_Transmit_DMA(&huart1, (uint8_t *)Txbuf, sizeof(Txbuf));
		HAL_UARTEx_ReceiveToIdle_DMA(&huart1,rx,sizeof(rx));
		HAL_Delay(500);	
  /* USER CODE END 2 */

3、在usart.h中,添加extern DMA_HandleTypeDef hdma_usart1_rx;

//在usart.h中

/* USER CODE BEGIN Includes */
	 
extern DMA_HandleTypeDef hdma_usart1_rx;
	
/* USER CODE END Includes */

4、接收回调函数,将接收到的数据反发回到上位机

void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
		if(huart == &huart1) //  将上位机发来的数据完整的返回回去
		{ 

			HAL_UART_Transmit_DMA(&huart1,rx,Size);
			HAL_UARTEx_ReceiveToIdle_DMA(&huart1,rx,sizeof(rx));
			__HAL_DMA_DISABLE_IT(&hdma_usart1_rx,DMA_IT_HT);			
	  }
}

5、实验现象

说明:由于用16进制显示模式,开机汉字全部显示为16进制。功能:上位机输入不定长度的 数字,都能正确的返回显示。

  • 21
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

面包板扎

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值