2018-04-10 11:15 AM
Hello,
I am using STM32F429ZI, I would like to use timer 3 to generate a timer with high resolution something like 4000Hz My Timer 3 setting is following:
static void MX_TIM3_Init(void)
{TIM_ClockConfigTypeDef sClockSourceConfig;
TIM_MasterConfigTypeDef sMasterConfig;htim3.Instance = TIM3;
htim3.Init.Prescaler = 419; htim3.Init.CounterMode = TIM_COUNTERMODE_UP; htim3.Init.Period =49; htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; htim3.Init.RepetitionCounter=0; if (HAL_TIM_Base_Init(&htim3) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); }sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); }sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); }}
I use global interrupt event TIM3_IRQHandler to handle event update
void TIM3_IRQHandler(void)
{ /* USER CODE BEGIN TIM3_IRQn 0 *//* USER CODE END TIM3_IRQn 0 */
HAL_TIM_IRQHandler(&htim3); /* USER CODE BEGIN TIM3_IRQn 1 */printf('timer 3 update: %d\n',timer_counter);
if (timer_counter>=10000)
{ HAL_TIM_Base_Stop_IT(&htim3); } else { HAL_GPIO_TogglePin(NOMIGBT_GPIO_PORT,NOMIGBT_PIN); __HAL_TIM_CLEAR_FLAG(&htim3,TIM_IT_UPDATE);timer_counter++;
}/* USER CODE END TIM3_IRQn 1 */
}I trigger digital output to verify my timer. It looks my timer locked by 3Hz. Does anybody knows what is happen?
Thank you so much.
2018-04-10 02:29 PM
- verify your system clock is set as you expect, outputting it to MCO
- read out and check/post the timer registers content
JW
2018-04-11 02:17 PM
Hello,
I did some bug and get system clock information as followed:
Do you think it is ok?
2018-04-11 02:17 PM
You are doing a slow task (print) from within the isr.
Make the isr as short as possible and see where you go from there.
2018-04-11 02:31 PM
I don't know. There are too many things that may go wrong between setting a structure and actually having the regsiters set up - including the oscillator may be running or not.
Why don't you output the system clock onto a MCO pin, and measure it? That's a sure way to know what is its frequency.
JW
2018-04-13 11:21 AM
Hello,
I have simplified the isq code, so now only toggle output, it looks faster now, but it is still slower than what I want. I did some calculations, for example, prescale=29 and autoload=30, I got 8.5khz output, so it looks I have 8MHz timer clock. it is pretty strange because I thought I should have APB1 (84MHz). I am using NUCLEO-F429ZI and I use STM32CUBEMX to generate a code for my demo project.
I read systme clock, hclk, pclk1 and pclk2 frequency. all of them are 16M.
I attach my system clock code below:
void SystemClock_Config(void)
{RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_ClkInitTypeDef RCC_ClkInitStruct;/**Configure the main internal regulator output voltage
*/ __HAL_RCC_PWR_CLK_ENABLE();__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
/**Initializes the CPU, AHB and APB busses clocks
*/ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = 16; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLM = 8; RCC_OscInitStruct.PLL.PLLN = 168; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; RCC_OscInitStruct.PLL.PLLQ = 7; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); return ; }/**Initializes the CPU, AHB and APB busses clocks
*/ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
{ _Error_Handler(__FILE__, __LINE__); return; }/**Configure the Systick interrupt time
*/ HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);/**Configure the Systick
*/ HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);/* SysTick_IRQn interrupt configuration */
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);}
void TIM3_IRQHandler(void)
{ TIM3->SR &= ~(TIM_SR_UIF); NOMIGBT_GPIO_PORT->ODR ^= NOMIGBT_PIN;}
What I want is to set one timer for 1 micro second interval (this interval is the best I want, of course, if it is impossible, I can have 10 micro second or 5 micro second), every 1 micro second to trigger interrupt timer event, then according to preset timing to trigger on/off some digital outputs. Do I need use assemble program for fast irq event?
2018-04-13 12:02 PM
Sure, so long as you make sure that the isr is quick and short.
2018-04-13 12:42 PM
right now, I only have 1/10 interrupt frequency I need, for example, I suppose to have 600Hz, I only get 60Hz, my sysclk, hclk, plclk1, and plclk2 are the same value, 160M. Do you think it is correct?
2018-04-13 01:05 PM
If your system clock is 160Mhz and you want to get 600hz interrupt, use a Pressler to decide down the clock and then set the period or output match.
So take a look at your timer and pick the right Pressler and period register or compare register and go from there.
2018-04-13 02:47 PM
Hello,
Thank you for your reply. I regenerate code from stm32cubemax, it seems working now.