Usando Tim2 (84MHz) para parpadear Led por cada 500 ms - STM32F407VG

-1

Desarrollé un código en orden para hacer parpadear un Led cada 500 ms usando el temporizador 2 con una frecuencia de 84Mhz.

Genero el archivo "system_stm32f4xx.c" para tener una frecuencia de 84MHz para Tim2.

Hemodificadoelarchivo"stm32f4xx.h" agregando la línea

#define HSE_VALUE ((uint32_t) 8000000)

He modificado el archivo "startup_stm32f4xx.c" descomentando la función SystemInit () y agregándolo antes de main () en la función Default_Reset_Handler ().

Después de eso creé el proyecto que se muestra a continuación.

El problema es que no obtengo el resultado de excepción, el led parpadea cada 100 ms:

#include "stm32f4xx.h"
#include "stm32f4xx_rcc.h"
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_tim.h"

void InitializeLEDs()
{
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
GPIO_InitTypeDef gpioStructure;
gpioStructure.GPIO_Pin = GPIO_Pin_12 ;
gpioStructure.GPIO_Mode = GPIO_Mode_OUT;
gpioStructure.GPIO_OType = GPIO_OType_PP;
gpioStructure.GPIO_Speed = GPIO_Speed_50MHz;
gpioStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOD, &gpioStructure);
}

void InitializeTimer()
{
// Ftim2 = 84Mhz
TIM_TimeBaseInitTypeDef timerInitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
timerInitStructure.TIM_Prescaler = 84000 - 1; // counter rate is 1ms
timerInitStructure.TIM_Period = 60000;
timerInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
timerInitStructure.TIM_ClockDivision = 0;
timerInitStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM2, &timerInitStructure);
}

void delay_ms(uint16_t ms)
{
TIM_SetCounter(TIM2, 0);    // Make sure TIM2 Counter start from zero
TIM_Cmd(TIM2, ENABLE);              // Enalbe TIM2
while(TIM_GetCounter(TIM2) < ms);   // Wait ms Miliseconds
TIM_Cmd(TIM2, DISABLE);
}

int main(void)
{
InitializeLEDs();
InitializeTimer();
    while(1)
    {
        GPIO_SetBits(GPIOD, GPIO_Pin_12);
        delay_ms(500);
        GPIO_ResetBits(GPIOD, GPIO_Pin_12);
        delay_ms(500);
    }
}

Aquí está el resultado:

    
pregunta Walid Amehri

2 respuestas

0

Quieres aprender a usar esos códigos generados automáticamente. Modificarlos requiere una buena comprensión de cómo funciona.

En cuanto a su código, lea el manual sobre cómo funcionan esas funciones, junto con la hoja de datos. Preste especial atención a qué variable es de 16 o 32 bits para que los valores dados a esas funciones no se desborden.

Por último, escribe tu código para que haga lo que quieres hacer. Por ejemplo, para producir un retardo de 0 5s en un reloj de 84 mhz se necesitan 42 millones de ciclos, que se desglosarán entre el prescaler y el registro de recarga. Puedes averiguar cuáles deberían ser los valores correctos.

Basta con decir que lo que tienes no está bien.

    
respondido por el dannyf
1

El registro prescalar del temporizador es solo de 16 bits, por lo que cuando intenta cargar el valor de (84000-1) = 83999, el valor que realmente carga es 83999-65536 = 18463. Por lo tanto, divide el reloj de 84000 MHz entre 18464 produciendo un recuento de 4.549 KHz en lugar de uno de 1 KHz.

Esto provoca que su intento de 500 milisegundos de demora sea 4.549 veces más rápido de lo previsto, lo que resulta en un intervalo de aproximadamente 110 milisegundos.

Es posible que desee considerar el uso del temporizador de systick para la temporización, o el cálculo con un intervalo de tiempo de hardware más pequeño (quizás de 5 KHz exactamente), o tal vez incluso dividir el reloj en sentido ascendente de los temporizadores si solo desea reducir el tiempo. eventos.

En este caso, puede ejecutar el PLL en un multiplicador diferente para producir un reloj del sistema más lento, si no tiene necesidad de realizar un procesamiento rápido. Esto también ahorrará energía.

    
respondido por el Chris Stratton

Lea otras preguntas en las etiquetas