STM32F7 46 G Descubrimiento configurando TIM2 a 1 segundo

0

Estoy aprendiendo a programar en una tarjeta de descubrimiento STM32F7 46 G usando Eclipse como IDE y STM32CubeMX. Estoy intentando configurar un temporizador (actualmente TIM2) a un segundo sin usar un ISR. Me gustaría recibir un tick del temporizador cada segundo.

A continuación se muestra lo que intenté hasta ahora:

#include "main.h"
#include "stm32f7xx_hal.h"  

/* Private variables ---------------------------------------------------------*/
TIM_HandleTypeDef htim2;

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_TIM2_Init(void);
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim);    

int main(void)
{
    HAL_Init();
    SystemClock_Config(); 
    MX_GPIO_Init();
    MX_TIM2_Init();
    __TIM2_CLK_ENABLE();

   while (1)
   {
       HAL_TIM_PeriodElapsedCallback(&htim2);
   }
}

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim2)
{
    if (htim2->Instance==TIM2) //check if the interrupt comes from TIM2
        {
           HAL_GPIO_TogglePin(ARDUINO_D2_GPIO_Port,ARDUINO_D2_Pin);
        }
}

static void MX_TIM2_Init(void) /* TIM2 init function */
{
  TIM_ClockConfigTypeDef sClockSourceConfig;
  TIM_MasterConfigTypeDef sMasterConfig;

  htim2.Instance = TIM2;
  htim2.Init.Prescaler = 41999; //max 65 536
  htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim2.Init.Period = 1999;
  htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim2.Init.AutoReloadPreload = 0;
  HAL_TIM_Base_Init(&htim2);
  HAL_TIM_Base_Start(&htim2);

  if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;

  if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;


   if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
      {
        _Error_Handler(__FILE__, __LINE__);
      }
}

Sé que la MCU funciona a 42MHz, lo que finalmente hace que el reloj funcione a 84MHz con PLL y creo que ya configuré los valores de Prescaler y Period (para corregir el tiempo de carga automática) en consecuencia.

Gracias por responder y perdón por cualquier error en inglés (no es mi primer idioma)

    

2 respuestas

2

No necesita llamar a la función HAL_TIM_PeriodElapsedCallback () en el bucle while (1). ¡Porque funciona en modo no bloqueante! En su lugar, puedes hacer algo como esto si quieres cambiar el led cada segundo.

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
   /*Include channel assertion as you did above */
   HAL_GPIO_TogglePin(ARDUINO_D2_GPIO_Port,ARDUINO_D2_Pin);
}

Simplemente puede eliminar la llamada de la función de devolución de llamada en main ().

No creo que necesites habilitar el reloj por separado en la función main (). Se habilitará en el archivo * _hal_msp.c. Verifique que la función "HAL_TIM_Base_MspInit (TIM_HandleTypeDef * htim)" se haya inicializado en el archivo * _hal_msp.c en la carpeta ./Src.

La configuración de tu temporizador se ve bien para mí, pero para que la configuración de Timer_Clock sea precisa, calcula el valor de Prescaler a partir del valor de SystemCoreClock.

y finalmente, si desea activar una interrupción o crear ISR por cada 1 segundo, simplemente puede usar "HAL_TIM_Base_Start_IT ()".

Edit: Entonces, jugué un poco con él y ejecuté con éxito su programa en mi tablero STM32E407 y aquí es el enlace! Mi observación es que debes iniciar TIME_BASE en modo de interrupción, es decir, incluir

  /*##-2- Start the TIM Base generation in interrupt mode **/ 
  if(HAL_TIM_Base_Start_IT(&TimHandle) != HAL_OK)
  {
     /* Starting Error */
     _Error_Handler(__FILE__, __LINE__);
   }

e inicie TIM2_IRQHandler () en * _it.c e incluya la prioridad de NVIC en * hal_msp.c.

Incluso no conozco en particular la razón por la cual tiene que usar el modo de interrupción. Pero supongo que la función de devolución de llamada está relacionado con ISR .

Edit2: ¡Sí! Compruebe * _tim.c en la biblioteca stdPheripharal. La función PeriodElapsedCallback se llama solo en HAL_TIM_IRQHandler (). Entonces, sin usar el controlador de interrupción, la función de devolución de llamada no devuelve nada.

    
respondido por el charansai
1

Finalmente resolví mi problema. Tres puntos estaban equivocados:

  • Según lo sugerido por Charansai, la función de devolución de llamada no debe ser no en el bucle mientras que (1) (aquí permanece vacío)
  • La línea HAL_TIM_Base_Start_IT(&htim2); debe agregarse
  • La devolución de llamada debe colocarse antes de the main ()

Al final, el código se ve así:

/* Includes     ---------------------------------------------------------*/
#include "main.h"
#include "stm22f7xx_hal.h"

/*Private variables ---------------------------------------------------------*/
TIM_HandleTypeDef htim2;

/*Protypes  ---------------------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_TIM2_Init(void);
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)  ;

/*Private functions ---------------------------------------------------------*/
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    if (htim->Instance==TIM2) //check if the interrupt comes from TIM2
        {
             HAL_GPIO_TogglePin(ARDUINO_D2_GPIO_Port,ARDUINO_D2_Pin);
        }
}

int main(void)
{
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_TIM2_Init();

  HAL_TIM_Base_Start_IT(&htim2);

  while (1)
  {
  }
}

/* TIM2 init function */
static void MX_TIM2_Init(void)
{
  TIM_ClockConfigTypeDef sClockSourceConfig;
  TIM_MasterConfigTypeDef sMasterConfig;

  htim2.Instance = TIM2;
  htim2.Init.Prescaler = 41999;
  htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim2.Init.Period = 1999;
  htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;

  if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

Gracias por responder y resaltar algunos problemas

    
respondido por el Valentin CHOUETTE

Lea otras preguntas en las etiquetas