2017-07-08 50 views
1

STM32F103を使用して、DMAを使用してあるアレイから別のアレイにコピーしようとしています。転送は初めて実行され、DMA1_Channel1_IRQHandlerのブレークポイントがヒットしますが、その後のDMA_Cmd(DMA1_Channel1, ENABLE)の呼び出しは無効であり、ブレークポイントはヒットしません。エラーフラグDMA1_FLAG_TE1が設定されていません。 2回目の転送のために転送を設定/リセットする必要のある追加のものがありますか?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

ブロックすると、プログラムは2度目に入力されません。ステータスを0に設定しています。あなたは、連続的な循環DMA転送をしたいのですか、それとも自分で開始するのですか? – rkrahl

+0

私はisrのステータスの設定に気づいていませんが、前のコメントの最初の部分はもはや関連しません。 – rkrahl

答えて

1

DMAを無効にしてから、有効にしてから有効にしてください。 RM0008(287ページ)によると、DMA_CNDTRxは、チャネルが無効になっているときにのみ書き込むことができます。 DMA_CMARxについても同様です。

+1

レジスタを設定する前に 'DMA_Cmd(DMA1_Channel1、DISABLE); 'を行に移動すると、DMAトランザクションは意図どおりに連続して実行されます。 – Batperson

関連する問題