你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【说出你的故事】在外设与存储器之间  

[复制链接]
creep 提问时间:2016-2-21 22:08 /
    偶然看到自己刚来社区时发的一个关于DMA的跟帖 说的是使用DMA写SD。在社区STM32的交流QQ群里也经常看到很多小伙伴在讨论DMA,那今天就说说我常用的几个例子。

参考手册上是这样介绍DMA的:用于在外设与存储器之间以及存储器与存储器之间提供高速数据传输。可以在无需任何 CPU 操作的情况下通过 DMA 快速移动数据。这样节省的 CPU 资源可供其它操作使用。从上面我们可以看到DMA就好比是个“包邮的快递”一样,可以不收钱(不占用CPU)帮我们送快递(传递数据),有这等便宜岂能放过,我们必须要“用用用”!

1、DMA写SD卡
我最开始使用DMA是写SD卡,因为STM32的SPI在连续传递数据时字节和字节之间有很大的时间间隔,这导致了写一个扇区需要很长的时间,经过很多测试发现字节之间的间隔没法很好的被优化掉,所以就考虑用DMA写SD卡了。使用DMA写SD卡时只需设置好要写的数据,然后使能DMA传输完成中断,在中断中判断写数据是否成功。
如果使用常规的SPI写SD没有问题,那么修改为SPI的DMA模式写SD就卡就比较简单了。只需要修改下面几个函数即可。
1) 在写512字节时使用DMA传输
1.jpg
2.jpg

2) 在中断函数中进行判断即可
  1. <font size="4" face="Tahoma">void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi)
  2. {
  3.                 uint8_t t,s;
  4.                 //扇区写完后发送校验字节
  5.                 SPI2_ReadWriteByte(0xFF);
  6.                 SPI2_ReadWriteByte(0xFF);
  7.                 for(s = 0;s < 255;s++)
  8.                 {
  9.                         //接收响应        
  10.                         t = SPI2_ReadWriteByte(0xFF);
  11.                         if((t&0x1F)==0x05)        
  12.                         {
  13.                                 SD_DMA_Write_Status = Status_OK;
  14.                                 break;
  15.                         }
  16.                 }
  17.                 if(s == 0xff)
  18.                 {
  19.                         s = s;
  20.                 }
  21.                 SD_DisSelect();

  22. }</font>
复制代码
2、DMA传输多通道ADC采集数据

这个测试使用NUCLEO-STM32F410RB,我们先初始化4个通道的ADC输出,然后用DMA将转换的数据传到数组中。
  4个通道配置如下:

adc_1.jpg
ADC1初始化如下:
adc_2.jpg
然后在main函数中开始adc的转换:
  1. <font size="4" face="Tahoma">#include "main.h"

  2. __IO uint16_t uhADCxConvertedValue[4];
  3. int main(void)
  4. {
  5.         HAL_Init();
  6.         SystemClock_Config();
  7.         LED_Init();
  8.         USART2_Init();
  9.         ADC1_Init();
  10.         ADC1_Config();
  11.         HAL_ADC_Start_DMA(&AdcHandle, (uint32_t*)&uhADCxConvertedValue, 4);

  12.         while(1)
  13.         {
  14.                
  15.         }               
  16. }
  17. </font>
复制代码
首先悬空4个输入引脚,从转换结果可以看到ADC的值为随机值,这也说明了可以使用悬空ADC引脚的方法来产生随机数是可行的

adc_3.jpg adc_4.jpg
将其中的2个通道接地,可以看到ADC的值接近0


adc5.png


3、使用DMA和串口空闲中断接收不定长数据
这个测试也使用NUCLEO-STM32F410RB。串口在接收数据时使用空闲中断和DMA接收不定长的数据,在发送时使用DMA发送。使用这个方法能够很方便的接收不定长的数据,但是也有一些限制,实际使用中如果出现问题要根据需要优化。

需要注意的是使用HAL库要自己写个回调函数如下:
232_0.jpg
在main中我们将PC端发送的数据返回到PC端:
  1. <font size="4" face="Tahoma">#include "main.h"

  2. int main(void)
  3. {
  4.         HAL_Init();
  5.         SystemClock_Config();
  6.         LED_Init();
  7.         USART2_Init();
  8.         while(1)
  9.         {
  10.                 if(U1_Rxlen)
  11.                 {
  12.                         HAL_UART_Transmit_DMA(&UARTHandle,aU3RxBuff,U1_Rxlen);
  13.                         U1_Rxlen = 0;
  14.                 }
  15.         }               
  16. }
  17. </font>
复制代码

发送不同长度的数据,可以看到都能够正确接收:
232_1.jpg

      上面只是DMA的几个最简单的使用,因为比较常用而且简单,所以并没有详细的叙述,具体可以参考代码。测试代码是使用hal写的,明白了原理很容易转换为标准库。DMA在其他的外设也有很多可以使用的场合,合理使用DMA能起到事倍功半的效果。

    周末撸代码不易,希望人品能够给力赶上这个活动的末班车 :)  @苏柚

  测试代码:
SPI SD DMA.rar (4.36 KB, 下载次数: 61)
收藏 9 评论25 发布时间:2016-2-21 22:08

举报

25个回答
creep 回答时间:2016-11-29 14:08:37
honyuan 发表于 2016-11-29 10:52
此贴有BUG
没有标示出UART_IDLE_Callback(&UARTHandle);中断函数的调用位置
我移植到F405上,DMA发送数据结 ...

我在410/429/469上测试过这个代码,没发现特别明显的bug,不清楚是不是在405上有问题。
creep 回答时间:2016-3-2 08:59:32

                                
honyuan 回答时间:2016-11-29 10:52:11
此贴有BUG
没有标示出UART_IDLE_Callback(&UARTHandle);中断函数的调用位置
我移植到F405上,DMA发送数据结束后,不能自动清除寄存器中的数据
lisingch 回答时间:2016-2-21 22:24:38
这贴子不错,长知识。
creep 回答时间:2016-2-21 23:09:37
lising 发表于 2016-2-21 22:24
这贴子不错,长知识。

感谢支持  
zhwd102198 回答时间:2016-2-23 14:16:08
idodoyo 回答时间:2016-3-1 17:41:47
这个可以,最开始为难了好久
creep 回答时间:2016-3-1 18:41:37
idodoyo 发表于 2016-3-1 17:41
这个可以,最开始为难了好久

是的,刚开始接触的时候的确有点难搞。
海绵宝宝233 回答时间:2016-3-2 08:52:09
学习了。。。
雪山飞狼 回答时间:2016-3-2 21:39:38
谢谢分享,支持一个!
creep 回答时间:2016-3-2 23:22:02
雪山飞狼 发表于 2016-3-2 21:39
谢谢分享,支持一个!

感谢支持!!!
xinnian-400985 回答时间:2016-3-14 17:32:45
谢谢分享
wofei1314 回答时间:2016-10-26 14:58:03
新手学习中.....
creep 回答时间:2016-10-26 18:09:17

客气了            
peter001 回答时间:2016-10-27 12:49:01
这个帖子不错
ynwscfsfi 回答时间:2016-10-31 13:52:24
谢谢分享,支持一个!
12下一页

所属标签

相似问题

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版