cancel
Showing results for 
Search instead for 
Did you mean: 

need a simple loaded timer example using an external signal

jhanc.11
Senior

Hi, I've been looking at timer examples for days and can't seem to find what I need. If I find something, then the interrupt routine isn't listed, for example.

I have a precise 2.5Mhz signal that I want to count 25,000 times and then overflow. I don't need the number of overflows, just the current count. When it overflows I want the 25,000 counter time reloaded. The board I am using, STM32F769-DISCO has TIM3_CH3 exposed on GPIO C8. I went into cube and set it all up, at least I thought I did, but I can't find where cube initializes GPIO C8. The counter looks correct. I put a signal into C8 and it fires exactly once.

I tried starting the timer using   HAL_TIM_Base_Start_IT(&htim3); That fires the interrupt void TIM3_IRQHandler(void) once. In the interrupt, I had planed to increment a counter and then on overflow, reset it, or better yet, since the timer must be counting up by itself (to know when to reload) I was thinking I shouldn't have to do anything in the routine, just read the counter possibly using __HAL_TIM_GetCounter(&htim3);

Do I have to clear the interrupt? If you could point me to a complete example, I'd appreciate it. I've read thru the timer cookbook but the examples quickly get much more complicated than needed.

Thanks,

Jerry

1 REPLY 1
jhanc.11
Senior

I regenerated this in cube and used the pin that came up in the tim3 GPIO section instead of the one I was trying to use, and it seems to be working, albeit strangely.

1) I can't find where cube generated the GPIO settings to config the pin, PA6.

2) My interrupt routine should be counting up as below. Instead, it looks like this routine is only called on overflow because PulseCnt increments at that time. PulseCnt is declared as an extern, though it doesn't matter.

void TIM3_IRQHandler(void)
{
  PulseCnt++;
  HAL_TIM_IRQHandler(&htim3);
}

In my code, I read the counter as such below:     Counter = __HAL_TIM_GetCounter(&htim3);  This is returning 2 counts for every pulse for some reason. I have the GPIO for the LED on GPIO_PIN_12 wired to the TIM3_CH3 signal input signal. That pulse goes up and down only once and I thought the clock was configured for "rising" but since I can't find the GPIO definition (too long to post here), for that pin, it must be defaulting. Consequently. it counts up from zero by 2,4,6,8,10 then it hits 10 (I have that as the reload) and when it trips to 11, it resets and goes to 1 because it has that exra pulse left over. Then it counts up by 2 from 1 to 3,5,7,9, 11, resets to 0 and counts up as 0,2,4,6,8,10, and around again.

  while (1) {
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_12, GPIO_PIN_RESET);  // turn off LED
HAL_Delay(500);
Counter = __HAL_TIM_GetCounter(&htim3);      // read counter
      if(PulseCnt<10){
        HAL_GPIO_WritePin(GPIOA, GPIO_PIN_12, GPIO_PIN_SET);   // turn on LED
        HAL_Delay(500);
        }
  HAL_UART_Transmit(&huart1,rxData,sizeof(rxData),1000);          // send constant msg
  sprintf(&outBuffer,"%ld\n",PulseCnt);
  for(x =0; x<30;x++) if (outBuffer[x]==0x0A) break;                 // count chars until \n
  HAL_UART_Transmit(&huart1,outBuffer,x+1,1000);              // xmit chars with count \n
  HAL_Delay(100);
  }

This has an interesting effect of giving me both the overflow count as well as the count, which is handy. Here's the timer config:

static void MX_TIM3_Init(void)
{
  TIM_SlaveConfigTypeDef sSlaveConfig = {0};
  TIM_MasterConfigTypeDef sMasterConfig = {0};
  TIM_IC_InitTypeDef sConfigIC = {0};
 
  htim3.Instance = TIM3;
  htim3.Init.Prescaler = 0;
  htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim3.Init.Period = 10;
  htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_Base_Init(&htim3) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_TIM_IC_Init(&htim3) != HAL_OK)
  {
    Error_Handler();
  }
  sSlaveConfig.SlaveMode = TIM_SLAVEMODE_EXTERNAL1;
  sSlaveConfig.InputTrigger = TIM_TS_TI1F_ED;
  sSlaveConfig.TriggerFilter = 0;
  if (HAL_TIM_SlaveConfigSynchro(&htim3, &sSlaveConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING;
  sConfigIC.ICSelection = TIM_ICSELECTION_TRC;
  sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;
  sConfigIC.ICFilter = 0;
  if (HAL_TIM_IC_ConfigChannel(&htim3, &sConfigIC, TIM_CHANNEL_3) != HAL_OK)
  {
    Error_Handler();
  }
}

Here's the weird thing, note from the tim3 config above that it reads TIM_CHANNEL_3 at the bottom. Ch3 is my Pin, PC8 that I configured. I am not plugged into that pin, I am plugged into the CH1 pin that Cube insisted on using. I wanted to use CH3 PC8 (ARD_D5 on this board as it has arduino connectors) and CH3, that cube wouldn't let me change the GPIO settings in the TIM3 module. It wanted to use PC6, ADC1_IN6 which is TIM3_CH1 and that pin works fine.

So, why is it using the channel CH1 pin that I had disabled? Why is it counting twice for every pulse up and down (default?). I'm going to change that code at the bottom to the pin cube used to see if it takes the "rising" from it. Now I just have to figure out why usart1 isn't working at all.

Thanks

Jerry