Tutorial Microcontroller MCS-51 ATMEL ISP


Super MCS51 Trainer

Standart MCS51 Trainer

Standart AVR Trainer

Programmer USBASP

Standart ARM Trainer


Sending Block Memory to Another Block Memory Via DMA

/* DMA Stream parameters definitions. You can modify these parameters to select a different DMA Stream and/or channel. 
   But note that only            DMA2 Streams are capable of Memory to Memory transfers. */
#define DMA_STREAM DMA2_Stream0
#define DMA_CHANNEL DMA_Channel_0
#define DMA_STREAM_IRQ DMA2_Stream0_IRQn
#define BUFFER_SIZE 32
#define TIMEOUT_MAX 10000 /* Maximum timeout value */
const uint32_t SRC_Const_Buffer[BUFFER_SIZE] = { 
0x01020304, 0x05060708,0x090A0B0C, 0x0D0E0F10, 0x11121314, 0x15161718, 0x191A1B1C,0x1D1E1F20,
0x21222324, 0x25262728, 0x292A2B2C, 0x2D2E2F30, 0x31323334, 0x35363738,0x393A3B3C, 0x3D3E3F40, 
0x41424344, 0x45464748,0x494A4B4C, 0x4D4E4F50,0x51525354, 0x55565758, 0x595A5B5C, 0x5D5E5F60, 
0x61626364, 0x65666768,0x696A6B6C, 0x6D6E6F70, 0x71727374,0x75767778, 0x797A7B7C, 0x7D7E7F80 };
uint32_t DST_Buffer[BUFFER_SIZE];
/* Private typedef ---------------------------------------------*/
typedef enum 
  } TestStatus;
 /* Private variables --------------------------------------------*/
__IO TestStatus TransferStatus = FAILED;
 * @brief Compares two buffers.
 * @param pBuffer, pBuffer1: buffers to be compared.
 * @param BufferLength: buffer's length
 * @retval PASSED: pBuffer identical to pBuffer1
 * FAILED: pBuffer differs from pBuffer1
TestStatus Buffercmp(const uint32_t* pBuffer, uint32_t* pBuffer1, uint16_t BufferLength) 
 while (BufferLength--) 
  if (*pBuffer != *pBuffer1) 
   return FAILED;
   return PASSED;
 * @brief Configure the DMA controller according to the Stream parameters
 * defined in main.h file
 * @param None
 * @retval None
void DMA_Config(void) 
  NVIC_InitTypeDef NVIC_InitStructure;
  DMA_InitTypeDef DMA_InitStructure;
  __IO uint32_t Timeout = TIMEOUT_MAX;
  /* Enable DMA clock */
  /* Reset DMA Stream registers (for debug purpose) */
  /* Check if the DMA Stream is disabled before enabling it. 
  Note that  this step is useful when the same Stream is used multiple times: enabled,            
  then disabled then re-enabled... In this case, the DMA Stream disable            
  will be effective only at the end of the ongoing data transfer and it            
  will not be possible to re-configure it before making sure that the            
  Enable bit has been cleared by hardware. If the Stream is used only            
  once, this step might be bypassed. 
  while (DMA_GetCmdStatus(DMA2_Stream0) != DISABLE)
  /* Configure DMA Stream */
  DMA_InitStructure.DMA_Channel = DMA_Channel_0;
  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)SRC_Const_Buffer;
  DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)DST_Buffer;
  DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToMemory;
  DMA_InitStructure.DMA_BufferSize = (uint32_t)BUFFER_SIZE;
  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_FIFOMode = DMA_FIFOMode_Disable;
  DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
  DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
  DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
  DMA_Init(DMA2_Stream0, &DMA_InitStructure);
  /* Enable DMA Stream Transfer Complete interrupt */
  DMA_ITConfig(DMA2_Stream0, DMA_IT_TC, ENABLE);
  /* DMA Stream enable */
  DMA_Cmd(DMA2_Stream0, ENABLE);
  /* Check if the DMA Stream has been effectively enabled.
  The DMA Stream Enable bit is cleared immediately by hardware if there is an
  error in the configuration parameters and the transfer is no started (ie. 
  When wrong FIFO threshold is configured ...) 
  Timeout = TIMEOUT_MAX;
  while ((DMA_GetCmdStatus(DMA2_Stream0) != ENABLE) && (Timeout--> 0))
  /* Check if a timeout condition occurred */
  if (Timeout == 0)
   /* Manage the error: to simplify the code enter an infinite loop */
   while (1)
  /* Enable the DMA Stream IRQ Channel */
  NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream0_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 5;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
volatile uint8_t i;
void DMA2_Stream0_IRQHandler(void) 
 /* Test on DMA Stream Transfer Complete interrupt */
 if (DMA_GetITStatus(DMA2_Stream0, DMA_IT_TCIF0)) 
  /* Clear DMA Stream Transfer Complete interrupt pending bit */
  DMA_ClearITPendingBit(DMA2_Stream0, DMA_IT_TCIF0);
   i = 1;
/*---------------------START OF BOOT---------------------------------*/
int main(void) {
//First of all, we need to setup proper interrupt priority
//Only preemption priority //group (4 bits)
uint32_t counter=0;
while (1) 
 /* Configure and enable the DMA Stream for Memory to Memory transfer */
 i = 0;
 /* Wait the end of transmission (the DMA Stream is disabled by Hardware            
  at the end of the transfer) .
 There is also another way to check on end of transfer by monitoring            
 the number of remaining data to be transferred. 
 // while (DMA_GetCurrentMemoryTarget(DMA_STREAM) != 0) *//* First method            */\
 while (DMA_GetCmdStatus(DMA2_Stream0) != DISABLE) /* Second method            */
  Since this code present a simple example of how to use DMA, it is just
  waiting on the end of transfer. But, while DMA Stream is transferring            data, 
  the CPU is free to perform other tasks in parallel to the DMA transfer.
  /*Check if the transmitted and received data are equal */
    TransferStatus = Buffercmp(SRC_Const_Buffer, DST_Buffer, BUFFER_SIZE);
  /*TransferStatus = PASSED, if the transmitted and received data
    are the same */
  /*TransferStatus = FAILED, if the transmitted and received data
    are different */
 if (TransferStatus != PASSED) 
  /* Turn LED4 on: Transfer correct */
  while (1)
 while (1)