这里会显示出您选择的修订版和当前版本之间的差别。
两侧同时换到之前的修订记录 前一修订版 后一修订版 | 前一修订版 | ||
icore3l_15 [2020/11/11 10:19] zgf |
icore3l_15 [2020/11/11 10:26] (当前版本) zgf |
||
---|---|---|---|
行 116: | 行 116: | ||
MX_GPIO_Init(); | MX_GPIO_Init(); | ||
MX_DMA_Init(); | MX_DMA_Init(); | ||
- | HAL_DMA_Start(&hdma_memtomem_dma2_stream0,(unsigned long int)src_buffer,(unsigned long int)dst_buffer, | + | HAL_DMA_Start(&hdma_memtomem_dma2_stream0,(unsigned long int)src_buffer,(unsigned long int)dst_buffer,(unsigned |
- | (unsigned long int)BUFFER_SIZE); | + | long int)BUFFER_SIZE); |
while(__HAL_DMA_GET_FLAG(&hdma_memtomem_dma2_stream0,DMA_FLAG_TCIF0_4) == SET); | while(__HAL_DMA_GET_FLAG(&hdma_memtomem_dma2_stream0,DMA_FLAG_TCIF0_4) == SET); | ||
for(i = 0;i < BUFFER_SIZE;i++) | for(i = 0;i < BUFFER_SIZE;i++) | ||
{ | { | ||
if(dst_buffer[i] != src_buffer[i]) //测试失败 | if(dst_buffer[i] != src_buffer[i]) //测试失败 | ||
- | { | + | { |
while(1) | while(1) | ||
- | { | + | { |
HAL_Delay(500); | HAL_Delay(500); | ||
LED_RED_ON; | LED_RED_ON; | ||
HAL_Delay(500); | HAL_Delay(500); | ||
LED_RED_OFF; | LED_RED_OFF; | ||
- | } | + | } |
} | } | ||
} | } | ||
行 138: | 行 138: | ||
} | } | ||
</code> | </code> | ||
+ | === 2.DMA初始化函数 === | ||
+ | <code c> | ||
+ | void MX_DMA_Init(void) | ||
+ | { | ||
+ | //使能DMA控制器时钟 | ||
+ | __HAL_RCC_DMA2_CLK_ENABLE(); //配置DMA工作方式 | ||
+ | hdma_memtomem_dma2_stream0.Instance = DMA2_Stream0; | ||
+ | hdma_memtomem_dma2_stream0.Init.Request = DMA_REQUEST_MEM2MEM; | ||
+ | hdma_memtomem_dma2_stream0.Init.Direction = DMA_MEMORY_TO_MEMORY;//方向为存储器到存储器 | ||
+ | hdma_memtomem_dma2_stream0.Init.PeriphInc = DMA_PINC_ENABLE; | ||
+ | hdma_memtomem_dma2_stream0.Init.MemInc = DMA_MINC_ENABLE; | ||
+ | hdma_memtomem_dma2_stream0.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD; //外设数据宽度 | ||
+ | hdma_memtomem_dma2_stream0.Init.MemDataAlignment = DMA_MDATAALIGN_WORD; //存储器数据宽度 | ||
+ | hdma_memtomem_dma2_stream0.Init.Mode = DMA_NORMAL; | ||
+ | hdma_memtomem_dma2_stream0.Init.Priority = DMA_PRIORITY_HIGH; //优先级别为高 | ||
+ | hdma_memtomem_dma2_stream0.Init.FIFOMode = DMA_FIFOMODE_ENABLE; | ||
+ | hdma_memtomem_dma2_stream0.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL; | ||
+ | hdma_memtomem_dma2_stream0.Init.MemBurst = DMA_MBURST_SINGLE; //存储器突发单次传输 | ||
+ | hdma_memtomem_dma2_stream0.Init.PeriphBurst = DMA_PBURST_SINGLE; //外设突发单次传输 | ||
+ | if (HAL_DMA_Init(&hdma_memtomem_dma2_stream0) != HAL_OK) | ||
+ | { | ||
+ | Error_Handler(); | ||
+ | } | ||
+ | //DMA2中断配置 | ||
+ | HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 0, 0); | ||
+ | HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn); | ||
+ | } | ||
+ | </code> | ||
+ | === 3.DMA寄存器结构体 === | ||
+ | DMA相关的寄存器是通过HAL库中的结构体DMA_TypeDef 和DMA_Stream_TypeDef定义的 | ||
+ | <code c> | ||
+ | typedef struct | ||
+ | { | ||
+ | __IO uint32_t CR; /* DMA stream x 配置寄存器 */ | ||
+ | __IO uint32_t NDTR; /* DMA stream x 数据寄存器数 */ | ||
+ | __IO uint32_t PAR; /* DMA stream x 外设地址寄存器 */ | ||
+ | __IO uint32_t M0AR; /* DMA stream x 存储器0地址寄存器 */ | ||
+ | __IO uint32_t M1AR; /* DMA stream x 存储器1地址寄存器 */ | ||
+ | __IO uint32_t FCR; /* DMA stream x FIFO控制寄存器 */ | ||
+ | } | ||
+ | DMA_Stream_TypeDef; | ||
+ | typedef struct | ||
+ | { | ||
+ | __IO uint32_t LISR; /* DMA低中断状态寄存器,地址偏移量:0x00 */ | ||
+ | __IO uint32_t HISR; /* DMA高中断状态寄存器,地址偏移量:0x04 */ | ||
+ | __IO uint32_t LIFCR; /* DMA低中断标志清除寄存器,地址偏移量:0x08 */ | ||
+ | __IO uint32_t HIFCR; /* DMA高中断标志清除寄存器,地址偏移量:0x0C */ | ||
+ | } | ||
+ | DMA_TypeDef; | ||
+ | </code> | ||
+ | === 4.DMA句柄结构体DMA_HandleTypeDef === | ||
+ | HAL库在DMA_TypeDef的基础上封装了一个结构体DMA_HandleTypeDef,定义如下: | ||
+ | <code c> | ||
+ | typedef struct __DMA_HandleTypeDef | ||
+ | { | ||
+ | void *Instance; /* 注册基地址 */ | ||
+ | DMA_InitTypeDef Init; /* DMA通讯参数 */ | ||
+ | HAL_LockTypeDef Lock; /* DMA锁定对象 */ | ||
+ | __IO HAL_DMA_StateTypeDef State; /* DMA传输状态 */ | ||
+ | void *Parent; /* 父对象状态 */ | ||
+ | void (* XferCpltCallback)( struct __DMA_HandleTypeDef * hdma); | ||
+ | /* DMA传输完成回调 */ | ||
+ | void (* XferHalfCpltCallback)( struct __DMA_HandleTypeDef * hdma); | ||
+ | /* DMA半传输完成回调 */ | ||
+ | void (* XferM1CpltCallback)( struct __DMA_HandleTypeDef * hdma); | ||
+ | /* DMA传输完成Memory1回调 */ | ||
+ | void (* XferM1HalfCpltCallback)( struct __DMA_HandleTypeDef * hdma); | ||
+ | /* DMA传输半完成Memory1回调 */ | ||
+ | void (* XferErrorCallback)( struct __DMA_HandleTypeDef * hdma); | ||
+ | /* DMA传输错误回调 */ | ||
+ | void (* XferAbortCallback)( struct __DMA_HandleTypeDef * hdma); | ||
+ | /* DMA传输中止回调 */ | ||
+ | __IO uint32_t ErrorCode; /* DMA错误代码 */ | ||
+ | uint32_t StreamBaseAddress; /* DMA流基址 */ | ||
+ | uint32_t StreamIndex; /* DMA流索引 */ | ||
+ | DMAMUX_Channel_TypeDef *DMAmuxChannel; /* DMAMUX通道基地址 */ | ||
+ | DMAMUX_ChannelStatus_TypeDef *DMAmuxChannelStatus; | ||
+ | /* DMAMUX通道状态基地址 */ | ||
+ | uint32_t DMAmuxChannelStatusMask; /* DMAMUX通道状态掩码 */ | ||
+ | DMAMUX_RequestGen_TypeDef *DMAmuxRequestGen; /* DMAMUX请求生成器基地址 */ | ||
+ | DMAMUX_RequestGenStatus_TypeDef *DMAmuxRequestGenStatus; | ||
+ | /* DMAMUX请求生成器状态地址 */ | ||
+ | uint32_t DMAmuxRequestGenStatusMask; /* DMAMUX请求生成器状态掩码 */ | ||
+ | }DMA_HandleTypeDef; | ||
+ | </code> | ||
+ | ==== 五、实验步骤 ==== | ||
+ | - 把仿真器与iCore3L的SWD调试口相连(直接相连或者通过转接器相连); | ||
+ | - 把iCore3L通过Micro USB线与计算机相连,为iCore3L供电; | ||
+ | - 打开Keil MDK 开发环境,并打开本实验工程; | ||
+ | - 烧写程序到iCore3L上; | ||
+ | - 也可以进入Debug 模式,单步运行或设置断点验证程序逻辑。 | ||
+ | ==== 六、实验现象 ==== | ||
+ | 实验成功红色LED灯常亮,实验失败红色LED灯闪烁。 |