STM32F7 Temporizador y DMA

0

Actualmente estoy intentando adaptar el proyecto de ejemplo TIM_DMA de F769I_EVAL al tablero de descubrimiento STM32F746G. Soy bastante nuevo en STM32 y esto podría ser un error obvio.

El código crea un temporizador y lo configura con DMA.
Lo cambié para usar TIM2 en el pin PB_8 y para usar DMA2 (Transmisión 0) en lugar de DMA1 (he leído en algún lugar en la documentación que DMA1 es principalmente para memoria a memoria)

La generación de la señal PWM funciona, pero permanece en el primer valor (75% de ciclo de trabajo). No sé por qué ese es el caso.

Mi configuración es

#define TIMx                             TIM4
#define TIMx_CLK_ENABLE                  __HAL_RCC_TIM4_CLK_ENABLE
#define DMAx_CLK_ENABLE                  __HAL_RCC_DMA2_CLK_ENABLE
#define TIMx_CHANNEL3_GPIO_CLK_ENABLE    __HAL_RCC_GPIOB_CLK_ENABLE
#define TIMx_GPIO_CHANNEL3_PORT          GPIOB
#define GPIO_PIN_CHANNEL3                GPIO_PIN_8
#define GPIO_AF_TIMx                     GPIO_AF2_TIM4
#define TIMx_CC3_DMA_INST                DMA2_Stream0
#define TIMx_DMA_IRQn                    DMA2_Stream0_IRQn
#define TIMx_DMA_IRQHandler              DMA2_Stream0_IRQHandler

mi función principal

int main(void) {
    CPU_CACHE_Enable();
    HAL_Init();
    SystemClock_Config();
    BSP_LED_Init(LED1);

    uwTimerPeriod = (uint32_t)(((SystemCoreClock/2) / 17570) - 1);
    aCCValue_Buffer[0] = (uint32_t)(((uint32_t) 75 * (uwTimerPeriod - 1)) / 100);
    aCCValue_Buffer[1] = (uint32_t)(((uint32_t) 50 * (uwTimerPeriod - 1)) / 100);
    aCCValue_Buffer[2] = (uint32_t)(((uint32_t) 25 * (uwTimerPeriod - 1)) / 100);

    /*-1- Configure the TIM peripheral */
    TimHandle.Instance = TIMx;
    TimHandle.Init.Period            = uwTimerPeriod;
    TimHandle.Init.RepetitionCounter = 3;
    TimHandle.Init.Prescaler         = 0;
    TimHandle.Init.ClockDivision     = 0;
    TimHandle.Init.CounterMode       = TIM_COUNTERMODE_UP;
    TimHandle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
    if (HAL_TIM_PWM_Init(&TimHandle) != HAL_OK) {
        Error_Handler();
    }

    /*-2- Configure the PWM channel 3 */
    sConfig.OCMode       = TIM_OCMODE_PWM1;
    sConfig.OCPolarity   = TIM_OCPOLARITY_HIGH;
    sConfig.Pulse        = aCCValue_Buffer[0];
    sConfig.OCNPolarity  = TIM_OCNPOLARITY_HIGH;
    sConfig.OCFastMode   = TIM_OCFAST_DISABLE;
    sConfig.OCIdleState  = TIM_OCIDLESTATE_RESET;
    sConfig.OCNIdleState = TIM_OCNIDLESTATE_RESET;
    if (HAL_TIM_PWM_ConfigChannel(&TimHandle, &sConfig, TIM_CHANNEL_3) != HAL_OK) {
        Error_Handler();
    }

    /*-3- Start PWM signal generation in DMA mode */
    if (HAL_TIM_PWM_Start_DMA(&TimHandle, TIM_CHANNEL_3, aCCValue_Buffer, 3) != HAL_OK) {
        Error_Handler();
    }

    while (1) {
    }
}

la función de interrupción

void TIMx_DMA_IRQHandler(void) {
    HAL_DMA_IRQHandler(TimHandle.hdma[TIM_DMA_ID_CC3]);
}

y la función de inicialización PWM MSP

void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim) {
    GPIO_InitTypeDef   GPIO_InitStruct;
    static DMA_HandleTypeDef  hdma_tim;

    /*-1- Enable peripherals and GPIO Clocks */
    TIMx_CLK_ENABLE();
    TIMx_CHANNEL3_GPIO_CLK_ENABLE();
    DMAx_CLK_ENABLE();

    GPIO_InitStruct.Pin = GPIO_PIN_CHANNEL3;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF_TIMx;
    HAL_GPIO_Init(TIMx_GPIO_CHANNEL3_PORT, &GPIO_InitStruct);

    hdma_tim.Init.Channel = DMA_CHANNEL_3;
    hdma_tim.Init.Direction = DMA_MEMORY_TO_PERIPH;
    hdma_tim.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma_tim.Init.MemInc = DMA_MINC_ENABLE;
    hdma_tim.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD ;
    hdma_tim.Init.MemDataAlignment = DMA_MDATAALIGN_WORD ;
    hdma_tim.Init.Mode = DMA_CIRCULAR;
    hdma_tim.Init.Priority = DMA_PRIORITY_HIGH;
    hdma_tim.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
    hdma_tim.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
    hdma_tim.Init.MemBurst = DMA_MBURST_SINGLE;
    hdma_tim.Init.PeriphBurst = DMA_PBURST_SINGLE;

    hdma_tim.Instance = TIMx_CC3_DMA_INST;

    __HAL_LINKDMA(htim, hdma[TIM_DMA_ID_CC3], hdma_tim);

    /* Initialize TIMx DMA handle */
    if(HAL_DMA_Init(htim->hdma[TIM_DMA_ID_CC3]) != HAL_OK) {
        Error_Handler();
    }

    /*-2- Configure the NVIC for DMA */
    HAL_NVIC_SetPriority(TIMx_DMA_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(TIMx_DMA_IRQn);
}

La salida se ve así:

¿Qué es exactamente lo que me estoy perdiendo? ¿El TIM4 no funciona con el DMA2 o tengo que usar controladores específicos de Interrupción?

    
pregunta thomasguenzel

0 respuestas

Lea otras preguntas en las etiquetas