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

查看: 2407|回复: 3

【HAL库每天一例】第010例:DMA_MemToMem

[复制链接]

122

主题

129

回帖

0

蝴蝶豆

论坛元老

最后登录
2019-5-28
发表于 2016-5-15 11:10:23 | 显示全部楼层 |阅读模式
本帖最后由 haohao663 于 2016-6-16 11:16 编辑

【HAL库每天一例】系列例程从今天开始持续更新。。。。。
我们将坚持每天至少发布一个基于YS-F1Pro开发板的HAL库例程,
该系列例程将带领大家从零开始使用HAL库,后面会持续添加模块应用例程。
同样的,我们还程序发布基于HAL库的指导文档和视频教程,欢迎持续关注,并提出改进意见。
例程下载:
资料包括程序、相关说明资料以及软件使用截图
链接:https://pan.baidu.com/s/1i574oPv
密码:r3s3
(硬石YS-F1Pro开发板HAL库例程持续更新\1. 软件设计之基本裸机例程(HAL库版本)\YSF1_HAL-010. DMA-MemToMem

/**
  ******************************************************************************
  *                           硬石YS-F1Pro开发板例程功能说明
  *
  *  例程名称: YSF1_HAL-011. DMA-USART1接发
  *   
  ******************************************************************************
  * 说明:
  * 本例程配套硬石stm32开发板YS-F1Pro使用。
  *
  * 淘宝:
  * 论坛:硬石电子社区
  * 版权归硬石嵌入式开发团队所有,请勿商用。
  ******************************************************************************
  */
【1】例程简介
  DMA:直接内存存取,起源与数字信号处理器(DSP)用于快速数据交换技术,实现不用CPU操作即可
传输数据,大大减少CPU负荷。
  本例程使用DMA最基本功能,实现内部存储空间数据传输。
【2】跳线帽情况
******* 为保证例程正常运行,必须插入以下跳线帽 **********
丝印编号     IO端口      目标功能引脚        出厂默认设置
  JP3        PB0           LED1               已接入
  JP4        PG6           LED2               已接入
  JP5        PG7           LED3               已接入
  
【3】操作及现象
  使用开发板配套的MINI USB线连接到开发板标示“调试串口”字样的MIMI USB接口为开发板供电。
下载完程序之后,通过LED灯状态判断DMA传输状态。

CubeMX_1.jpg
CubeMX_2.jpg
CubeMX_3.jpg


main.c文件内容:
  1. /* 包含头文件 ----------------------------------------------------------------*/
  2. #include "stm32f1xx_hal.h"
  3. #include "led/bsp_led.h"

  4. /* 私有类型定义 --------------------------------------------------------------*/
  5. typedef enum
  6. {
  7.   FAILED = 0,
  8.   PASSED = !FAILED
  9. } TestStatus;

  10. /* 私有宏定义 ----------------------------------------------------------------*/
  11. /* 私有变量 ------------------------------------------------------------------*/
  12. DMA_HandleTypeDef hdma_memtomem_dma1_channel1;

  13. static const uint32_t SRC_Const_Buffer[32]= {
  14.   0x01020304,0x05060708,0x090A0B0C,0x0D0E0F10,
  15.   0x11121314,0x15161718,0x191A1B1C,0x1D1E1F20,
  16.   0x21222324,0x25262728,0x292A2B2C,0x2D2E2F30,
  17.   0x31323334,0x35363738,0x393A3B3C,0x3D3E3F40,
  18.   0x41424344,0x45464748,0x494A4B4C,0x4D4E4F50,
  19.   0x51525354,0x55565758,0x595A5B5C,0x5D5E5F60,
  20.   0x61626364,0x65666768,0x696A6B6C,0x6D6E6F70,
  21.   0x71727374,0x75767778,0x797A7B7C,0x7D7E7F80};

  22. uint32_t DST_Buffer[32];
  23. __IO TestStatus TransferStatus= FAILED;
  24. /* 扩展变量 ------------------------------------------------------------------*/
  25. /* 私有函数原形 --------------------------------------------------------------*/
  26. TestStatus Buffercmp(const uint32_t* pBuffer, uint32_t* pBuffer1, uint16_t BufferLength);
  27. void MX_DMA_Init(void);

  28. /* 函数体 --------------------------------------------------------------------*/
  29. /**
  30.   * 函数功能: 系统时钟配置
  31.   * 输入参数: 无
  32.   * 返 回 值: 无
  33.   * 说    明: 无
  34.   */
  35. void SystemClock_Config(void)
  36. {
  37.   RCC_OscInitTypeDef RCC_OscInitStruct;
  38.   RCC_ClkInitTypeDef RCC_ClkInitStruct;

  39.   RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;  // 外部晶振,8MHz
  40.   RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  41.   RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  42.   RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  43.   RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  44.   RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;  // 9倍频,得到72MHz主时钟
  45.   HAL_RCC_OscConfig(&RCC_OscInitStruct);

  46.   RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
  47.                               |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  48.   RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;       // 系统时钟:72MHz
  49.   RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;              // AHB时钟:72MHz
  50.   RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;               // APB1时钟:36MHz
  51.   RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;               // APB2时钟:72MHz
  52.   HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2);

  53.          // HAL_RCC_GetHCLKFreq()/1000    1ms中断一次
  54.         // HAL_RCC_GetHCLKFreq()/100000         10us中断一次
  55.         // HAL_RCC_GetHCLKFreq()/1000000 1us中断一次
  56.   HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);  // 配置并启动系统滴答定时器
  57.   /* 系统滴答定时器时钟源 */
  58.   HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
  59.   /* 系统滴答定时器中断优先级配置 */
  60.   HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
  61. }


  62. /**
  63.   * 函数功能: 主函数.
  64.   * 输入参数: 无
  65.   * 返 回 值: 无
  66.   * 说    明: 无
  67.   */
  68. int main(void)
  69. {      
  70.   HAL_StatusTypeDef har_status;
  71.   
  72.   /* 复位所有外设,初始化Flash接口和系统滴答定时器 */
  73.   HAL_Init();
  74.   /* 配置系统时钟 */
  75.   SystemClock_Config();
  76.   
  77.   /* 板载LED初始化 */
  78.   LED_GPIO_Init();
  79.   
  80.   /* DMA初始化 */
  81.   MX_DMA_Init();
  82.   
  83.   har_status=HAL_DMA_Start(&hdma_memtomem_dma1_channel1,(uint32_t)&SRC_Const_Buffer,(uint32_t)&DST_Buffer,32);
  84.   
  85.   if(har_status==HAL_OK)
  86.   {
  87.     /* 检查发送和接收的数据是否相等 */
  88.     TransferStatus = Buffercmp(SRC_Const_Buffer, DST_Buffer, 32);
  89.    
  90.     /* 如果接收和发送的数据都是相同的,则通过 */
  91.     if(TransferStatus == PASSED)
  92.     {
  93.       LED1_ON;
  94.     }
  95.     /* 如果接收和发送的数据不同,则传输出错 */
  96.     else
  97.     {
  98.       LED2_ON;
  99.     }
  100.   }
  101.   else
  102.   {
  103.     LED3_ON;
  104.   }
  105.   /* 无限循环 */
  106.   while (1)
  107.   {

  108.   }
  109. }

  110. /**
  111.   * 函数功能: DMA配置
  112.   * 输入参数: 无
  113.   * 返 回 值: 无
  114.   * 说    明: 无
  115.   */
  116. void MX_DMA_Init(void)
  117. {
  118.   /* 使能DMA控制器时钟 */
  119.   __HAL_RCC_DMA1_CLK_ENABLE();

  120.   /* 配置DMA通道工作方式 */
  121.   hdma_memtomem_dma1_channel1.Instance = DMA1_Channel1;
  122.   hdma_memtomem_dma1_channel1.Init.Direction = DMA_MEMORY_TO_MEMORY;
  123.   hdma_memtomem_dma1_channel1.Init.PeriphInc = DMA_PINC_ENABLE;
  124.   hdma_memtomem_dma1_channel1.Init.MemInc = DMA_MINC_ENABLE;
  125.   hdma_memtomem_dma1_channel1.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
  126.   hdma_memtomem_dma1_channel1.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
  127.   hdma_memtomem_dma1_channel1.Init.Mode = DMA_NORMAL;
  128.   hdma_memtomem_dma1_channel1.Init.Priority = DMA_PRIORITY_HIGH;
  129.   HAL_DMA_Init(&hdma_memtomem_dma1_channel1);

  130. }

  131. /**
  132.   * 函数功能: 判断指定长度的两个数据源是否完全相等
  133.   * 输入参数: 无
  134.   * 返 回 值: 无
  135.   * 说    明: 如果完全相等返回1,只要其中一对数据不相等返回0
  136.   */
  137. TestStatus Buffercmp(const uint32_t* pBuffer, uint32_t* pBuffer1, uint16_t BufferLength)
  138. {
  139.   while(BufferLength--)
  140.   {
  141.     if(*pBuffer != *pBuffer1)
  142.     {
  143.       return FAILED;
  144.     }
  145.    
  146.     pBuffer++;
  147.     pBuffer1++;
  148.   }
  149.   return PASSED;  
  150. }
