0
\$\begingroup\$

I wrote a code using DMA with TIM1. In DMA buffer i load diffrent periods and send to ARR Register. How Can I change a Pulse of PWM to 50% from Dma buffer ?

int i = 0;
volatile u16 PWM_Buf[20];
void TIMInit(void);
void GPIOInit(void);
void DMAInit(void);
void PWMInit(void);

int main(void) {
    GPIOInit();
    TIMInit();
    DMAInit();
    PWMInit();

    for (i = 0; i < 20; i++) {
        PWM_Buf[i] = i*100+300; //TU ŁADUJE WARTOSCI DO DMA ALE OKRES TIMERA SIE NIE ZMIENAI
    }

    while (1) {
    }
}
void TIMInit(void) {
    TIM_TimeBaseInitTypeDef TIMInit;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);

    //TIMInit.TIM_Period = 1000 - 1;
    TIMInit.TIM_Prescaler = 64000 - 1;
    TIMInit.TIM_ClockDivision = TIM_CKD_DIV1;
    TIMInit.TIM_CounterMode = TIM_CounterMode_Up;
    TIMInit.TIM_RepetitionCounter = 0;

    TIM_TimeBaseInit(TIM1, &TIMInit);
}

void GPIOInit(void) {
    GPIO_InitTypeDef GPIOInit;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);

    GPIOInit.GPIO_Pin = GPIO_Pin_8;
    GPIOInit.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIOInit.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_Init(GPIOA, &GPIOInit);
}

void DMAInit(void) {

    DMA_InitTypeDef DMAInit;
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
    DMA_DeInit(DMA1_Channel5);
    DMAInit.DMA_PeripheralBaseAddr = (u32)&TIM1 -> ARR && (u32)&TIM1 -> CCR1;
    DMAInit.DMA_MemoryBaseAddr = (u32) PWM_Buf;
    DMAInit.DMA_DIR = DMA_DIR_PeripheralDST;
    DMAInit.DMA_BufferSize = 20;
    DMAInit.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMAInit.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMAInit.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
    DMAInit.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
    DMAInit.DMA_Mode = DMA_Mode_Circular;
    DMAInit.DMA_Priority = DMA_Priority_High;
    DMAInit.DMA_M2M = DMA_M2M_Disable;
    DMA_Init(DMA1_Channel5, &DMAInit);

    DMA_Cmd(DMA1_Channel5, ENABLE);
}

void PWMInit(void) {
    TIM_OCInitTypeDef PWMInit;

    PWMInit.TIM_OCMode = TIM_OCMode_PWM1;
    PWMInit.TIM_OutputState = TIM_OutputState_Enable;
    PWMInit.TIM_Pulse = 5;
    PWMInit.TIM_OCPolarity = TIM_OCPolarity_High;
    TIM_OC1Init(TIM1, &PWMInit);
    //TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);
    //TIM_ARRPreloadConfig(TIM1, ENABLE);
    TIM_DMACmd(TIM1, TIM_DMA_Update, ENABLE);
    TIM_Cmd(TIM1, ENABLE);
    TIM_CtrlPWMOutputs(TIM1, ENABLE);
}
\$\endgroup\$
1
\$\begingroup\$

DMAInit.DMA_PeripheralBaseAddr = (u32)&TIM1 -> ARR && (u32)&TIM1 -> CCR1; It is unclear what you are doing here.

If you want two registers as destination, you will need two DMA channels.

The DMAInit.DMA_PeripheralBaseAddr (DMA_CPARx) register only takes one address.

\$\endgroup\$
  • \$\begingroup\$ You can write to multiple timer registers (for TIM1 and TIM8) using 1 DMA channel, by configuring TIM1->DCR and using TIM1->DMAR as the peripheral base address. \$\endgroup\$ – Batperson Aug 23 at 3:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.