2017-07-08 102 views
1

我正在使用STM32F103,试图使用DMA从一个阵列复制到另一个阵列。该传输第一次工作,并且DMA1_Channel1_IRQHandler中的一个断点被击中,但随后对DMA_Cmd(DMA1_Channel1, ENABLE)的调用不起作用且断点未被命中。错误标志DMA1_FLAG_TE1未设置。是否还有其他需要设置/重置的转移以便第二次运行?STM32 DMA内存到内存的传输只触发一次

#include "stm32f10x.h" 

#define ARRAYSIZE 800 
volatile uint32_t status = 0; 
volatile uint32_t i; 


int main(void) 
{ 
    uint32_t source[ARRAYSIZE]; 
    uint32_t destination[ARRAYSIZE]; 
    for (i=0; i<ARRAYSIZE;i++) 
     source[i]=i; 

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); 

    DMA_InitTypeDef DMA_InitStructure; 
    DMA_DeInit(DMA1_Channel1); 

    DMA_InitStructure.DMA_M2M = DMA_M2M_Enable; 
    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; 
    DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; 
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; 
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; 
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; 
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable; 
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; 
    DMA_InitStructure.DMA_BufferSize = ARRAYSIZE; 
    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)source; 
    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)destination; 

    DMA_Init(DMA1_Channel1, &DMA_InitStructure); 
    DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE); 

    NVIC_InitTypeDef NVIC_InitStructure; 
    NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn; 
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; 
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; 
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 
    NVIC_Init(&NVIC_InitStructure); 

    status = 1; 

    while (1) 
     { 
     if(status == 1) 
     { 
      status = 0; 

      DMA1_Channel1->CNDTR = ARRAYSIZE; 
      DMA1_Channel1->CPAR = (uint32_t)source; 
      DMA1_Channel1->CMAR = (uint32_t)destination; 
      DMA_ClearFlag(DMA1_FLAG_GL1); 
      DMA_ClearFlag(DMA1_FLAG_TC1); 

      DMA_Cmd(DMA1_Channel1, DISABLE); 
      DMA_Cmd(DMA1_Channel1, ENABLE); 
     } 
     } 
} 

void DMA1_Channel1_IRQHandler(void) 
{ 
    if(DMA_GetITStatus(DMA1_IT_TC1)) 
    { 
    status=1; 
    DMA_ClearITPendingBit(DMA1_IT_GL1); 
    } 
} 
+0

如果在block中将状态设置为0,则程序不会第二次进入。你想持续,循环的DMA传输还是自己开始? – rkrahl

+0

我还没有注意到在isr中的状态设置,以前的评论的第一部分不再相关。 – rkrahl

回答

1

在设置寄存器之前禁用DMA,然后启用它。根据RM0008(第289页),DMA_CNDTRx只能在通道禁用时写入。 DMA_CMARx也是如此。

+1

将'DMA_Cmd(DMA1_Channel1,DISABLE);'移动到设置寄存器之前解决了问题,DMA事务按预期持续运行。 – Batperson