cancel
Showing results for 
Search instead for 
Did you mean: 

is there a sample code showing how to count external events on a STM32F429I discovery (using timer 3)? Thanks, Piero

Hicss.2033
Associate III
 
1 ACCEPTED SOLUTION

Accepted Solutions
// STM32F429I-DISCO TIM3 (CH1 PA6) External Count Demo - sourcer32@gmail.com
 
#include "stm32f429i_discovery.h"
 
//****************************************************************************
 
void GPIO_Configuration(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
 
  /* GPIOA clock enable */
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
 
  /*  pin configuration */
  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_DOWN;
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
 
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource6,  GPIO_AF_TIM3); // PA6 TIM3_CH1
}
 
//****************************************************************************
 
void TIM3_Configuration(void)
{
  TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
  int i;
 
  /* Enable TIM3 Peripheral clock */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
 
  TIM_TimeBaseStructure.TIM_Prescaler = 0;
  TIM_TimeBaseStructure.TIM_Period = 100 - 1; // 100 (16-bit counter)
  TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
 
  TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
 
  TIM_TIxExternalClockConfig(TIM3, TIM_TIxExternalCLK1Source_TI1, TIM_ICPolarity_Rising, 0);
 
  TIM_Cmd(TIM3, ENABLE);
 
  // Likely will interrupt initially unless we clear it
 
  for(i=0; i<3; i++)
    if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)
      TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
 
  TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);
 
  // Could also use compare mode, set the counter maximal and advance CCRx 100 ticks at a time
}
 
//****************************************************************************
 
void TIM3_IRQHandler(void)
{
  if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)
  {
    TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
 
    /* Toggle LED3 */
    STM_EVAL_LEDToggle(LED3);
  }
}
 
//****************************************************************************
 
void NVIC_Configuration(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;
 
  /* Enable the TIM3 global Interrupt */
  NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}
 
//****************************************************************************
 
int main(void)
{
  /* Initialize Leds mounted on STM32F429I-DISCO board */
  STM_EVAL_LEDInit(LED3);
 
  /* Turn on LED3 */
  STM_EVAL_LEDOn(LED3);
 
  NVIC_Configuration();
 
  GPIO_Configuration();
 
  TIM3_Configuration();
 
  while(1); // Do not exit
}
 
//******************************************************************************
 
#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t* file, uint32_t line)
{
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
 
  /* Infinite loop */
  while (1)
  {
  }
}
#endif
 
//******************************************************************************

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..

View solution in original post

5 REPLIES 5
S.Ma
Principal

You should look at the corresponding Nucleo board examples, for timer and say input capture or external clock mode whichever closer to your needs.

// STM32F429I-DISCO TIM3 (CH1 PA6) External Count Demo - sourcer32@gmail.com
 
#include "stm32f429i_discovery.h"
 
//****************************************************************************
 
void GPIO_Configuration(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
 
  /* GPIOA clock enable */
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
 
  /*  pin configuration */
  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_DOWN;
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
 
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource6,  GPIO_AF_TIM3); // PA6 TIM3_CH1
}
 
//****************************************************************************
 
void TIM3_Configuration(void)
{
  TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
  int i;
 
  /* Enable TIM3 Peripheral clock */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
 
  TIM_TimeBaseStructure.TIM_Prescaler = 0;
  TIM_TimeBaseStructure.TIM_Period = 100 - 1; // 100 (16-bit counter)
  TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
 
  TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
 
  TIM_TIxExternalClockConfig(TIM3, TIM_TIxExternalCLK1Source_TI1, TIM_ICPolarity_Rising, 0);
 
  TIM_Cmd(TIM3, ENABLE);
 
  // Likely will interrupt initially unless we clear it
 
  for(i=0; i<3; i++)
    if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)
      TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
 
  TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);
 
  // Could also use compare mode, set the counter maximal and advance CCRx 100 ticks at a time
}
 
//****************************************************************************
 
void TIM3_IRQHandler(void)
{
  if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)
  {
    TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
 
    /* Toggle LED3 */
    STM_EVAL_LEDToggle(LED3);
  }
}
 
//****************************************************************************
 
void NVIC_Configuration(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;
 
  /* Enable the TIM3 global Interrupt */
  NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}
 
//****************************************************************************
 
int main(void)
{
  /* Initialize Leds mounted on STM32F429I-DISCO board */
  STM_EVAL_LEDInit(LED3);
 
  /* Turn on LED3 */
  STM_EVAL_LEDOn(LED3);
 
  NVIC_Configuration();
 
  GPIO_Configuration();
 
  TIM3_Configuration();
 
  while(1); // Do not exit
}
 
//******************************************************************************
 
#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t* file, uint32_t line)
{
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
 
  /* Infinite loop */
  while (1)
  {
  }
}
#endif
 
//******************************************************************************

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
Hicss.2033
Associate III

thanks for yor reply

I thanks for your reply, but I'm using the HAL library on system workbench (I don't know which is the reference library of your example)

My take. No library.

// https://community.st.com/s/question/0D53W00000COHcsSAH/is-there-a-sample-code-showing-how-to-count-external-events-on-a-stm32f429i-discovery-using-timer-3-thanks-piero
// wek at efton dot sk
 
#include "stm32f4xx.h"
 
// 'F429 DISCO
// GREEN_LED  PG13
// RED_LED    PG14
#define GREEN_LED_PORT   GPIOG
#define GREEN_LED_PIN    13
 
#define RED_LED_PORT     GPIOG
#define RED_LED_PIN      14
 
 
 
// ------- defines missing from the device header -- normally I have the complete collection in a separate header, this is just to keep things in one file
 
  // GPIOx_MODER - 2 bits per pin
