当前位置:   article > 正文

设计分享 | STM32F103RCT6实现DMA数据转运_stm32f103 rtt dma

stm32f103 rtt dma

wechat:嵌入式工程师成长日记

https://mp.weixin.qq.com/s?__biz=Mzg4Mzc3NDUxOQ==&mid=2247484202&idx=1&sn=d971dc5e34e9dc3365cc3aeae44dac58&chksm=cf430672f8348f644e4a76094b8c27b389f18c2586b020740f9a2c2837aaabe34194b6bb8404&token=1206186946&lang=zh_CN#rdicon-default.png?t=M85Bhttps://mp.weixin.qq.com/s?__biz=Mzg4Mzc3NDUxOQ==&mid=2247484202&idx=1&sn=d971dc5e34e9dc3365cc3aeae44dac58&chksm=cf430672f8348f644e4a76094b8c27b389f18c2586b020740f9a2c2837aaabe34194b6bb8404&token=1206186946&lang=zh_CN#rd

具体功能实现

打开开关后,OLED屏上显示数组DataA和DataB的数据。DataA是源地址数据,DataB是目的地址数据,将DataA中的数据每隔一秒自增加一然后通过DMA控制器传输至DataB。为了加强效果,DataA中数据自增一后需要间隔一秒才会在DataB数组中的显示

STM32F103RCT6原理图

器件

STM32F103RCT6,OLED屏,四根杜邦线

前后展示图

DMA转运前:

此时是转运前,DataA中的数据自增一,此时还没有开始转运,所以DataB中的数据还是原来的。

DMA转运后

此时是转运后,DataA中的数据已经传给了DataB

知识介绍

DMA介绍

全称是直接存储器存取,用来提供外设和存储器之间或存储器和存储器之间的高速数据传输。它的作用是不需要经过CPU进行数据传输,换句话说就是替CPU分担任务。同时,DMA可以将数据从源地址中的数据转移到目的地址而不经过CPU的干预。

12个独立可配置通道:DMA1(7个通道)和DMA2(5个通道)

最常用的用途:配合ADC的扫描模式,因为ADC有个最大的缺点是数据覆盖,如果不适用DMA则ADC的功能会受到很大的限制

需要配置的内容:方向,传输计数器,选择硬件触发还是软件触发,自动重装器,M2M(是否为存储器到存储器模式),使能开关DMA

数据选择器

数据选择器是经过选择,把多个通道的数据传送到唯一的公共数据通道上去,实现数据选择功能的逻辑电路,有时也叫多路选择器或多路调制器

仲裁器

根据通道的优先级来启动外设/存储器的访问。配置通道的优先级,决定哪个通道先执行,哪个通道后执行

循环模式和存储器模式

循环模式:用于处理循环缓存区和连续的数据传输(如ADC的扫描模式)。当启动扫描模式后,数据传输的数目变为0,将会自动恢复成配置通道时设定的初值,DMA将继续执行操作。

存储器模式:DMA在没有外设请求下,这种操作方式就是存储器到存储器模式。(不能和循环模式同时使用)

DMA寄存器

①DMA中断状态寄存器(DMA_ISR)

②DMA中断标志清除寄存器(DMA_IFCR)

③DMA通道配置寄存器(DMA_CCR)

④DMA通道传输数量寄存器(DMA_CNDTR)

⑤DMA通道外设地址寄存器(DMA_CPAR)

⑥DMA通道存储器地址寄存器(DMA_CMAR)

存储器、寄存器地址

0x08 程序存储器FLASH

0x20 运行内存SRAM

0x40 外设寄存器

0xE0 内核外设寄存器

M2M

全称:memory to memory

模式:存储器到存储器模式

触发方式:软件触发

总线:AHB,所以开启的是AHB总线时钟——RCC_AHBPeriphClockCmd()

const

定义数组可以将数据存储在Flash,将变量变为常量,const定义的变量的值是不允许被更改的

存储器映像

重要:存储器Flash和运行内存SRAM

Flash用来存储C语言编译后的程序代码

SRAM用来存储运行中的临时变量