复制代码



回复

使用道具 举报

16

主题

92

回帖

2

蝴蝶豆

金牌会员

最后登录
2020-12-8
发表于 2016-5-21 14:32:16 | 显示全部楼层
请问楼主,这个功能实际使用在那个方面的?  把flash 里面的数据写到RAM里面?
请轻举一个实际应用例子,可以吗?谢谢.
回复 支持 反对

使用道具 举报

122

主题

129

回帖

0

蝴蝶豆

论坛元老

最后登录
2019-5-28
 楼主| 发表于 2016-5-21 17:18:11 | 显示全部楼层
可以代替memcpy函数,特别是大数组数据转移还是很有用的
memcpy函数或者用循环构建的数据复制过程是占用CPU时间的
使用DMA是可以不用占用CPU时间的
回复 支持 反对

使用道具 举报

18

主题

34

回帖

0

蝴蝶豆

金牌会员

最后登录
2020-9-9
发表于 2019-10-30 15:46:45 | 显示全部楼层
您好,请教下,DMA1 不支持 MEM to MEM 模式吧
回复 支持 反对

使用道具 举报

关于 意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
13245底部标题123相同标题
12底部标题123相同标题
33333底部标题123相同序号
3435底部标题-无链接
关注我们
st-img 微信公众号
st-img 手机版