Question
stm32 DMA transfer to Timer
Posted on February 16, 2015 at 14:21
Hello,
I'm working with the STM32F373 µC trying to get the DMA work with a timer. I want the DMA controller to write 3 different values in the ccr1 register of timer Unfortunately there is no example how to implement this on the STM32f373 in the STDPeriPH. So i take the example out of the STM32F4xx STDPeriph and try to adapt the source code for the stm32f Sadly to program doesn't work. The output on the PA2 pin is only a PWM signal with a fixed duty cycle. There is no update on the duty cycle which i expect. Here is the code i try to adept so far:#include ''stm32f37x.h''
#include ''stm32f37x_conf.h''
#include ''stdbool.h''
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
uint16_t aSRC_Buffer[3] = {0, 0, 0};
uint16_t uhTimerPeriod = 0;
/* Private function prototypes -----------------------------------------------*/
static void TIM_Config(void);
int main(void)
{
/* TIM Configuration */
TIM_Config();
/* Compute the value to be set in ARR regiter to generate signal frequency at 57 Khz */
uhTimerPeriod = (SystemCoreClock / 17570 ) - 1;
/* Compute CCR1 value to generate a duty cycle at 50% */
aSRC_Buffer[0] = (uint16_t) (((uint32_t) 5 * (uhTimerPeriod - 1)) / 10);
/* Compute CCR1 value to generate a duty cycle at 5% */
aSRC_Buffer[1] = (uint16_t) (((uint32_t) 375 * (uhTimerPeriod - 1)) / 1000);
/* Compute CCR1 value to generate a duty cycle at 25% */
aSRC_Buffer[2] = (uint16_t) (((uint32_t) 25 * (uhTimerPeriod - 1)) / 100);
/* TIM1 Peripheral Configuration -------------------------------------------*/
/* TIM1 clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM15, ENABLE);
/* Time Base configuration */
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_Period = uhTimerPeriod;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM15, &TIM_TimeBaseStructure);
/* Channel 3 Configuration in PWM mode */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable;
TIM_OCInitStructure.TIM_Pulse = 50;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
// TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
// TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
TIM_OC1Init(TIM15, &TIM_OCInitStructure);
/* Enable preload feature */
TIM_OC1PreloadConfig(TIM15, TIM_OCPreload_Enable);
/* TIM1 counter enable */
TIM_Cmd(TIM15, ENABLE);
/* DMA enable*/
DMA_Cmd(DMA1_Channel5, ENABLE);
/* TIM1 Update DMA Request enable */
TIM_DMACmd(TIM15, TIM_DMA_CC1, ENABLE);
// TIM_DMACmd(TIM15, TIM_DMA_Update, ENABLE);
/* Main Output Enable */
TIM_CtrlPWMOutputs(TIM15, ENABLE);
while (1)
{
}
}
/**
* @brief Configure the TIM1 Pins.
* @param None
* @retval None
*/
static void TIM_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
/* GPIOA and GPIOB clock enable */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
/* GPIOA Configuration: Channel 3 as alternate function push-pull */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 ;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_9);
/* DMA clock enable */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1 , ENABLE);
DMA_DeInit(DMA1_Channel5);
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&TIM15->CCR1;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&aSRC_Buffer;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure.DMA_BufferSize = 3;
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_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_Init(DMA1_Channel5, &DMA_InitStructure);
}
and this is what the osczi says:
As i described i take the code out of the STM32F4 STDPeriph. There i used the example:
\STM32F4xx_DSP_StdPeriph_Lib_V1.3.0\Project\STM32F4xx_StdPeriph_Examples\TIM\TIM_DMA
After starting the programm there is the first value of
aSRC_Buffer in the ccr1 register but the dma doesnt update.
I hope you can help me with that issue
greetz