st_dma.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. #include "st_sys.h"
  2. #include "st_dma.h"
  3. static DMA_Stream_TypeDef * st_dma_steam_map[] = {
  4. DMA1_Channel1,
  5. DMA1_Channel2,
  6. DMA1_Channel3,
  7. DMA1_Channel4,
  8. DMA1_Channel5,
  9. DMA1_Channel6,
  10. DMA1_Channel7,
  11. DMA2_Channel1,
  12. DMA2_Channel2,
  13. DMA2_Channel3,
  14. DMA2_Channel4,
  15. DMA2_Channel5
  16. };
  17. /**
  18. * 初始化DMA
  19. *
  20. * @author lxz
  21. */
  22. void st_dma_init(void)
  23. {
  24. //使能DMA2 DMA1的时钟
  25. int index = 0;
  26. do
  27. {
  28. RCC->AHBENR|=3<<0;
  29. }while ((RCC->AHBENR & (0x03 << 0)) == 0);
  30. while(index <= ST_DMA2_STREAM5)
  31. {
  32. DMA_Stream_TypeDef *DMA_Streamx = st_dma_steam_map[index];
  33. DMA_Streamx->CCR = 0;
  34. DMA_Streamx->CNDTR = 0;
  35. DMA_Streamx->CPAR = 0;
  36. DMA_Streamx->CMAR = 0;
  37. index++;
  38. }
  39. }
  40. //DMAx的各通道配置
  41. //这里的传输形式是固定的,这点要根据不同的情况来修改
  42. //从存储器->外设模式/8位数据宽度/存储器增量模式
  43. //DMA_Streamx:DMA数据流,DMA1_Stream0~7/DMA2_Stream0~7
  44. //chx:DMA通道选择,范围:1~115(详见<<STM32H7xx参考手册>>16.3.2节,Table 116)
  45. //par:外设地址
  46. //mar:存储器地址
  47. //ndtr:数据传输量
  48. void st_dma_config(uint8_t streamx,uint8_t chx,uint32_t par,uint32_t mar,uint16_t ndtr)
  49. {
  50. DMA_Stream_TypeDef *DMA_Streamx;
  51. DMA_Streamx = st_dma_steam_map[streamx];
  52. DMA_Streamx->CPAR=par; //DMA外设地址
  53. DMA_Streamx->CMAR=mar; //DMA 存储器0地址
  54. DMA_Streamx->CNDTR=ndtr; //DMA 存储器0地址
  55. DMA_Streamx->CCR=0; //先全部复位CR寄存器值
  56. DMA_Streamx->CCR|=1<<6; //存储器到外设模式
  57. DMA_Streamx->CCR|=0<<8; //非循环模式(即使用普通模式)
  58. DMA_Streamx->CCR|=0<<9; //外设非增量模式
  59. DMA_Streamx->CCR|=1<<10; //存储器增量模式
  60. DMA_Streamx->CCR|=0<<11; //外设数据长度:8位
  61. DMA_Streamx->CCR|=0<<13; //存储器数据长度:8位
  62. DMA_Streamx->CCR|=1<<16; //中等优先级
  63. DMA_Streamx->CCR|=0<<21; //外设突发单次传输
  64. DMA_Streamx->CCR|=0<<23; //存储器突发单次传输
  65. DMA_Streamx->CCR |= chx << 25;
  66. //DMA_Streamx->FCR=0X21; //FIFO控制寄存器
  67. }
  68. //开启一次DMA传输
  69. //DMA_Streamx:DMA数据流,DMA1_Stream0~7/DMA2_Stream0~7
  70. //ndtr:数据传输量
  71. void st_dma_enable(uint8_t streamx,uint16_t ndtr)
  72. {
  73. DMA_Stream_TypeDef *DMA_Streamx = st_dma_steam_map[streamx];
  74. DMA_Streamx->CCR&=~(1<<0); //关闭DMA传输
  75. while(DMA_Streamx->CCR&0X1); //确保DMA可以被设置
  76. DMA_Streamx->CNDTR=ndtr; //DMA 存储器0地址
  77. DMA_Streamx->CCR|=1<<0; //开启DMA传输
  78. }
  79. /**
  80. * 停止DMA
  81. *
  82. * @author lxz
  83. *
  84. * @param streamx
  85. */
  86. void st_dma_disable(uint8_t streamx)
  87. {
  88. st_dma_steam_map[streamx]->CCR &= ~(1 << 0);
  89. }
  90. /**
  91. * 获取DMA的实体指针
  92. *
  93. * @author lxz
  94. *
  95. * @param streamx
  96. *
  97. * @return void*
  98. */
  99. void * st_dma_get_stream(uint8_t streamx)
  100. {
  101. SW_WAIT_FINISH(streamx > ST_DMA2_STREAM5);
  102. return st_dma_steam_map[streamx];
  103. }
  104. /**
  105. * 获取DMA通道所在的DMA
  106. *
  107. * @author lxz
  108. *
  109. * @param streamx
  110. *
  111. * @return void*
  112. */
  113. void * st_dma_get_dmax(uint8_t streamx)
  114. {
  115. SW_WAIT_FINISH(streamx > ST_DMA2_STREAM5);
  116. if(streamx > ST_DMA1_STREAM7)
  117. {
  118. return DMA2;
  119. }
  120. return DMA1;
  121. }
  122. /**
  123. * 判断通道是否使能了
  124. *
  125. * @author lxz
  126. *
  127. * @param streamx
  128. *
  129. * @return void*
  130. */
  131. int st_dma_is_enable(uint8_t streamx)
  132. {
  133. return (((DMA_Stream_TypeDef *)st_dma_get_stream(streamx))->CCR & 0x0001);
  134. }