stm 32 f 407のDMA(操作レジスタ)

5875 ワード

八、DMA
       ダイレクトメモリアクセス(DMA)は、周辺機器とメモリ、メモリ、メモリとメモリとの間の高速データ転送を提供するために使用される.データは、CPUの干渉なしにDMAによって伝送されてもよい.これにより、CPUリソースが他の動作により重くなる.
       DMAコントローラは複雑なバスマトリックスアーキテクチャに基づいて、強力なデュアルAHBメインバスアーキテクチャと独立したFIFOを組み合わせて、システム帯域幅を最適化する.
        2つのDMAコントローラには16個のデータストリーム(stream)があり、各データストリームは所定のチャネルの1つと組み合わせることができる.
 
DMAの動作モード
1.  シングルトランスポート
2. マルチトランスポート(burst):データをマルチトランスポートに分割する
 
 
DMAの動作モード
 
1. ≪ループ・モード|Loop Mode|oem_src≫:ループ・モードは、ADCスキャン・モードなどのループ・バッファおよび連続データ・ストリームの処理に使用できます.DMA_を設定するには、この機能を有効にします.SxCRレジスタのCIRCビットが有効になります.
 
ループモードではburst方式では、次のルールに従う必要があります.
DMA_SxNDTR等しい(Mburst beat)× (Msize)/(Psize))の整数倍です.
 
2.     デュアルバッファモード:デュアルバッファモードDMAに設定SxCRレジスタのDBMビットが有効です.
デュアルバッファモードとシングルバッファモードの違いは、2つのアドレスがあり、ボルトバッファモードが使用可能になると、サイクルモードが自動的に使用可能になり、転送が完了するたびにメモリアドレスが交換されます.一方のメモリ領域がDMAコントローラによって使用される場合、他方はプログラムによって使用される.
 
メモリアドレスを変更する必要がある場合は、次のルールに従います.
DMA_SxCRレジスタのCTビットが0の場合、DMA_SxM 1 ARレジスタは変更可能
DMA_SxCRレジスタのCTビットが1の場合、DMA_SxM 0 ARレジスタは変更可能
 
 
    設定手順:
1.     時計を相関させる.
2.     データストリームが有効になっている場合は、DMA_にリセットします.SxCRレジスタのENビットを無効にし、ビットを読み出して、継続的なデータストリーム動作があるかどうかを確認します.このビットライト0は、実際にはすべての転送が完了したときに消去されるため、すぐには有効になりません.ENビットが0と読むと、これはデータストリームが準備されていることを意味し、構成することができる.したがって、任意のデータストリーム構成の前に、ENビットがクリアされるのを待つ必要がある.データストリームが再起動される前に、前回DMA伝送中の状態レジスタ(DMA_LISR and DMA_HISR)の全てのデータストリーム専用ビットはクリアされるべきである.
3.      DMAでSxPARレジスタには、周辺ポートレジスタのアドレスが設定されている.
4.     DMAでSxMA 0 Rレジスタにメモリのアドレスを設定します(デュアルバッファモードの場合、DMA_SxMA 1 Rレジスタにメモリのアドレスを設定する必要もあります).
5.     DMAでSxNDTRレジスタには、送信されたデータの総数が設定され、各周辺機器のイベントまたはburst送信のたびに、この値は減少します.
6.      DMAでSxCRレジスタはCHSEL[2:0]を使用してDMAチャネルを選択する.
7.      外部設定がトラフィックコントローラの場合、この機能をサポートし、DMA_を設定します.SxCRレジスタにおけるPFCTRLのビット.
8.      DMAでSxCRレジスタのPL[1:0]ビット構成データストリーム優先度.
9.     FIFO(有効または無効、送受信のバルブ値)を設定します.
10.  DMAでSxCRレジスタには、データ転送の方向、周辺機器とメモリの増分/固定モード、単一またはburst転送、周辺機器とメモリのデータ幅、ループモード、デュアルバッファモード、および完了数分の数後に中断するように構成されています.
11.   DMA_での設定データストリームのアクティブ化SxCRレジスタのENビット.
12.  周辺レジスタのDMAモードビットを関連付け、転送を開始する.
 
 
プログラム:
/*********************************************
      :  DMA   
        :IAR for ARM6.21
        :stm32f4-discovery
      :168M
    
      :         ,        
          USART3    ,   DMA
    author:  
    data:2012-02-03
**********************************************/

#include  