#define GPIO_Mode_In                         0x00  // GPIO Input Mode
#define GPIO_Mode_Out                        0x01  // GPIO Output Mode
#define GPIO_Mode_AlternateFunction          0x02  // GPIO Alternate function Mode
#define GPIO_Mode_AF                         GPIO_Mode_AlternateFunction
#define GPIO_Mode_Analog                     0x03  // GPIO Analog Mode
 
#define GPIO_PullNone                        0x00
#define GPIO_PullUp                          0x01
#define GPIO_PullDown                        0x02
 
#define GPIO_AlternateFunction_TIM3       2
 
#define SHL <<
#define AND &
#define PIN_SET(pin)   pin##_PORT->BSRR = (1 SHL (pin##_PIN + 0))
#define PIN_CLR(pin)   pin##_PORT->BSRR = (1 SHL (pin##_PIN + 16))
#define PIN_GET(pin)   ((pin##_PORT->IDR AND (1 SHL pin##_PIN)) ? 1 : 0)
 
 
#define  TIM_CCMR_CCS__INPUT_TI1             1  // CC unit in capture mode, input from "own" pin (i.e. TI1 for CC1, TI2 for CC2, TI3 for CC3, TI4 for CC4)
 
#define  TIM_SMCR_TS__TI1FP1                 5  // TI1FP1 with the same polarity as if CH1 used for capturing in CC1
 
#define  TIM_SMCR_SMS__EXT_CLK_1             7
 
#define  TIM_CCMR_ICF__32_8S                 15 // input filter - 8 samples, sampled by fDTS/32
 
 
// -------- utils/frameworks
// trivial loopdelay
static void LoopDelay(volatile uint32_t n) {
	while(n > 0) n--;
}
 
#define DELAY_CONSTANT 1000000
 
 
 
// ---------------------------- MAIN ------------------------------
int main(void) {
 
  RCC->AHB1ENR |= 0
    | RCC_AHB1ENR_GPIOAEN   // let's enable all GPIOs, we are going to use them all anyway, and don't plan to spare power significantly, so what
    | RCC_AHB1ENR_GPIOBEN
    | RCC_AHB1ENR_GPIOCEN
    | RCC_AHB1ENR_GPIODEN
    | RCC_AHB1ENR_GPIOEEN
    | RCC_AHB1ENR_GPIOFEN
    | RCC_AHB1ENR_GPIOGEN
    | RCC_AHB1ENR_GPIOHEN
  ;
  RCC->APB1ENR |= 0
    | RCC_APB1ENR_TIM3EN
  ;
 
 
 
  GPIOA->MODER = (GPIOA->MODER  // assuming reset value
  ) | (0
    | (GPIO_Mode_AF  * GPIO_MODER_MODER6_0)   // PA6 - TIM3_CH1
  );
  GPIOA->AFR[0] = 0  // AFRL
    | (GPIO_AlternateFunction_TIM3 * GPIO_AFRL_AFRL6_0)  // PA6 - TIM3_CH1
  ;
  GPIOA->PUPDR = GPIOA->PUPDR
    | (GPIO_PullUp  * GPIO_PUPDR_PUPDR6_0)   // pulled up, so can wiggle it by pulling it to GND
  ;
  // PA6 is input so no need for OSPEEDR setting
 
  GPIOG->MODER = (GPIOG->MODER
  ) | (0
    | (GPIO_Mode_Out  * GPIO_MODER_MODER13_0)   // GREEN_LED
    | (GPIO_Mode_Out  * GPIO_MODER_MODER14_0)   // RED_LED
  );
  // LEDs don't need to change OSPEEDR nor any other GPIO register
 
 
  // now setup TIM3 for the external counter
  // leave PSC and ARR at their defaults
  TIM3->CCMR1 = 0
    | (TIM_CCMR_CCS__INPUT_TI1 * TIM_CCMR1_CC1S_0)  // input capture from "its own" pin
    | (TIM_CCMR_ICF__32_8S     * TIM_CCMR1_IC1F_0)  // set the heaviest filtering here, as we are going to wiggle the pin using a loose wire
  ;
  TIM3->CCER = 0
    | (1 * TIM_CCER_CC1E)  // enable TIM1_CH1
  ;
  TIM3->SMCR = 0
    | (TIM_SMCR_TS__TI1FP1     * TIM_SMCR_TS_0)    // select TI1FP1 (filtered CH1) as TRGI source
    | (TIM_SMCR_SMS__EXT_CLK_1 * TIM_SMCR_SMS_0)   // and set external clock mode for slave controller
  ;
  TIM3->CR1  = 0
    | (1 * TIM_CR1_CEN)   // enable counter
  ;
 
  // for the laughs, enable interrupt from the capture
  TIM3->DIER = 0
    | (1 * TIM_DIER_CC1IE)  // enable interrupt from CC1
  ;
  NVIC_EnableIRQ(TIM3_IRQn);
 
 
 
  while(1) {
    PIN_SET(RED_LED);
    LoopDelay(DELAY_CONSTANT);
    PIN_CLR(RED_LED);
    LoopDelay(DELAY_CONSTANT);
    __asm("nop");
  }
}
 
 
// interrupt handler
 
void TIM3_IRQHandler(void) {
  uint32_t sr;
 
  sr = TIM3->SR;
  TIM3->SR = ~sr;  // clear flags
 
  if (sr & TIM_SR_CC1IF) {
    if (PIN_GET(GREEN_LED)) {
      PIN_CLR(GREEN_LED);
    } else {
      PIN_SET(GREEN_LED);
    }
  }
}

JW