cancel
Showing results for 
Search instead for 
Did you mean: 

PWM WÄ°TH DMA

ataberktopcuuu
Associate II
Posted on October 20, 2016 at 07:50

Hi guys.I want to try pwm with dma.(by using burst)I tried to send data to timx_arr(period) that necessary for pwm. Still, ı observed from logic analyzer. But it has not signal without writing ''tim_timebaseinitstructure.tim_period''.what do you think about that problem? Actually, ı send from buffer to memory0base.However,Will data that start in memory0base address cross to address of timx_arr in peripheral?

#include ''stm32f4xx.h'' // Device header
//DEFINITIONS
#define TIM1_DMAR_ADDRESS ((uint16_t)0x4001004C) //TIMER DMA REGISTER ADDRESS
#define BUFFER_SIZE 3 // DATA WIDTH
//ARRAYS & VARIABLES 
const uint16_t DATA_BUFFER[3]={0xFFFF,0,0x000F}; //ARR,RCR,CCR1
//PROTOTYPES
void DMA_CONFIGURATIONS(void);
void GPIO_CONFIGURATIONS(void);
void RCC_CONFIGURATIONS(void);
void TIMER_CONFIGURATIONS(void);
void PWM_CONFIGURATIONS(void);
void PERIPHERALS_ENABLE(void);
void NVIC_CONFIGURATIONS(void);
void LED_INIT(void);
//DEFINE STRUCTURE 
DMA_InitTypeDef DMA_InitStructure; //DIRECT MEMORY ACCESS(DMA) INITLIZATION VARIABLE
GPIO_InitTypeDef GPIO_InitStructure; //GENERAL PURPOSE INPUT/OUTPUT INITALIZATION VARIABLE
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure; //TIMER INITALIZATION VARIABLE
TIM_OCInitTypeDef TIM_OCInitStructure; //TIMER OUTPUT COMPARE INITALIZATION VARIABLE
NVIC_InitTypeDef NVIC_InitStructure; //INTERRUPTS INITALIZATION
//INTERRUPTS
void DMA2_Stream5_IRQHandler()
{
if(DMA_GetITStatus(DMA2_Stream5,DMA_IT_TCIF5)!=RESET)
{
DMA_ClearITPendingBit(DMA2_Stream5,DMA_IT_TCIF5); //CLEAR TCIF5 FLAG (TRANSFER COMPLETE INTERRUPT FLAG)
LED_INIT(); //LED INITALIZATION
}
}
int main()
{ 
// DEFAULT SYSTEM SETTINGS
RCC_CONFIGURATIONS(); 
GPIO_CONFIGURATIONS(); 
NVIC_CONFIGURATIONS(); 
TIMER_CONFIGURATIONS();
DMA_CONFIGURATIONS(); 
PWM_CONFIGURATIONS();
PERIPHERALS_ENABLE();
while (!DMA_GetFlagStatus(DMA2_Stream5, DMA_FLAG_TCIF5));
while(1);
} 
/**
@brief : DMA-2 CONFIGURATIONS
@para : NONE
@retval : NONE
*/
void DMA_CONFIGURATIONS()
{
DMA_DeInit(DMA2_Stream5); //DEFAULT DMA SETTINGS
DMA_InitStructure.DMA_Channel = DMA_Channel_6; // DEFINE DMA CHANNEL
DMA_InitStructure.DMA_Memory0BaseAddr = (uint16_t)DATA_BUFFER ; // SHOW FIRST ADDRESS OF MEMORY BASE 
DMA_InitStructure.DMA_BufferSize = BUFFER_SIZE ; // DATA THAT COME FROM PERIPHERAL(PWM) IS HALFWORD(16-BIT)
DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; // SHOW THAT GO FROM MEMORY TO PERIPHERAL
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable; // ENABLE FIRST-IN FIRST-OUT 
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; // THRESHOLD FULL OF DATA 
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; // (MEMORY BURST) SINGLE
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; // DATA TYPE HALFWORD
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; // AUTOMATICALLY INCREMENTING MEMORY ADDRESS 
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; // DON'T RELOAD AUTOMATICALLY WITH PREVIOUSLY PROGRAMMING VALUE
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint16_t)TIM1_DMAR_ADDRESS; // DEFINE PERIPHERAL ADDRESS
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; // PERIPHERAL SINGLE
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;// DATA TYPE HALFWORD
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable; // AUTOMATICALLY INCREMENTING PERIPHERAL ADDRESS
DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; // PRIORITY VERYHIGH
DMA_Init(DMA2_Stream5,&DMA_InitStructure); // DMA INITIZALITION
DMA_ITConfig(DMA2_Stream5,DMA_IT_TC,ENABLE); //TRANSFER COMPLETE INTERRUPT FLAG IS ENABLED 
DMA_PeriphIncOffsetSizeConfig(DMA2_Stream5,DMA_PINCOS_Psize);
}
/**
*@brief : GENERAL PURPOSE INPUT OUTPUT CONFIGURATIONS
*@para : NONE
*@retval: NONE
*/
void GPIO_CONFIGURATIONS()
{
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; // ALTERNATIVE FUNCTION
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; // PULL-UP PULL-DOWN
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; // CHOOSE PIN 8
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; // NOPULL
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; // SPEED 100MHz
GPIO_Init(GPIOA,&GPIO_InitStructure); // GPIOA INITALIZATION
GPIO_PinAFConfig(GPIOA,GPIO_PinSource8,GPIO_AF_TIM1); //ALTERNATIVE FUNCTION TIMER
}
/**
*@brief : CONFIGURE PERIPHERAL CLOCKS
*@para : NONE
*@retval : NONE
*/
void RCC_CONFIGURATIONS()
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE); //TIM1 CLOCK ENABLE
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOD,ENABLE); //GPIOA|D CLOCK ENABLE
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2,ENABLE); //DMA2 CLOCK ENABLE
}
/**
*@brief : CONFIGURE TIMER
*@para : NONE
*@retval : NONE
*/
void TIMER_CONFIGURATIONS()
{ 
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInitStructure.TIM_Prescaler = 0;
TIM_TimeBaseInitStructure.TIM_RepetitionCounter= 0;
TIM_TimeBaseInit(TIM1,&TIM_TimeBaseInitStructure);
}
/**
*@brief : CONFIGURE PWM 
*@para : NONE
*@retval : NONE
*/
void PWM_CONFIGURATIONS()
{
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; // PWM OUTPUT
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; // STARTING WAVE IS LOW
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 0xFFF; 
TIM_OC1Init(TIM1,&TIM_OCInitStructure); 
}
/**
*@brief : ENABLE PERIPHERALS (DMA,TIM,PWM)
*@para : NONE
*@retval : NONE
*/
void PERIPHERALS_ENABLE()
{
TIM_DMAConfig(TIM1,TIM_DMABase_PSC,TIM_DMABurstLength_3Transfers);
TIM_DMACmd(TIM1,TIM_DMA_Update,ENABLE);
TIM_Cmd(TIM1,ENABLE);
TIM_CtrlPWMOutputs(TIM1,ENABLE);
DMA_Cmd(DMA2_Stream5,ENABLE); 
}
/**
*@brief : CONFIGURE NVIC
*@para : NONE
*@retval : NONE
*/
void NVIC_CONFIGURATIONS()
{
NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
/**
*@brief : LED INITILIZATIONS
*@para : NONE
*@retval : NONE
*/
void LED_INIT()
{
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_Init(GPIOD,&GPIO_InitStructure);
GPIO_ToggleBits(GPIOD, GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15); 
}

4 REPLIES 4
Nesrine M_O
Lead II
Posted on October 20, 2016 at 11:25

Hi Ataberk,

I recommend you to have a look to the TIM1 DMA Burst transfer example under the STM32F4 standard peripherals library it may be very helpful:

STM32F4xx_DSP_StdPeriph_Lib_V1.7.1\STM32F4xx_DSP_StdPeriph_Lib_V1.7.0\Project\STM32F4xx_StdPeriph_Examples\TIM\TIM_DMABurst

-Syrine-

Walid FTITI_O
Senior II
Posted on October 20, 2016 at 12:24

Hi Ataberk,

The Timer DMA burst feature use is little bit different from the general DMA burst.

A recent application note

http://www.st.com/content/ccc/resource/technical/document/application_note/group0/91/01/84/3f/7c/67/41/3f/DM00236305/files/DM00236305.pdf/jcr:content/translations/en.DM00236305.pdf

which treat in one of its several topics the Timer DMA burst (feature and use) and there is a relevant example called '' Arbitrary waveform generation using timer DMA-burst feature'' located in the firmware package ''

http://www.st.com/content/st_com/en/products/embedded-software/mcus-embedded-software/stm32-embedded-software/stm32cube-expansion-software/x-cube-timcooker.html

''

-Hannibal-
ataberktopcuuu
Associate II
Posted on October 20, 2016 at 14:47

hi hannibal, thanks you for your informations.there is a theme that ı dont understand.Now,peripheral take data from aSRC_Buffer(memory0base).Well, why do we write ''time.period'' in timer configurations?İs not it necessary?Anyway, is aSRC_Buffer's datas sent via dmaburst to tim_arr?

Walid FTITI_O
Senior II
Posted on November 01, 2016 at 11:02

Hi Ataberk, 

TIM_ARR is not implicated at all in the TIMER DMA Burst transfer, it is just initialized as all instance parameters should be initialized. The default initialization value is at the maximum to ensure continuous and long timer processing time allowed for burst transfer.

-Hannibal-