HAL库下Uart与SPI的DMA发送与接收

HAL库下Uart与SPI的DMA发送与接收
一直有想法对HAL库下对串口与与SPI进行DMA方式接收与发送的详细配置了解,以及正确的操作流程。
首先介绍Uart在HAL中实现DMA的发送与接收

串口配置这个就无需我在此叙述,直接进入主题:
软件配置如图,DMA中断默认开启,需要我们采用DMA传输必须要使能串口中断;
HAL_UART_Transmit_DMA(&huart1,Uart_tx_buf,sizeof(Uart_tx_buf));为DMA发送函数

配置完成后灰色默认开启,蓝色为用户可选择此次配置如下

在配置完成后,调用上面的函数就可以直接发送到电脑。
串口的DMA接收,就要麻烦一些,需要了解回调函数:
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)和
HAL_UART_Receive_IT(&huart1,(uint8_t *)Uart_rx_temp,Length);//Uart_DMA数据缓存接收中断
其中Uart_rx_temp,Length为在进入callback函数之前需要接收到的数据长度以及数据接收存放地址。所以在代码main初始化时需要加上。当满足一次接收中断的要求后,就会直接调转到HAL_UART_RxCpltCallback;当然此前CUBEMAX已经就为我们初始化了Uart1的中断。
下面是一段简单的测试代码:
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart->Instance == USART1)
{
Uart_rx_buf[Rx_cnt++]= Uart_rx_temp[0];
Uart_rx_buf[Rx_cnt++]= Uart_rx_temp[1];

	 if((Uart_rx_temp[0] == 0x0D)&&(Uart_rx_temp[1] == 0x0A))
	 {
		  Uart_rec_success= 1;
	 }
	 HAL_UART_Receive_IT(&huart1,(uint8_t *)Uart_rx_temp,Length);
	
 }

在主函数中我们就只要轮询 Uart_rec_success= 1;这个条件是否满足,去执行相对应的结果就行。

在此我遇到一个DMA发送的一个坑,就是谨防在DMA数据没有发送完成时,将数据进行改变。我最开始用:HAL_SPI_Transmit(&hspi1,(uint8_t*)tx_buf,1,10);测试没有任何问题,但: HAL_UART_Transmit_DMA(&huart1,Uart_tx_buf,11);会出现数据掉包,不完整的;结果是因为我在下面一条语句就是
for(i=0;i<Rx_cnt;i++)
Uart_rx_buf[i] = 0;
我也就不多说串口 。下面介绍SPI_DMA 中的配置;
最开始测试:采用 HAL_SPI_Transmit_DMA(&hspi1,(uint8_t*)tx_buf,7);
效果波形如图:

数据正常,但是数据边沿有脉冲,考虑原因可能是采样率太高,造成波形抖动,降低采样率后,有好转,但是尚未完全解决。
HAL_SPI_TransmitReceive_DMA(&hspi1,(uint8_t *)tx_buf,(uint8_t *)rec_buf,(sizeof(tx_buf)/sizeof(uint16_t)));
函数在最开始使用时,数据掉包,审查了发现:
HAL_SPI_TransmitReceive_IT(&hspi1,(uint8_t *)tx_buf,(uint8_t *)rec_buf,7);

接收数据正常,与上图波形一致。为什么DMA全双工数据就会掉包呢?
考虑到并未对缓冲区数据进行操作,就去检查自己的配的工程,发现原来没有打开SPI接收DMA。在此三个函数都能正常数据传输。
对于回调函数,也和串口相似,只需要在发送或则从机接收完成后,就会进去执行各种flag,需要控制操作就在主函数进行操作判断。但是最近从机的SPI一直有问题,数据乱码不稳定,希望后面能够解决,或得到网友的帮助。

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值