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)は、周辺機器とメモリ、メモリ、メモリとメモリとの間の高速データ転送を提供するために使用される.データは、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;//
}
}
実行結果: