close

7

大量資料的快速搬移─DMA

 

7.1 STM32 DMA簡介

DMA,又稱Direct Memory Access。主要功能為對記憶體坐直接存取的動作而不用透過CPU,透過硬體使得記憶體與I/O設備建立一條直接傳送資料的通道,藉此使CPU的效率大為提高。

使用DMA,對CPU而言有兩個很大的好處:

  1. 1.          使用DMA,能使CPU的使用效率提升。
  2. 2.          使用DMA操作記憶體,比使用CPU操作記憶體還要快速。

STM32最多有兩個DMA的控制器,(DMA2僅存在於大容量的產品當中)DMA17個通道,每個通道專門用來管理來自於一個或多個外部設備的請求。此外還有一個仲裁器來協調各個DMA請求的優先權。

STM32DMA有以下的特性:

  1. 每個通道都直接連接到DMA,每個通道都支援軟體觸發,這些功能透過軟體來設定。
  2. 在七個請求通知的優先權,須通過軟體進行設定,一共有四級,假如在相等優先權時,則由硬體決定優先權。
  3. 可獨立設置來源位置與目的位置的資料傳輸寬度(8bits、16bits、32bits),兩邊的資料寬度必須相等。
  4. 支援Circular buffer
  5. 每個通道都有三個旗標(DMA半傳輸、DMA傳輸完成、DMA傳輸錯誤)。
  6. 支援記憶體對記憶體的傳輸
  7. 支援外部設備對記憶體與記憶體對外部設備的傳輸
  8. FLASH、SRAM、外部SRAM、APB1APB2和AHB均可當作DMA操作的來源位置或目的位置。
  9. 可傳輸的最大數目為65535。

SIOC(STM32F103C8T6)只有一個DMA控制器,DMA1,下面我們就針對DMA1進行介紹。

從外部周邊(TIMxADCSPIxI2CxUSARTx)產生的DMA請求,須通過OR邏輯閘輸入至DMA控制器,這表示同時只能有一個外部請求可被執行。

DMA1通道一覽表與DMA Request Mapping

外部

通道1

通道2

通道3

通道4

通道5

通道6

通道7

ADC

ADC1

 

 

 

 

 

 

SPI

 

SPI1_RX

SPI1_TX

SPI2_RX

SPI2_TX

 

 

USART

 

USART3_TX

USART3_RX

USART1_TX

USART1_RX

USART2_RX

USART2_TX

I2C

 

 

 

I2C2_TX

I2C2_RX

I2C1_TX

I2C1_RX

TIM1

 

TIM1_CH1

TIM1_CH2

TIM1_TX4

TIM1_TRIG

TIM1_COM

TIM1_UP

TIM1_CH3

 

TIM2

TIM2_CH3

TIM2_UP

 

 

TIM2_CH1

 

TIM2_CH2

TIM2_CH4

TIM3

 

TIM3_CH3

TIM3_CH4

TIM3_UP

 

 

TIM3_CH1

TIM3_TRIG

 

TIM4

TIM4_CH1

 

 

TIM4_CH2

TIM4_CH3

 

TIM4_UP

 

image001  

7.2  DMA Registers

本章節將逐一介紹在使用DMA時,會使用到的暫存器

Register

Description

ISR

紀錄DMA 中斷狀態的暫存器

IFCR

計錄DMA 清除中斷的暫存器

CCRx

紀錄DMA Channelx 設定的暫存器

CNDTRx

紀錄DMA Channelx待傳輸資料筆數的暫存器

CPARx

儲存DMA Channelx 周邊記憶體位置的暫存器

CMARx

儲存DMA Channelx 主記憶體位置的暫存器

 

image002  

image003  

image004  

image005  

image006  

image007  

 

DMA Register Mapping

image008  

image009  

 

image010  

image011  

 

7.3  DMA Standard Driver Library

本章節將介紹使用者在撰寫程式時,會使用到的函式。

 

Function name

Description

DMA_DeInit

 

DMA_Init

初始 DMAy Channelx

DMA_StructInit

填入 DMA_InitStruct 參數

DMA_Cmd

Enables or disables the specified DMAy Channelx.

DMA_ITConfig

Enables or disables the specified DMAy Channelx interrupts.

DMA_GetCurrDataCounter

回傳 DMAy當下的剩餘資料個數

DMA_ClearFlag

清除 DMAy Channelx pending flags.

DMA_GetITStatus

確認 DMAy Channelx的中斷旗標有沒有被觸發

DMA_ClearITPendingBit

清除 DMAy Channelx interrupt pending bits.

 

 

 

DMA_DeInit function

 

Function name

DMA_DeInit

Function prototype

void DMA_DeInit(DMA_Channel_TypeDef* DMAy_Channelx)

Behavior description

Resets the DMAy Channelx registers to their default reset values.

Input parameter

DMAy_Channelx: where y selects the DMA (y = 1 for DMA1, y = 2 for DMA2) and x selects the DMA Channel (x = 1 to 7 for DMA1 or x = 1 to5 for DMA2).

Output parameter

None

Return parameter

None

Required preconditions

None

Called functions

RCC_AHBPeriphClockCmd().

 

Example:

 

/* Deinitialize the DMA1 Channel2 */

 

DMA_DeInit(DMA1_Channel2);

 

 

 

DMA_Init function

 

Function name

DMA_Init

Function prototype

void DMA_Init(DMA_Channel_TypeDef* DMAy_Channelx,DMA_InitTypeDef* DMA_InitStruct)

Behavior description

Initializes the DMAy Channelx according to the parameters specified in the DMA_InitStruct.

Function name

DMA_Init

Input parameter1

DMAy_Channelx: where y selects the DMA (y = 1 for DMA1, y = 2 for DMA2) and x selects the DMA Channel (x = 1 to 7 for DMA1 or x = 1 to 5 for DMA2).

Input parameter2

DMA_InitStruct: pointer to a DMA_InitTypeDef structure that contains the configuration information for the specified DMAy Channelx. Refer to DMA_InitTypeDef structure for more details on the allowed values for this parameter.

Output parameter

None

Return parameter

None

Required preconditions

None

Required preconditions

None

 

DMA_InitTypeDef structure

 

The DMA_InitTypeDef structure is defined in the stm32f10x_dma.h file:

 

typedef struct

 

{

 

u32 DMA_PeripheralBaseAddr;

 

u32 DMA_MemoryBaseAddr;

 

u32 DMA_DIR;

 

u32 DMA_BufferSize;

 

u32 DMA_PeripheralInc;

 

u32 DMA_MemoryInc;

 

u32 DMA_PeripheralDataSize;

 

u32 DMA_MemoryDataSize;

 

u32 DMA_Mode;

 

u32 DMA_Priority;

 

u32 DMA_M2M;

 

} DMA_InitTypeDef;

 

DMA_PeripheralBaseAddr

 

紀錄DMA周邊記憶體起始位置。

 

DMA_MemoryBaseAddr

 

紀錄DMA主記憶體起始位置。

 

DMA_DIR

 

設定DMA要將周邊記憶體視為來源端或是目的端。

 

DMA_DIR

Description

DMA_DIR_PeripheralDST

將周邊視為目的端

DMA_DIR_PeripheralSRC

將周邊視為來源端

 

DMA_BufferSize

 

此欄位定義DMA傳送的buffer大小,此大小必須想等於DMA_PeripheralDataSizeDMA_MemoryDataSize

 

DMA_PeripheralInc

 

此欄位將設定DMA操作周邊時,是否要啟用累加器。

 

DMA_PeripheralInc

Description

DMA_PeripheralInc_Enable

Current peripheral register incremented

DMA_PeripheralInc_Disable

Current peripheral register unchanged

 

DMA_MemoryInc

 

此欄位將設定DMA操作主記憶體時,是否要啟用累加器。

 

DMA_MemoryInc

Description

DMA_MemoryInc_Enable

Current memory register incremented

DMA_MemoryInc_Disable

Current memory register unchanged

 

DMA_PeripheralDataSize

 

此欄位設定來自周邊的資料寬度。

 

DMA_PeripheralDataSize

Description

DMA_PeripheralDataSize_Byte

Data width = 8bits

DMA_PeripheralDataSize_HalfWord

Data width = 16bits

DMA_PeripheralDataSize_Word

Data width = 32bits

 

DMA_MemoryDataSize

 

此欄位設定來自主記憶體的資料寬度。

 

DMA_MemoryDataSize

Description

DMA_MemoryDataSize_Byte

Data width = 8bits

DMA_MemoryDataSize_HalfWord

Data width = 16bits

DMA_MemoryDataSize_Word

Data width = 32bits

 

DMA_Mode

 

此欄位設定DMA的運作模式。

 

DMA_Mode

Description

DMA_Mode_Circular

Circular buffer mode is used

DMA_Mode_Normal

