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
 
This discussion is locked. Please start a new topic to ask your question.
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)

waclawek.jan
Super User

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