2017-07-08 103 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