利用空闲中断和DMA实现不定长数据的接收(STM32 F411RET6开发版)

实验器材:STM32 F411RET6开发版

任务目标:利用空闲中断和DMA实现不定长数据的接收

任务内容:PC发送任意唱的数据到Nucleo开发板,开发板将数据原样回传到PC

一、CubeMX配置

关于CubeMX配置参考http://t.csdn.cn/gGp3x,相同设置部分不再赘述

 3.3 Connectivity 配置

在NVIC Settings下勾选“USART2 global interrupt”

 在DMA Settings下设置如下

   二 Cube IDE程序编写

关于Cube IDE中添加头文件及串口重定向同http://t.csdn.cn/gGp3x中1/6完全一致

1. 进行宏定义

/* USER CODE BEGIN PD */
#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#define GETCHAR_PROTOTYPE int __io_getchar(FILE *f)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch,FILE *f)
#define GETCHAR_PROTOTYPE int fgetc(FILE *f)
#endif

#define LENGTH  100 //数据缓冲区大小,该数据一定要大于一帧数据的总字符数
/* USER CODE END PD */

2.定义自变量

/* USER CODE BEGIN PV */
extern DMA_HandleTypeDef hdma_usart2_rx;  
extern DMA_HandleTypeDef hdma_usart2_tx;
extern UART_HandleTypeDef huart2;
uint8_t  RxBuffer[LENGTH];    //数据缓冲区
uint8_t  RxCount=0;          //实际接受的数据项数
volatile uint8_t RxFlag=0;   //数据接受标志
/* USER CODE END PV */

3.用户代码2

  /* USER CODE BEGIN 2 */
  //发送提示信息
  printf ("/*******UART Communication LL using IDLE IT + DMA *******\r\n");
  printf ("Please enter arbitrary length characters:\r\n");
  __HAL_UART_ENABLE_IT(&huart2,UART_IT_IDLE); //使能IDLE中断
  HAL_UART_Receive_DMA(&huart2, (uint8_t *)RxBuffer, LENGTH);//启动DMA接受
  /* USER CODE END 2 */

4.用户代码3

  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
	  if( RxFlag==1 ) //判断接收是否完成
	  {
		  RxFlag=0;  //清除数据接收标志
		  RxCount = LENGTH - __HAL_DMA_GET_COUNTER(&hdma_usart2_rx);  
		  HAL_UART_Transmit_DMA(&huart2,(uint8_t *)RxBuffer,RxCount);
		  __HAL_DMA_DISABLE(&hdma_usart2_rx);
	  }
  }
  /* USER CODE END 3 */
}

5.用户代码4

/* USER CODE BEGIN 4 */

PUTCHAR_PROTOTYPE
{
  HAL_UART_Transmit(&huart2, (uint8_t*)&ch, 1, HAL_MAX_DELAY);
  return ch;
}

GETCHAR_PROTOTYPE
{
	uint8_t  ch;
	HAL_UART_Receive(&huart2,(uint8_t *)&ch, 1, HAL_MAX_DELAY);
    return  ch;
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if(huart->Instance==USART2)
	{
		HAL_UART_Receive_DMA(&huart2, (uint8_t *)RxBuffer, LENGTH);
	}
}
void HAL_UART_IdleCpltCallback(UART_HandleTypeDef *huart)
{
	RxFlag =1 ;
}

/* USER CODE END 4 */

6. 在stm32f4xx_it.c中添加的函数

6.1引用变量

/* USER CODE BEGIN EV */

extern volatile uint8_t RxFlag;

/* USER CODE END EV */

6.2撰写  void USART2_IRQHandler(void)

void USART2_IRQHandler(void)
{
  /* USER CODE BEGIN USART2_IRQn 0 */

  /* USER CODE END USART2_IRQn 0 */
  HAL_UART_IRQHandler(&huart2);
  /* USER CODE BEGIN USART2_IRQn 1 */
	if (__HAL_UART_GET_FLAG(&huart2,UART_FLAG_IDLE)!=RESET)
	{
		__HAL_UART_CLEAR_IDLEFLAG(&huart2);
		HAL_UART_IdleCpltCallback(&huart2);
		RxFlag=1;
	}
  /* USER CODE END USART2_IRQn 1 */
}

7.在main.h中添加代码

/* USER CODE BEGIN EFP */
void HAL_UART_IdleCpltCallback(UART_HandleTypeDef *huart);
/* USER CODE END EFP */

8. 实验结果

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值