第8周实验 基于中断DMA方式的串口通信

第8周实验 基于中断/DMA方式的串口通信

一、DMA串口通信与中断

DMA (Direct Memory Access) 是一种数据传输方式,用于实现高速的设备之间的数据传输,而不需要 CPU 的干预。在传统的串口通信中,数据的传输需要 CPU 介入,通过轮询或中断的方式进行数据的收发。而使用 DMA 串口通信,可以通过 DMA 控制器直接进行数据的传输,减轻了 CPU 的负担,提高了数据传输的效率。

DMA 串口通信的流程如下:

  1. 配置串口通信参数:包括波特率、数据位数、停止位等参数;
  2. 配置 DMA 控制器:设置 DMA 通道和传输方向(接收或发送);
  3. 配置 DMA 缓冲区:设置用于数据传输的缓冲区地址和大小;
  4. 启动 DMA 传输:通过编程方式启动 DMA 传输;
  5. 在传输完成后,DMA 控制器会触发中断通知 CPU。

中断是一种机制,用于处理异步事件或外部设备的请求。在串口通信中,中断可以用于通知 CPU 数据的传输完成或数据的接收。当 DMA 传输完成时,DMA 控制器会发出中断信号,中断控制器会将中断请求传递给 CPU,CPU 接收到中断请求后会执行相应的中断处理程序。

中断处理程序的流程如下:

  1. CPU 接收到中断请求后,保存当前的执行现场(包括程序计数器、寄存器等);
  2. 执行中断处理程序,处理与中断相关的操作,如数据的接收或发送、状态的更新等;
  3. 中断处理程序执行完毕后,恢复之前保存的执行现场,继续执行被中断的程序。

通过使用 DMA 串口通信和中断,可以实现高效的数据传输和并行处理,提高系统的性能和效率。

二、实验过程

1.设置项目

打开STM32CubeMX,创建一个新项目,选择芯片,进入设置
在这里插入图片描述

设置RCC
在这里插入图片描述

设置SYS
在这里插入图片描述

设置USART
在这里插入图片描述

设置NVIC
在这里插入图片描述

创建项目
在这里插入图片描述

2.keil设置

项目创建完毕,打开项目,点击uzer里面的main.c,修改main.c里面的内容
在这里插入图片描述

main.c函数代码如下:

#include “main.h”
#include “usart.h”
#include “gpio.h”
#include <string.h>

void SystemClock_Config(void);

char start[6] = “start”;
char message[]=“hello Windows\r\n”;//输出信息
char tips[]=“CommandError\r\n”;//提示1
char tips1[]=“Start…\r\n”;//提示2
char tips2[]=“Stop…\r\n”;//提示3
int flag=0;//标志 0:停止发送 1.开始发送

int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART1_UART_Init();

//设置接受中断
HAL_UART_Receive_IT(&huart1, (uint8_t *)&start, 1);


//当flag为1时,每秒发送一次信息
//当flag为0时,停止
while (1)
{
if(flag==1){
//发送信息
HAL_UART_Transmit(&huart1, (uint8_t *)&message, strlen(message),0xFFFF);

		//延时
		HAL_Delay(1000);
	}

}
}

int stringcompare(char str1[6],char str2[6])
{
for(uint8_t i = 0 ; i < 6 ; i++)
{
if (str1[i] != str2[i])
return 0;
}
return 1;
}

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{

if(stringcompare(start,"stop!"))//输入为stop时,标志位置0
{
	flag=0;
	
}


else if(stringcompare(start,"start"))//输入为 start时,标志位置1
{
	flag=1;
}

//重新设置中断
HAL_UART_Receive_IT(&huart1,(uint8_t*)start,5);

}
/* USER CODE END 4 /
/
*

  • @brief System Clock Configuration
  • @retval None
    */
    void SystemClock_Config(void)
    {
    RCC_OscInitTypeDef RCC_OscInitStruct = {0};
    RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

/** Initializes the RCC Oscillators according to the specified parameters

  • in the RCC_OscInitTypeDef structure.
    /
    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
    RCC_OscInitStruct.HSIState = RCC_HSI_ON;
    RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
    if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
    {
    Error_Handler();
    }
    /
    * Initializes the CPU, AHB and APB buses clocks
    */
    RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
    |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
    RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
    RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
    RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
    RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
{
Error_Handler();
}
}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**

  • @brief This function is executed in case of error occurrence.
  • @retval None
    /
    void Error_Handler(void)
    {
    /
    USER CODE BEGIN Error_Handler_Debug /
    /
    User can add his own implementation to report the HAL error return state /
    __disable_irq();
    while (1)
    {
    }
    /
    USER CODE END Error_Handler_Debug */
    }

执行结果:

在这里插入图片描述

三、实验分析与总结

rn state /
__disable_irq();
while (1)
{
}
/
USER CODE END Error_Handler_Debug */
}

执行结果:

[外链图片转存中…(img-SrbgBOZM-1698929792811)]

三、实验分析与总结

本次实验在上一次实验的基础上,新增加了中断功能,扩展的地方主要就是我们需要发送信息,芯片接收到信息之后反馈信息。难度的话变化不算太大,有上一次的基础这次做来也会容易一些。HAL库的方式确实让整个过程都变得轻松不少。本次实验用字符串来控制接收发送,这也需要注意不能弄错。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值