用户工具

站点工具


icore3l_15

差别

这里会显示出您选择的修订版和当前版本之间的差别。

到此差别页面的链接

两侧同时换到之前的修订记录 前一修订版
后一修订版
前一修订版
icore3l_15 [2020/11/11 10:15]
zgf
icore3l_15 [2020/11/11 10:26] (当前版本)
zgf
行 92: 行 92:
   - DMA_SxNDTR计数器在数据存储结束后递减,该计数器中包含仍需执行的事务数。在产生事件后,外设会向DMA控制器发送请求信号。DMA控制器根据通道优先级处理该请求。只要DMA控制器访问外设,DMA控制器就会向外设发送确认信号。外设获得DMA控制器的确认信号后,便会立即释放其请求。一旦外设使请求失效,DMA控制器就会释放确认信号。如果有更多请求,外设可以启动下一个事务。   - DMA_SxNDTR计数器在数据存储结束后递减,该计数器中包含仍需执行的事务数。在产生事件后,外设会向DMA控制器发送请求信号。DMA控制器根据通道优先级处理该请求。只要DMA控制器访问外设,DMA控制器就会向外设发送确认信号。外设获得DMA控制器的确认信号后,便会立即释放其请求。一旦外设使请求失效,DMA控制器就会释放确认信号。如果有更多请求,外设可以启动下一个事务。
 ==== 四、实验程序 ==== ==== 四、实验程序 ====
 +=== 1.主函数 === 
 +<code c> 
 +//​定义src_buffer数组作为DMA传输数据源  
 +//​const关键字将src_buffer数组变量定义为常量类型  
 +//​表示数据存储在内部的FLASH中 
 +const unsigned long int src_buffer[BUFFER_SIZE] = { 
 +  0x01020304,​0x05060708,​0x090A0B0C,​0x0D0E0F10,​ 
 +  0x11121314,​0x15161718,​0x191A1B1C,​0x1D1E1F20,​ 
 +  0x21222324,​0x25262728,​0x292A2B2C,​0x2D2E2F30,​ 
 +  0x31323334,​0x35363738,​0x393A3B3C,​0x3D3E3F40, ​   
 +  0x41424344,​0x45464748,​0x494A4B4C,​0x4D4E4F50,​ 
 +  0x51525354,​0x55565758,​0x595A5B5C,​0x5D5E5F60,​ 
 +  0x61626364,​0x65666768,​0x696A6B6C,​0x6D6E6F70,​ 
 +  0x71727374,​0x75767778,​0x797A7B7C,​0x7D7E7F80};​ 
 +//​定义DMA传输目标存储器  
 +//​存储在内部的SRAM中 
 +unsigned long int dst_buffer[BUFFER_SIZE] = {0}; 
 +int main(void) 
 +
 +  int i; 
 +  HAL_Init();​ 
 +  SystemClock_Config();​ 
 +  MX_GPIO_Init();​ 
 +  MX_DMA_Init();​ 
 +  HAL_DMA_Start(&​hdma_memtomem_dma2_stream0,​(unsigned long int)src_buffer,​(unsigned long int)dst_buffer,​(unsigned  
 +  long int)BUFFER_SIZE);​ 
 +  while(__HAL_DMA_GET_FLAG(&​hdma_memtomem_dma2_stream0,​DMA_FLAG_TCIF0_4) == SET); 
 +  for(i = 0;i < BUFFER_SIZE;​i++) 
 +  { 
 +     ​if(dst_buffer[i] != src_buffer[i]) ​ //​测试失败 
 +     { 
 +         ​while(1) 
 +
 +           ​HAL_Delay(500);​ 
 +           ​LED_RED_ON;​ 
 +           ​HAL_Delay(500);​ 
 +           ​LED_RED_OFF;​ 
 +         } 
 +     ​} ​  
 +  } 
 +  LED_RED_ON; ​  //​测试成功 
 +  While(1) 
 +  { 
 +  } 
 +
 +</​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灯闪烁。
icore3l_15.1605060921.txt.gz · 最后更改: 2020/11/11 10:15 由 zgf