Örnek : STM32F100RB ile DMA kullanımı

Başlatan camby, 18 Kasım 2012, 00:58:45

camby

Bülent hocam burada F4 için bir örnek yapmış : https://www.picproje.org/index.php/topic,35896.0.html

Ben de STM32F100RB için yapayım dedim. Bilmeyenler neden bu işlemci ile diye sorarsa , işte bu kit yüzünden http://www.st.com/internet/evalboard/product/250863.jsp . Kit üzerinde Cortex M3 mimarili bu işlemci bulunuyor. Bu işlemci ile ilgili az da olsa forumda örnekler var. Muhittin Hocam'ın bloğunda da benzer çalışmalar var.

STM32F100RB'de DMA yapısı F4'ten biraz daha farklı , data basit denebilir.

Bülent hocanın örneğindeki gibi 1024 adet veri bir yerden başka bir yere kopyalanıyor.

Ekstra özel bir kütüphane yada header yok , GPIO ve System_Init koda dahil değil.

Kopyalama işlemi sonunda , işlem tamamlandı kesmesi gelerek , kesme programında kopyalama öncesi yanan led sönüyor. Bu sayede işlemin durumu ledden gözlenebilir.


/******************************************************************************/
/*  STM32F100RB  DMA  TEST	                                                  */
/******************************************************************************/

#include "stm32f10x.h"

char Source[1024];
char Target[1024];

//================= DMA1 Channel2 Handler =====================================

void DMA1_Channel2_IRQHandler()
{
	GPIOC->ODR &=~ 0x00000100;				// Test Led OFF
	DMA1->IFCR |= (1<<5);					// Clear Flag	
}

//================= DMA Memory to Memory  =====================================
void DMA_Kopyala(void)
{
	RCC->AHBENR |= 1;       					// DMA1EN: DMA1 clock enable 
		
	DMA1_Channel2->CNDTR = 1024;				// Tasinacak veri sayisi 1024
    DMA1_Channel2->CMAR = (int)&Source[0];  	// Source array dan datalari alacagiz
    DMA1_Channel2->CPAR = (int)&Target[0];  	// Target array a datalari tasiyacagiz
	
	DMA1_Channel2->CCR |= (1<<14);				// MEM2MEM: Memory to memory mode
	DMA1_Channel2->CCR |= (3<<12);				// PL[1:0]: Channel priority level - 11: Very high
	DMA1_Channel2->CCR |= (1<<7);				// MINC: Memory increment mode - enabled
	DMA1_Channel2->CCR |= (1<<6);				// PINC: Peripheral increment mode - enabled
	DMA1_Channel2->CCR |= (1<<4);				// DIR: Data transfer direction - 1: Read from memory
	
	DMA1_Channel2->CCR |= (1<<1);				// TCIE: Transfer complete interrupt enable
 
	NVIC->ISER[0] |= (1<<12);					// DMA1 Channel 2 global Interrupt
	
    DMA1_Channel2->CCR |= 1;     				// EN: Channel enable
	
}

//================= Main ======================================================
int main (void) 
 {	 
	volatile int i;
	 
	GPIO_Init(); 
	 
	for(i=0;i<1024;i++) Source[i]=i;  			// Baslangic Datalari
 
	GPIOC->ODR |= 0x00000100;
	DMA_Kopyala();
	
	while(1) 									// Loop forever
	{						
	}
}

prometus

Merhabalar, Ben STM32L100 kullanmaktayım DMA yı birçok örnek incelemem rağmen bir türlü osiloskoptan göremedim. yardımcı olursanız sevinirim.
void gpio_configure(void)

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9| GPIO_Pin_10;	  // UART1 TX pin and Rx pin
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF ; // SELECT ALTERNATE FUNCTION
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;    // push pull type
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz;
    GPIO_Init(RF_TXD_PORT, &GPIO_InitStructure);  // RF_TXD_PORT = RF_RXD_PORT
    /* Connect USART pins to AF */
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource9,  GPIO_AF_USART1);
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource10,  GPIO_AF_USART1);

{


void dma_configure(void)
{
     NVIC_InitTypeDef NVIC_InitStructure;
    /* DMA clock */
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
    /* DMA configuration ------------------------------------------------------*/
    DMA_DeInit(DMA1_Channel5);          //       RX channel
    DMA_DeInit(DMA1_Channel4);          //       TX channel
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; 
    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;        // in normal mode
    DMA_InitStructure.DMA_BufferSize = STORAGE_BUFFER_SIZE;         
    DMA_InitStructure.DMA_PeripheralBaseAddr =(uint32_t) USART1_BASE + 0x04;      // source
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;             //rs232 have byte size
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;                     // equally byte size
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;                    // autoincrement disable
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;                             // autoincrement enable
    // TX  configuration
    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)DMA_sending_data;         // destinition
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
    DMA_InitStructure.DMA_Priority = DMA_Priority_Low;  								// high priority
    DMA_Init(DMA1_Channel4, &DMA_InitStructure);
    
    //DMA_Cmd(DMA1_Channel5,ENABLE);

    // RX  configuration
    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)DMA_received_data;
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
    DMA_Init(DMA1_Channel5, &DMA_InitStructure);

    //NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    /* Enable the USART1 RX DMA Interrupt */
    NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel5_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0B;
    NVIC_InitStructure.NVIC_IRQChannelCmd =ENABLE;
    NVIC_Init(&NVIC_InitStructure);
    /* Enable the USART1 TX DMA Interrupt */
    NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel4_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0A;
    NVIC_InitStructure.NVIC_IRQChannelCmd =ENABLE;
    NVIC_Init(&NVIC_InitStructure);


void DMA_send(unsigned char* pt_data,unsigned char lenght)
{

    DMA_ClearFlag(DMA1_FLAG_GL4); /*clear global flag clears all other flags*/
    send_control=ORC_send_data_continue;
    DMA_ITConfig(DMA1_Channel4, DMA_IT_TC, ENABLE);
    DMA_InitStructure.DMA_BufferSize=(uint16_t)lenght;
    DMA_InitStructure.DMA_MemoryBaseAddr=(uint32_t)*pt_data;
    DMA_Init(DMA1_Channel4L,&DMA_InitStructure);
    DMA_Cmd(DMA1_Channel4,ENABLE);
    USART_DMACmd(USART1 ,USART_DMAReq_Tx,ENABLE);
    do
    {
        if(DMA_GetCurrDataCounter(DMA1_Channel4)==0)
        {
            break;
        }
    }
    while(send_control!=ORC_success);
    DMA_Cmd(DMA1_Channel4,DISABLE);
    USART_DMACmd(USART1 ,USART_DMAReq_Tx,DISABLE);
    DMA_ITConfig(DMA1_Channel4, DMA_IT_TC, DISABLE);

}

void DMA1_Channel4_IRQHandler (void)
{
  //Test on DMA1 Channel1 Transfer Complete interrupt
  if(DMA_GetITStatus(DMA1_FLAG_GL4))
  {
    send_control=ORC_success;
    DMA_ClearITPendingBit(DMA1_FLAG_GL4);
  }
  DMA_ClearITPendingBit(DMA1_FLAG_GL4);

}