Normal buffer mode is used

 

DMA_Mode_Circular模式下,不能使用memory-to-memory轉移。

 

DMA_Priority

 

此欄位設定軟體的優先權。

 

DMA_Priority

Description

DMA_Priority_VeryHigh

DMAy Channelx has a very high priority

DMA_Priority_High

DMAy Channelx has a high priority

DMA_Priority_Medium

DMAy Channelx has a medium priority

DMA_Priority_Low

DMAy Channelx has a low priority

 

DMA_M2M

 

此欄位設定memory-to-memory轉移是否要被啟用。

 

DMA_M2M

Description

DMA_M2M_Enable

DMAy Channelx configured for memory-to-memory transfer

DMA_M2M_Enable

DMAy Channelx not configured for memory-to memory transfer

 

Example:

 

/* Initialize the DMA1 Channel1 according to the DMA_InitStructure members */

 

DMA_InitTypeDef DMA_InitStructure;

 

DMA_InitStructure.DMA_PeripheralBaseAddr = 0x40005400;

 

DMA_InitStructure.DMA_MemoryBaseAddr = 0x20000100;

 

DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;

 

DMA_InitStructure.DMA_BufferSize = 256;

 

DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

 

DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;

 

DMA_InitStructure.DMA_PeripheralDataSize =

 

DMA_PeripheralDataSize_HalfWord;

 

DMA_InitStructure.DMA_MemoryDataSize =

 

DMA_MemoryDataSize_HalfWord;

 

DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;

 

DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;

 

DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;

 

DMA_Init(DMA1_Channel1, &DMA_InitStructure);

 

 

 

DMA_StructInit function

 

Function name

DMA_StructInit

Function prototype

Void DMA_StructInit(DMA_InitTypeDef* DMA_InitStruct)

Behavior description

Fills each DMA_InitStruct member with its default value.

Input parameter

DMA_InitStruct: pointer to the DMA_InitTypeDef structure to be initialized

Output parameter

None

Return parameter

None

Required preconditions

None

Called functions

None

 

DMA_initStruct default values

 

Member

Default value

DMA_PeripheralBaseAddr

0

DMA_MemoryBaseAddr

0

DMA_DIR

DMA_DIR_PeripheralSRC

DMA_BufferSize

0

DMA_PeripheralInc

DMA_PeripheralInc_Disable

DMA_MemoryInc

DMA_MemoryInc_Disable

DMA_PeripheralDataSize

DMA_PeripheralDataSize_Byte

DMA_MemoryDataSize

DMA_MemoryDataSize_Byte

DMA_Mode

DMA_Mode_Normal

DMA_Priority

DMA_Priority_Low

DMA_M2M

DMA_M2M_Disable

 

 

 

Example:

 

/* Initialize a DMA_InitTypeDef structure */

 

DMA_InitTypeDef DMA_InitStructure;

 

DMA_StructInit(&DMA_InitStructure);

 

DMA_Cmd function

 

Function name

DMA_Cmd

Function prototype

void DMA_Cmd(DMA_Channel_TypeDef* DMAy_Channelx,FunctionalState NewState)

Behavior description

Enables or disables the specified DMAy Channelx.

Input parameter1

DMAy_Channelx: where y selects the DMA (y = 1 for DMA1, y = 2 for DMA2) and x selects the DMA Channel (x = 1 to 7 for DMA1 or x = 1 to 5 for DMA2).

Input parameter2

NewState: new state of the DMAy Channelx. This parameter can be: ENABLE or DISABLE

Output parameter

None

Return parameter

None

Required preconditions

None

Called functions

None

 

Example:

 

/* Enable DMA1 Channel7 */

 

DMA_Cmd(DMA1_Channel7, ENABLE);

 

 

 

DMA_ITConfig function

 

Function name

DMA_ITConfig

Function prototype

void DMA_ITConfig(DMA_Channel_TypeDef* DMAy_Channelx, u32 DMA_IT, FunctionalState NewState)

Behavior description

Enables or disables the specified DMAy Channelx interrupts.

Input parameter1

DMAy_Channelx: where y selects the DMA (y = 1 for DMA1, y = 2 for DMA2) and x selects the DMA Channel (x = 1 to 7 for DMA1 or x = 1 to 5 for DMA2).

Input parameter2

DMA_IT: specifies the DMAy Channelx interrupt sources to be enabled or disabled. More than one interrupt can be selected using the “|” operator.Refer to DMA_IT for more details on the allowed values for this parameter.

Input parameter3

NewState: new state of the specified DMAy Channelx interrupts.This parameter can be: ENABLE or DISABLE.

Output parameter

None

Return parameter

None

Required preconditions

None

Called functions

None

 

DMA_IT

 

此函數用來設置DMA的三個中斷

 

DMA_IT

Description

DMA_IT_TC

Transfer complete interrupt mask

DMA_IT_HT

Half transfer interrupt mask

DMA_IT_TE

Transfer error interrupt mask

 

Example:

 

/* Enable DMA1 Channel5 complete transfer interrupt */

 

DMA_ITConfig(DMA1_Channel5, DMA_IT_TC, ENABLE);

 

 

 

DMA_GetCurrDataCounter function

 

Function name

DMA_GetCurrDataCounter

Function prototype

u16 DMA_GetCurrDataCounter(DMA_Channel_TypeDef* DMAy_Channelx)

Behavior description

Returns the number of remaining data units in the current DMAy Channelx transfer.

Input parameter

DMAy_Channelx: where y selects the DMA (y = 1 for DMA1, y = 2 for DMA2) and x selects the DMA Channel (x = 1 to 7 for DMA1 or x = 1 to 5 for DMA2).

Output parameter

None

Return parameter

The number of remaining data units in the current DMAy Channelx transfer.

Required preconditions

None

Called functions

None

 

Example:

 

/* Get the number of remaining data units in the current DMA1 Channel2 transfer */

 

u16 CurrDataCount;

 

CurrDataCount = DMA_GetCurrDataCounter(DMA1_Channel2);

 

 

 

DMA_GetFlagStatus function

 

 

 

Function name

DMA_GetFlagStatus

Function prototype

FlagStatus DMA_GetFlagStatus(u32 DMA_FLAG)

Behavior description

Checks whether the specified DMAy Channelx flag is set or not.

Input parameter

DMA_FLAG: specifies the flag to check.Refer to DMA_FLAG for more details on the allowed values for this parameter.

Output parameter

None

Return parameter

New state of DMA_FLAG (SET or RESET).

Required preconditions

None

Called functions

None

 

DMA_FLAG

 

DMA_FLAG

Description

DMA1_FLAG_GL1

DMA1 Channel1 global flag

DMA1_FLAG_TC1

DMA1 Channel1 transfer complete flag

DMA1_FLAG_HT1

DMA1 Channel1 half transfer flag

DMA1_FLAG_TE1

DMA1 Channel1 transfer error flag

DMA1_FLAG_GL2

DMA1 Channel2 global flag

DMA1_FLAG_TC2

DMA1 Channel2 transfer complete flag

DMA1_FLAG_HT2

DMA1 Channel2 half transfer flag

DMA1_FLAG_TE2

DMA1 Channel2 transfer error flag

DMA1_FLAG_GL3

DMA1 Channel3 global flag

DMA1_FLAG_TC3

DMA1 Channel3 transfer complete flag

DMA1_FLAG_HT3

DMA1 Channel3 half transfer flag

DMA1_FLAG_TE3

DMA1 Channel3 transfer error flag

DMA1_FLAG_GL4

DMA1 Channel4 global flag

DMA1_FLAG_TC4

DMA1 Channel4 transfer complete flag

DMA1_FLAG_HT4

DMA1 Channel4 half transfer flag

DMA1_FLAG_TE4

DMA1 Channel4 transfer error flag

DMA1_FLAG_GL5

DMA1 Channel5 global flag

DMA1_FLAG_TC5

DMA1 Channel5 transfer complete flag

DMA1_FLAG_HT5

DMA1 Channel5 half transfer flag

DMA1_FLAG_TE5

DMA1 Channel5 transfer error flag

DMA1_FLAG_GL6

DMA1 Channel6 global flag

DMA1_FLAG_TC6

DMA1 Channel6 transfer complete flag

DMA1_FLAG_HT6

DMA1 Channel6 half transfer flag

DMA1_FLAG_TE6

DMA1 Channel6 transfer error flag

DMA1_FLAG_GL7

DMA1 Channel7 global flag

DMA1_FLAG_TC7

DMA1 Channel7 transfer complete flag

DMA1_FLAG_HT7

DMA1 Channel7 half transfer flag

DMA1_FLAG_TE7

DMA1 Channel7 transfer error flag

 

Example:

 

/* Test if the DMA1 Channel6 half transfer interrupt flag is set or not */

 

FlagStatus Status;

 

Status = DMA_GetFlagStatus(DMA1_FLAG_HT6);

 

 

 

DMA_ClearFlag function

 

Function name

DMA_ClearFlag

Function prototype

void DMA_ClearFlag(u32 DMA_FLAG)

Behavior description

Clears the DMAy Channelx's pending flags.

Input parameter

DMA_FLAG: flag to be cleared. More than one flag can be cleared using the “|” operator. Refer to DMA_FLAG for more details on the allowed values for this parameter. The user can select more than one flag, by ‘ORing’ them.

Output parameter

None

Return parameter

None

Required preconditions

None

Called functions

None

 

Example:

 

/* Clear the DMA1 Channel3 transfer error interrupt pending bit */

 

DMA_ClearFlag(DMA1_FLAG_TE3);

 

 

 

DMA_GetITStatus function

 

Function name

DMA_GetITStatus

Function prototype

ITStatus DMA_GetITStatus(u32 DMA_IT)

Behavior description

Checks whether the specified DMAy Channelx interrupt has occurred or not.

Input parameter

DMA_IT: DMAy Channelx interrupt source to check. Refer to DMA_IT for more details on the allowed values for this parameter.

Output parameter

None

Return parameter

The new state of DMA_IT (SET or RESET).

Required preconditions

None

Called functions

None

 

DMA_IT

 

DMA_FLAG

Description

DMA1_IT_GL1

DMA1 Channel1 global interrupt

DMA1_IT_TC1

DMA1 Channel1 transfer complete interrupt

DMA1_IT_HT1

DMA1 Channel1 half transfer interrupt

DMA1_IT_TE1

DMA1 Channel1 transfer error interrupt

DMA1_IT_GL2

DMA1 Channel2 global interrupt

DMA1_IT_TC2

DMA1 Channel2 transfer complete interrupt

DMA1_IT_HT2

DMA1 Channel2 half transfer interrupt

DMA1_IT_TE2

DMA1 Channel2 transfer error interrupt

DMA1_IT_GL3

DMA1 Channel3 global interrupt

DMA1_IT_TC3

DMA1 Channel3 transfer complete interrupt

DMA1_IT_HT3

DMA1 Channel3 half transfer interrupt

DMA1_IT_TE3

DMA1 Channel3 transfer error interrupt

DMA1_IT_GL4

DMA1 Channel4 global interrupt

DMA1_IT_TC4

DMA1 Channel4 transfer complete interrupt

DMA1_IT_HT4

DMA1 Channel4 half transfer interrupt

DMA1_IT_TE4

DMA1 Channel4 transfer error interrupt

DMA1_IT_GL5

DMA1 Channel5 global interrupt

DMA1_IT_TC5

DMA1 Channel5 transfer complete interrupt

DMA1_IT_HT5

DMA1 Channel5 half transfer interrupt

DMA1_IT_TE5

DMA1 Channel5 transfer error interrupt

DMA1_IT_GL6

DMA1 Channel6 global interrupt

DMA1_IT_TC6

DMA1 Channel6 transfer complete interrupt

DMA1_IT_HT6

DMA1 Channel6 half transfer interrupt

DMA1_IT_TE6

DMA1 Channel6 transfer error interrupt

DMA1_IT_GL7

DMA1 Channel7 global interrupt

DMA1_IT_TC7

DMA1 Channel7 transfer complete interrupt

DMA1_IT_HT7

DMA1 Channel7 half transfer interrupt

DMA1_IT_TE7

DMA1 Channel7 transfer error interrupt

 

Example:

 

/* Test if the DMA1 Channel7 transfer complete interrupt has occurred or not */

 

ITStatus Status;

 

Status = DMA_GetITStatus(DMA1_IT_TC7);

 

 

 

DMA_ClearITPendingBit function

 

Function name

DMA_ClearITPending Bit

Function prototype

void DMA_ClearITPendingBit(u32 DMA_IT)

Behavior description

Clears the DMAy Channelx’s interrupt pending bits.

Input parameter

DMA_IT: DMAy Channelx interrupt pending bit to clear.More than one interrupt can be cleared using the “|” operator. Refer to DMA_IT for more details on the allowed values for this parameter.

Output parameter

None

Return parameter

None

Required preconditions

None

Called functions

None

 

Example:

 

/* Clear the DMA1 Channel5 global interrupt pending bit */

 

DMA_ClearITPendingBit(DMA1_IT_GL5);

 

 

 

 

7.4  立即演練

 

實驗1Polling DMA

 

實驗說明:利用Polling的方式使用DMA搬移記憶體資料。

 

Grafcet

image012  

 

此實驗的重點,就是何謂「Polling」機制?所謂Polling就是輪詢的意思就是指CPU不斷的去檢查、查看。以範例的程式碼為例:

 

while (1)

 

{

 

        /* Wait the end of transmission */

 

       printf("\r\nWait the end of transmission...");

 

       while (DMA_GetFlagStatus(DMA1_FLAG_TC6) == RESET);

 

       printf("\r\nDMA1_FLAG_TC6:%d",DMA_GetFlagStatus(DMA1_FLAG_TC6));

 

       printf("\r\nDMA1 Channel6 Received Data:");

 

/* Check if the transmitted and received data are equal */

 

       Buffercmp(SRC_Const_Buffer, DST_Buffer, BufferSize);

 

       DMA_ClearFlag(DMA1_FLAG_TC6);

 

}

 

這段敘述就是一個典型的Polling的例子。DMA1_FLAG_TC6是確認DMA是否已搬完資料的旗標,為RESET時表示尚未搬完;為SET時表示已搬完。當CPU執行這段程式碼,一旦DMA_GetFlagStatus(DMA1_FLAG_TC6) == RESET條件成立,即DMA尚未搬完資料,程式將不斷執行此空迴圈,而CPU也會不斷地去檢查while當中的條件是否成立。

 

在此實驗當中,雖然CPU並沒有提升使用效率,因為CPU大部分的時間還是花在Polling的動作。但是因為有使用到DMA,在做記憶體存取資料的速度,還是比一般用for迴圈速度還要來的快!

 

其餘重要的DMA設定部分如:

 

void RCC_Configuration(void)

 

{

 

       /* Enable peripheral clocks ------------------------------------------------*/

 

       /* Enable DMA1 clock */

 

       RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

 

}

 

void DMA_Configuration(void)

 

{   /* DMA1 channel6 configuration */

 

       DMA_InitTypeDef DMA_InitStructure;

 

        DMA_DeInit(DMA1_Channel6);

 

       DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)SRC_Const_Buffer;

 

       DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)DST_Buffer;

 

       DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;

 

       DMA_InitStructure.DMA_BufferSize = BufferSize;

 

       DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable;

 

       DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;

 

       DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;

 

       DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;

 

       DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;

 

       DMA_InitStructure.DMA_Priority = DMA_Priority_High;

 

       DMA_InitStructure.DMA_M2M = DMA_M2M_Enable;

 

       DMA_Init(DMA1_Channel6, &DMA_InitStructure);

 

}

 

 

 

實驗2Interrupt DMA

 

實驗說明:利用Interrupt的方式使用DMA搬移記憶體資料。

 

Grafcet

image013  

Interrupt機制最大不同於Polling就是,DMA完成工作時,將會主動告知CPU,而CPU就無須用Polling的方式,大大增進了效率。

讀者可以發現,在main.c的程式碼中,不同於上一實驗,已經少了while (DMA_GetFlagStatus(DMA1_FLAG_TC6) == RESET)的敘述,取而代之的是在stm32f10x_it中的void DMA1_Channel6_IRQHandler(void)敘述:

void DMA1_Channel6_IRQHandler(void)

{

 

  /* Test on DMA1 Channel6 Transfer Complete interrupt */

  if(DMA_GetITStatus(DMA1_IT_TC6))

  {

    printf("\r\nDMA1_FLAG_TC6:%d",DMA_GetFlagStatus(DMA1_FLAG_TC6));

    DMA_ClearITPendingBit(DMA1_IT_TC6);

 

        printf("\r\n DMA1 Channel6 Interrupt Received data:");

        Buffercmp(SRC_Const_Buffer, DST_Buffer, BufferSize);

  }

}

此敘述就是在描述當DMA的工作完成,即啟動Interrupt通知CPU

開啟Interrupt設定部分如:

void NVIC_Configuration(void)

{

       NVIC_InitTypeDef NVIC_InitStructure;

      

        NVIC_SetVectorTable(0x08003000,0x0);

 

       /* Enable DMA1 channel6 IRQ Channel */

       NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel6_IRQn;

       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

       NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

       NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

       NVIC_Init(&NVIC_InitStructure);

}

 

 

 

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 youboook 的頭像
    youboook

    youboook的部落格

    youboook 發表在 痞客邦 留言(0) 人氣()