主函数代码(C语言)KEIL5实现

  1. //main.c
  2. #include "stm32f10x.h"  
  3. #include "Delay.h"
  4. #include "OLED.h"
  5. #include "MyDMA.h"
  6. uint8_t DataA[] = {0x01,0x02,0x03,0x04};//
  7. uint8_t DataB[]={0,0,0,0};//目的
  8. int main(void)
  9. {
  10. OLED_Init();
  11. MyDMA_Init((uint32_t)DataA,(uint32_t)DataB,4);
  12. OLED_ShowString(1,1,"DataA:");
  13. OLED_ShowString(3,1,"DataB:");
  14. OLED_ShowHexNum(1,8,(uint32_t)DataA,8);
  15. OLED_ShowHexNum(3,8,(uint32_t)DataB,8);
  16. while(1)
  17. {
  18. DataA[0]++;
  19. DataA[1]++;
  20. DataA[2]++;
  21. DataA[3]++;
  22. OLED_ShowHexNum(2,1,DataA[0],2);
  23. OLED_ShowHexNum(2,4,DataA[1],2);
  24. OLED_ShowHexNum(2,7,DataA[2],2);
  25. OLED_ShowHexNum(2,10,DataA[3],2);
  26. OLED_ShowHexNum(4,1,DataB[0],2);
  27. OLED_ShowHexNum(4,4,DataB[1],2);
  28. OLED_ShowHexNum(4,7,DataB[2],2);
  29. OLED_ShowHexNum(4,10,DataB[3],2);
  30. Delay_ms(1000);
  31. MyDMA_Transfer();//开始转换
  32. OLED_ShowHexNum(2,1,DataA[0],2);
  33. OLED_ShowHexNum(2,4,DataA[1],2);
  34. OLED_ShowHexNum(2,7,DataA[2],2);
  35. OLED_ShowHexNum(2,10,DataA[3],2);
  36. OLED_ShowHexNum(4,1,DataB[0],2);
  37. OLED_ShowHexNum(4,4,DataB[1],2);
  38. OLED_ShowHexNum(4,7,DataB[2],2);
  39. OLED_ShowHexNum(4,10,DataB[3],2);
  40. Delay_ms(1000);
  41. }
  42. }
  43. //AD.c
  44. #include "stm32f10x.h"  
  45. uint16_t MyDMA_Size;
  46. void MyDMA_Init(uint32_t AddrA, uint32_t AddrB, uint16_t Size)
  47. {
  48. MyDMA_Size = Size;
  49. RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
  50. DMA_InitTypeDef DMA_InitStructure;
  51. DMA_InitStructure.DMA_PeripheralBaseAddr = AddrA;
  52. DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
  53. DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable;
  54. DMA_InitStructure.DMA_MemoryBaseAddr = AddrB;
  55. DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
  56. DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  57. DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
  58. DMA_InitStructure.DMA_BufferSize = Size;
  59. DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
  60. DMA_InitStructure.DMA_M2M = DMA_M2M_Enable;
  61. DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
  62. DMA_Init(DMA1_Channel1, &DMA_InitStructure);
  63. DMA_Cmd(DMA1_Channel1, DISABLE);
  64. }
  65. void MyDMA_Transfer(void)
  66. {
  67. DMA_Cmd(DMA1_Channel1, DISABLE);
  68. DMA_SetCurrDataCounter(DMA1_Channel1,MyDMA_Size);
  69. DMA_Cmd(DMA1_Channel1, ENABLE);
  70. while(DMA_GetFlagStatus(DMA1_FLAG_TC1)==RESET);
  71. DMA_ClearFlag(DMA1_FLAG_TC1);
  72. }

 

WeChat:嵌入式工程师成长日记

https://mp.weixin.qq.com/s?__biz=Mzg4Mzc3NDUxOQ==&mid=2247484202&idx=1&sn=d971dc5e34e9dc3365cc3aeae44dac58&chksm=cf430672f8348f644e4a76094b8c27b389f18c2586b020740f9a2c2837aaabe34194b6bb8404&token=1206186946&lang=zh_CN#rdicon-default.png?t=M85Bhttps://mp.weixin.qq.com/s?__biz=Mzg4Mzc3NDUxOQ==&mid=2247484202&idx=1&sn=d971dc5e34e9dc3365cc3aeae44dac58&chksm=cf430672f8348f644e4a76094b8c27b389f18c2586b020740f9a2c2837aaabe34194b6bb8404&token=1206186946&lang=zh_CN#rd

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/酷酷是懒虫/article/detail/877313
推荐阅读
相关标签
  

闽ICP备14008679号