u8 USART_DMA_Completed;
u8 Rx_Completed;
u8 Rx_data_counter;
u8 usart3_buffer[100];

void USART3_DMA_config(void);
void USART3_config(void);

void main ()
{ 
  
  SCB->AIRCR = 0x05FA0000 | 0x400;  //          :  =3:1
  
  RCC->AHB1ENR |= ( (1<<3) | (1<<21) ); //  GPIOD  ,  DMA1  
  RCC->APB1ENR |= (1<<18);  //  usart3  
  
  USART3_DMA_config();
  USART3_config();
  
  USART_DMA_Completed = 1;
  
  while(1)
  {  
    if(USART_DMA_Completed & Rx_Completed)  //          ,       
    {  
      DMA1_Stream3->CR &= 0xFFFFFFFE; //  DMA1_Stream3
      while(DMA1_Stream3->CR & 0x00000001);//  DMA          
      DMA1->LIFCR |= 0x0f800000;//     DMA1_Stream3            
      DMA1_Stream3->NDTR = Rx_data_counter; //  dma       
      if((USART3->SR & (1<<7))) //        
      {
        USART3->CR3 &= ~(1<<7);//  usartdma  
        USART_DMA_Completed = 0;
        DMA1_Stream3->NDTR = Rx_data_counter; //  dma       
        DMA1_Stream3->CR |= 1;//  dma
        USART3->CR3 |= (1<<7);//  usartdma  
        Rx_Completed = 0;
        Rx_data_counter = 0;
      }
    }
  }
}

/****************************************
     :USART3_DMA_config
    : 
     : 
    :DMA1   3 usart3       
****************************************/
void USART3_DMA_config(void)
{
  DMA1_Stream3->CR &= 0xFFFFFFFE; //  DMA1_Stream3
  while(DMA1_Stream3->CR & 0x00000001);//  DMA     
  
  DMA1->LIFCR |= 0x0f800000;//     DMA1_Stream3      
  
  DMA1_Stream3->PAR = (uint32_t)&USART3->DR;//      USART3->DR  0x40004804
  DMA1_Stream3->M0AR = (uint32_t)usart3_buffer; //      
  DMA1_Stream3->NDTR = Rx_data_counter; //  dma       
  //DMA1_Stream3->FCR |= 0x00000007;//  fifo
  /*
      dma  4, usart3tx
       Medium
             
          
            
  */
  DMA1_Stream3->CR |= ( 0x08000000 |0x00010000 | (1<<6)
                        | (1<<10) | (1<<4) ); 

  USART3->CR3 &= ~(1<<7);//usart3 dma      
  
  NVIC->IP[14] = 0xA0;
  NVIC->ISER[0] |= (1<<14);
  
}

/**************************
     :USART3_config
    : 
     : 
    :  usart3
************************/
void USART3_config(void)
{
  USART3->BRR = 0x0000016C;   //   115200
  /*
     usart3
  usart3    
  usart3    
             
  8bit
       
     
  */
  USART3->CR1 |= (( 1<<13 ) | ( 1<<3 ) | ( 1<<2 ) | ( 1<<5 )); 
  
  GPIOD->AFR[1] |= 0x00000077;//  PD8,9     
  
  GPIOD->MODER &= 0xFFF0FFFF; //  PD8,9,    
  GPIOD->MODER |= 0x000A0000; 
  
//  GPIOD->OTYPER &= 0xFFFFDFFF; //  PD9    
  
  GPIOD->OSPEEDR &= 0xFFFCFFFF; //PD8  50m
  GPIOD->OSPEEDR |= 0x00020000;
  
  GPIOD->PUPDR &= 0xFFFCFFFF; //PD8
  GPIOD->PUPDR |= 0x00010000;
  
  NVIC->IP[39] = 0xf0; //       ,       1111
  NVIC->ISER[1] |= (1<SR & (1<<5)) //         
  {
    usart3_buffer[Rx_data_counter] = USART3->DR;
    Rx_data_counter++;
    if(usart3_buffer[Rx_data_counter - 1] == '\r')
    {
      USART3->CR1 &= ~(1<<5); //      
      Rx_Completed = 1;
    }
   } 
}

void DMA1_Stream3_IRQHandler(void)
{
  if(DMA1->LISR & 0x08000000)//DMA    
  {
    USART_DMA_Completed = 1;
    USART3->CR1 |= 1<<5;  //  usart3    
    DMA1->LIFCR |= 0x08000000;//      
  }
}

実行結果: