基于CubeMX的STM32串口DMA模式配置

提示:本文内容仅作参考


前言

本文提出基于CubeMX的STM32芯片配置串口DMA模式的方法,本文方法仅供参考。


一、串口简介

串行接口简称串口,也称串行通信接口或串行通讯接口(通常指COM接口),是采用串行通信方式的扩展接口。串行接口 (Serial Interface)是指数据一位一位地顺序传送。其特点是通信线路简单,只要一对传输线就可以实现双向通信(可以直接利用电话线作为传输线),从而大大降低了成本,特别适用于远距离通信,但传送速度较慢。

二、CubeMX配置详解

1.配置串口

此处使用串口1作为测试工具,具体来说使用PA9和PA10作为串口发送引脚。
①.在新建的工程里面配置PA9和PA10分别为串口的发送与接收引脚,如下图所示,此时引脚显示为黄色,表示暂未激活。

②.下一步需要对串口模式进行选择以激活,找到Connectivity下的USART1选项并点击,界面如下.

③.选择通信模式

在右上角配置界面的第一个配置为异步通信模式即可,即为Asynchronous。除了通讯模式的配置外,此界面还有一些常用工业接口(RS232\RS585)的硬件流控,在此无需使用。配置图如下。

在配置为异步通信模式后,引脚变为绿色,表示已经配置。

④.基本参数设置

a) 通信波特率为115200,数据长度8个字节,停止位1位,双向传输模式。

b) 设置中断模式:打开全局中断

此外,需要在NVIC Setting里面设置打开串口的全局中断,部分型号不打开此中断会出现传输失败的问题(如下图,在方框勾选即可)。

c) 配置DMA

找到DMA Settings这一栏,点击ADD添加DMA数据流,这里把发送和接收的DMA全部打开,同时注意DMA的配置,一般的串口都是8位,因此使用默认的DMA配置即可(也就是指针自增为BYTE)。

此处可以对串口接收的DMA进行更多设置,比如设置DMA模式为Circular,使DMA在一次接收完成后自动开启下一次接收。

d) gpio配置

CUBEMX配置到此结束,点击生成代码即可,然后可以直接在框架中使用串口DMA通信了。

2.代码参考

①.中断函数修改

在stm32f1xx_it.c文件中修改函数USART1_IRQHandler,打开DMA中断接收。

void USART1_IRQHandler(void)
{
     /* USER CODE BEGIN USART1_IRQn 0 */
	 //userUart1Handler();
     /* USER CODE END USART1_IRQn 0 */
     HAL_UART_IRQHandler(&huart1);
     /* USER CODE BEGIN USART1_IRQn 1 */
	 //USART1_IRQ_Func();
	 //#if uart_DMA_chonse
	 USART_DMA_IDLE_Func();//开启DMA接收中断
	 //#endif
     /* USER CODE END USART1_IRQn 1 */
}

②.中断函数体修改

在文件usart.c文件中修改函数USART_DMA_IDLE_Func(void)

extern uint8_t uart1RxState;
extern uint8_t uart1RxBuf[usartFifoLength];
extern uint8_t uart1RxCounter;
void USART_DMA_IDLE_Func(void)
{
	uint32_t temp;
	uint8_t flag=0;
	int i = 0;
	if(USART1 == huart1.Instance)//判断是否为串口1中断
	{
		flag=__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE);
		if(flag!=RESET)
		{
			huart1.gState = HAL_UART_STATE_READY;
			__HAL_UART_CLEAR_IDLEFLAG(&huart1);//清除中断标志位
			HAL_UART_DMAStop(&huart1);//停止DMA接收
			temp  = __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);//获取DMA当前还有多少未填充
			DMA_Rx_len =  DAM_Buff_Cnt - temp; //计算接收到的串口数据个数
			for(i = 0;i<DMA_Rx_len;i++)
			{
				uart1RxBuf[uart1RxCounter++] = DMA_Rx_Buff[i];
			}
			uart1RxState = UART_RX_STATE_DEAL;//主函数While循环查询到这个标志位就会解析数据
		}
	}
}

③.串口发送及接收代码参考

int main(void)
{
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_USART1_UART_Init();
  unsigned char s_buf[]="hello world\r\n";
  HAL_UART_Transmit_DMA(&huart1,s_buf,sizeof(s_buf));//发送DMA数据
  while (1)
  {
		if(uart1RxState==UART_RX_STATE_DEAL)//接收DMA数据
	  {
			for(i = 0;i<uart1RxCounter;i++)
			{
				usartRxFIFOMeg.usart1RxFIFO[usartRxFIFOMeg.usart1RxFIFOIndex++] =         uart1RxBuf[i];
			}
			uart1RxCounter = 0;
			memset(uart1RxBuf,0,sizeof(uart1RxBuf));
		    uart1RxState=UART_RX_STATE_READY;
			DMA_Rx_len=0;//接收数据长度清零
			HAL_UART_Receive_DMA(&huart1,DMA_Rx_Buff,DAM_Buff_Cnt);//开启下一次接收
	  }
  }
}

此处介绍下下面这个函数:

HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
//其中huart为句柄,代表调用的串口名称
//pData为数组的指针
//Size为要发送的数据大小

2.异常处理

a) DMA不通

初始化顺序有要求

MX_DMA_Init();

MX_USART1_UART_Init();

DMA要放在串口初始化之前!!

b) DMA数据接收数据异常

usartRxFIFOMeg.usart1RxFIFO[usartRxFIFOMeg.usart1RxFIFOIndex++] = uart1RxBuf[i];放在主函数中,不要放在DMA数据接收中断中处理外部数组索引等,因为会引起异常错误。


总结

以上就是今天要讲的内容,本文提出基于CubeMX的STM32芯片配置串口DMA模式的方法,本文方法仅供参考,整理资料不易,麻烦留下小爱心。

  • 10
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值