cancel
Showing results for 
Search instead for 
Did you mean: 

TIM2/TIM5 works but same code does not work for any other timers

jlaufer
Associate II

I am using STM32F4 and I am trying to create 8 independent pulse outputs. I have chosen 8 timers looking at the STM32F4 Discovery datasheet and mapped them to pins. I have code for TIM2 and TIM5 that works perfectly. I change the pulse and the frequency changes. I use the exact same code for the other timers except modified for the new timer, but these other timers once started just produce an unchanging pulse frequency regardless of what I initialize the pulse parameter to.

 

I'm really struggling to get this to work and don't understand what I am doing wrong, any help is appreciated.

 

int main(void)
{
	HAL_Init();

	SystemClock_Config(SYS_CLOCK_FREQ_48_MHZ);

	uint32_t clk_freq = Get_PCLK1TIM();

	UART2_Init();

	while (1)
	{
		HAL_UART_Receive_IT(&huart2, &recvd_data, 1);

		if (reception_complete == TRUE){
			Decode_MODBUS();
		}

		//  Check and see if there has been any updates to the register values
		for(uint8_t motor = 0; motor < NUM_MOTORS; motor++) {

			if (reg_changed[motor])
			{
				// pulse = clk_spd * (1 /(2*freq))
				double pulse_freq_float = (double)registers[motor];
				double pulse_float = ((double)clk_freq * (double)pump_speed_scale_factor) / (4.0 * pulse_freq_float); // 4 comes from (prescalar + 1) * 2 ... 2 for rising/falling edge
				pulse[motor] = (uint32_t)pulse_float;

				// Initialize the timer based on the frequency given by the user
				switch(motor) {

					case 0:
						TIMER5_Init();
						//Start the timer
						if(HAL_TIM_OC_Start_IT(&htimer5, TIM_CHANNEL_2) != HAL_OK)
						{
							Error_handler();
						}
						reg_changed[motor] = FALSE;
						break;

					case 1:
						TIMER2_Init();
						//Start the timer
						if(HAL_TIM_OC_Start_IT(&htimer2, TIM_CHANNEL_1) != HAL_OK)
						{
							Error_handler();
						}
						reg_changed[motor] = FALSE;
						break;

					case 2:
						TIMER3_Init();
						//Start the timer
						if(HAL_TIM_OC_Start_IT(&htimer3, TIM_CHANNEL_1) != HAL_OK)
						{
							Error_handler();
						}
						reg_changed[motor] = FALSE;
						break;

					case 3:
						TIMER14_Init();
						//Start the timer
						if(HAL_TIM_OC_Start_IT(&htimer14, TIM_CHANNEL_1) != HAL_OK)
						{
							Error_handler();
						}
						reg_changed[motor] = FALSE;
						break;

					case 4:
						TIMER1_Init();
						//Start the timer
						if(HAL_TIM_OC_Start_IT(&htimer1, TIM_CHANNEL_1) != HAL_OK)
						{
							Error_handler();
						}
						reg_changed[motor] = FALSE;
						break;

					case 5:
						TIMER4_Init();
						//Start the timer
						if(HAL_TIM_OC_Start_IT(&htimer4, TIM_CHANNEL_3) != HAL_OK)
						{
							Error_handler();
						}
						reg_changed[motor] = FALSE;
						break;

					case 6:
						TIMER11_Init();
						//Start the timer
						if(HAL_TIM_OC_Start_IT(&htimer11, TIM_CHANNEL_1) != HAL_OK)
						{
							Error_handler();
						}
						reg_changed[motor] = FALSE;
						break;

					case 7:
						TIMER9_Init();
						//Start the timer
						if(HAL_TIM_OC_Start_IT(&htimer9, TIM_CHANNEL_1) != HAL_OK)
						{
							Error_handler();
						}
						reg_changed[motor] = FALSE;
						break;
				}
			}
		}
	}
}

void TIMER5_Init()
{
	TIM_OC_InitTypeDef tim5OC_init;
	htimer5.Instance = TIM5;
	htimer5.Init.Period = 0xFFFFFFFF;
	htimer5.Init.Prescaler = 1;
	if (HAL_TIM_OC_Init(&htimer5) != HAL_OK)
	{
		Error_handler();
	}

	tim5OC_init.OCMode = TIM_OCMODE_TOGGLE;
	tim5OC_init.OCPolarity = TIM_OCPOLARITY_HIGH;
	tim5OC_init.Pulse  = pulse[0];
	if(HAL_TIM_OC_ConfigChannel(&htimer5,&tim5OC_init,TIM_CHANNEL_2) != HAL_OK)
	{
		Error_handler();
	}
}

void TIMER2_Init()
{
	TIM_OC_InitTypeDef tim2OC_init;
	htimer2.Instance = TIM2;
	htimer2.Init.Period = 0xFFFFFFFF;
	htimer2.Init.Prescaler = 1;
	if (HAL_TIM_OC_Init(&htimer2) != HAL_OK)
	{
		Error_handler();
	}

	tim2OC_init.OCMode = TIM_OCMODE_TOGGLE;
	tim2OC_init.OCPolarity = TIM_OCPOLARITY_HIGH;
	tim2OC_init.Pulse  = pulse[1];
	if(HAL_TIM_OC_ConfigChannel(&htimer2,&tim2OC_init,TIM_CHANNEL_1) != HAL_OK)
	{
		Error_handler();
	}
}

void TIMER3_Init()
{
	TIM_OC_InitTypeDef tim3OC_init;
	htimer3.Instance = TIM3;
	htimer3.Init.Period = 0xFFFFFFFF;
	htimer3.Init.Prescaler = 1;
	if (HAL_TIM_OC_Init(&htimer3) != HAL_OK)
	{
		Error_handler();
	}

	tim3OC_init.OCMode = TIM_OCMODE_TOGGLE;
	tim3OC_init.OCPolarity = TIM_OCPOLARITY_HIGH;
	tim3OC_init.Pulse  = pulse[2];
	if(HAL_TIM_OC_ConfigChannel(&htimer3,&tim3OC_init,TIM_CHANNEL_1) != HAL_OK)
	{
		Error_handler();
	}
}

void TIMER14_Init()
{
	TIM_OC_InitTypeDef tim14OC_init;
	htimer14.Instance = TIM14;
	htimer14.Init.Period = 0xFFFFFFFF;
	htimer14.Init.Prescaler = 1;
	if (HAL_TIM_OC_Init(&htimer14) != HAL_OK)
	{
		Error_handler();
	}

	tim14OC_init.OCMode = TIM_OCMODE_TOGGLE;
	tim14OC_init.OCPolarity = TIM_OCPOLARITY_HIGH;
	tim14OC_init.Pulse  = pulse[3];
	if(HAL_TIM_OC_ConfigChannel(&htimer14,&tim14OC_init,TIM_CHANNEL_1) != HAL_OK)
	{
		Error_handler();
	}
}

void TIMER1_Init()
{
	TIM_OC_InitTypeDef tim1OC_init;

	// Enable the Main Output (required for advanced timers)
	TIM1->CCER |= TIM_CCER_CC1E_Msk;
	TIM1->BDTR |= TIM_BDTR_MOE;
	TIM1->CR1 |= TIM_CR1_CEN;

	htimer1.Instance = TIM1;
	htimer1.Init.Period = 0xFFFFFFFF;
	htimer1.Init.Prescaler = 1;
	if (HAL_TIM_OC_Init(&htimer1) != HAL_OK)
	{
		Error_handler();
	}

	tim1OC_init.OCMode = TIM_OCMODE_TOGGLE;
	tim1OC_init.OCPolarity = TIM_OCPOLARITY_HIGH;
	tim1OC_init.Pulse  = pulse[4];



	if(HAL_TIM_OC_ConfigChannel(&htimer1,&tim1OC_init,TIM_CHANNEL_1) != HAL_OK)
	{
		Error_handler();
	}
}

void TIMER4_Init()
{
	TIM_OC_InitTypeDef tim4OC_init;
	htimer4.Instance = TIM4;
	htimer4.Init.Period = 0xFFFFFFFF;
	htimer4.Init.Prescaler = 1;
	if (HAL_TIM_OC_Init(&htimer4) != HAL_OK)
	{
		Error_handler();
	}

	tim4OC_init.OCMode = TIM_OCMODE_TOGGLE;
	tim4OC_init.OCPolarity = TIM_OCPOLARITY_HIGH;
	tim4OC_init.Pulse  = pulse[5];
	if(HAL_TIM_OC_ConfigChannel(&htimer4,&tim4OC_init,TIM_CHANNEL_3) != HAL_OK)
	{
		Error_handler();
	}
}

void TIMER11_Init()
{
	TIM_OC_InitTypeDef tim11OC_init;
	htimer11.Instance = TIM11;
	htimer11.Init.Period = 0xFFFFFFFF;
	htimer11.Init.Prescaler = 1;
	if (HAL_TIM_OC_Init(&htimer11) != HAL_OK)
	{
		Error_handler();
	}

	tim11OC_init.OCMode = TIM_OCMODE_TOGGLE;
	tim11OC_init.OCPolarity = TIM_OCPOLARITY_HIGH;
	tim11OC_init.Pulse  = pulse[6];
	if(HAL_TIM_OC_ConfigChannel(&htimer11,&tim11OC_init,TIM_CHANNEL_1) != HAL_OK)
	{
		Error_handler();
	}
}

void TIMER9_Init()
{
	TIM_OC_InitTypeDef tim9OC_init;
	htimer9.Instance = TIM9;
	htimer9.Init.Period = 0xFFFFFFFF;
	htimer9.Init.Prescaler = 1;
	if (HAL_TIM_OC_Init(&htimer9) != HAL_OK)
	{
		Error_handler();
	}

	tim9OC_init.OCMode = TIM_OCMODE_TOGGLE;
	tim9OC_init.OCPolarity = TIM_OCPOLARITY_HIGH;
	tim9OC_init.Pulse  = pulse[7];
	if(HAL_TIM_OC_ConfigChannel(&htimer9,&tim9OC_init,TIM_CHANNEL_1) != HAL_OK)
	{
		Error_handler();
	}
}


void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *htim)
{

	/* TIM2_CH2 toggling with frequency = 500 Hz */
	TIM_TypeDef *timer = htim->Instance;

	if (timer == TIM5)
	{
		if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2)
		{
			ccr_content = HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_2);
			__HAL_TIM_SET_COMPARE(htim,TIM_CHANNEL_2,ccr_content+pulse[0]);
		}
	}
	else if (timer == TIM2)
	{
		if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)
		{
			ccr_content = HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_1);
			__HAL_TIM_SET_COMPARE(htim,TIM_CHANNEL_1,ccr_content+pulse[1]);
		}
	}
	else if (timer == TIM3)
	{
		if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)
		{
			ccr_content = HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_1);
			__HAL_TIM_SET_COMPARE(htim,TIM_CHANNEL_1,ccr_content+pulse[2]);
		}
	}
	else if (timer == TIM14)
	{
		if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)
		{
			ccr_content = HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_1);
			__HAL_TIM_SET_COMPARE(htim,TIM_CHANNEL_1,ccr_content+pulse[3]);
		}
	}
	else if (timer == TIM1)
	{
		if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)
		{
			// for some unknown reason can't use the AF mode for advanced timers
			HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_8);
		}
	}
	else if (timer == TIM4)
	{
		if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_3)
		{
			ccr_content = HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_3);
			__HAL_TIM_SET_COMPARE(htim,TIM_CHANNEL_3,ccr_content+pulse[5]);
		}
	}
	else if (timer == TIM11)
	{
		if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)
		{
			ccr_content = HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_1);
			__HAL_TIM_SET_COMPARE(htim,TIM_CHANNEL_1,ccr_content+pulse[6]);
		}
	}
	else if (timer == TIM9)
	{
		if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)
		{
			ccr_content = HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_1);
			__HAL_TIM_SET_COMPARE(htim,TIM_CHANNEL_1,ccr_content+pulse[7]);
		}
	}
}

void HAL_TIM_OC_MspInit(TIM_HandleTypeDef *htim)
{
	GPIO_InitTypeDef tim5OC_ch_gpios;
	GPIO_InitTypeDef tim2OC_ch_gpios;
	GPIO_InitTypeDef tim3OC_ch_gpios;
	GPIO_InitTypeDef tim14OC_ch_gpios;
	GPIO_InitTypeDef tim1OC_ch_gpios;
	GPIO_InitTypeDef tim4OC_ch_gpios;
	GPIO_InitTypeDef tim11OC_ch_gpios;
	GPIO_InitTypeDef tim9OC_ch_gpios;

	//1. enable the peripheral clock for the timer2 peripheral
	__HAL_RCC_TIM5_CLK_ENABLE();
	__HAL_RCC_TIM2_CLK_ENABLE();
	__HAL_RCC_TIM3_CLK_ENABLE();
	__HAL_RCC_TIM14_CLK_ENABLE();
	__HAL_RCC_TIM1_CLK_ENABLE();
	__HAL_RCC_TIM4_CLK_ENABLE();
	__HAL_RCC_TIM11_CLK_ENABLE();
	__HAL_RCC_TIM9_CLK_ENABLE();
	__HAL_RCC_GPIOA_CLK_ENABLE();
	__HAL_RCC_GPIOB_CLK_ENABLE();
	__HAL_RCC_GPIOE_CLK_ENABLE();

	//2. Configure gpios to behave as timer2 channel 1,2,3 and 4
	// PA1 --> TIM2_CH2

	tim5OC_ch_gpios.Pin = GPIO_PIN_1;
	tim5OC_ch_gpios.Mode = GPIO_MODE_AF_PP;
	tim5OC_ch_gpios.Pull = GPIO_NOPULL;
	tim5OC_ch_gpios.Speed = GPIO_SPEED_FREQ_LOW;
	tim5OC_ch_gpios.Alternate = GPIO_AF2_TIM5;
	HAL_GPIO_Init(GPIOA, &tim5OC_ch_gpios);

	tim2OC_ch_gpios.Pin = GPIO_PIN_5;
	tim2OC_ch_gpios.Mode = GPIO_MODE_AF_PP;
	tim2OC_ch_gpios.Pull = GPIO_NOPULL;
	tim2OC_ch_gpios.Speed = GPIO_SPEED_FREQ_LOW;
	tim2OC_ch_gpios.Alternate = GPIO_AF1_TIM2;
	HAL_GPIO_Init(GPIOA, &tim2OC_ch_gpios);

	tim3OC_ch_gpios.Pin = GPIO_PIN_6;
	tim3OC_ch_gpios.Mode = GPIO_MODE_AF_PP;
	tim3OC_ch_gpios.Pull = GPIO_NOPULL;
	tim3OC_ch_gpios.Speed = GPIO_SPEED_FREQ_LOW;
	tim3OC_ch_gpios.Alternate = GPIO_AF2_TIM3;
	HAL_GPIO_Init(GPIOA, &tim3OC_ch_gpios);

	tim14OC_ch_gpios.Pin = GPIO_PIN_7;
	tim14OC_ch_gpios.Mode = GPIO_MODE_AF_PP;
	tim14OC_ch_gpios.Pull = GPIO_NOPULL;
	tim14OC_ch_gpios.Speed = GPIO_SPEED_FREQ_LOW;
	tim14OC_ch_gpios.Alternate = GPIO_AF9_TIM14;
	HAL_GPIO_Init(GPIOA, &tim14OC_ch_gpios);

	tim1OC_ch_gpios.Pin = GPIO_PIN_8;
	tim1OC_ch_gpios.Mode = GPIO_MODE_OUTPUT_PP;
	tim1OC_ch_gpios.Pull = GPIO_NOPULL;
	tim1OC_ch_gpios.Speed = GPIO_SPEED_FREQ_LOW;
	HAL_GPIO_Init(GPIOA, &tim1OC_ch_gpios);

	tim4OC_ch_gpios.Pin = GPIO_PIN_8;
	tim4OC_ch_gpios.Mode = GPIO_MODE_AF_PP;
	tim4OC_ch_gpios.Pull = GPIO_NOPULL;
	tim4OC_ch_gpios.Speed = GPIO_SPEED_FREQ_LOW;
	tim4OC_ch_gpios.Alternate = GPIO_AF2_TIM4;
	HAL_GPIO_Init(GPIOB, &tim4OC_ch_gpios);

	tim11OC_ch_gpios.Pin = GPIO_PIN_9;
	tim11OC_ch_gpios.Mode = GPIO_MODE_AF_PP;
	tim11OC_ch_gpios.Pull = GPIO_NOPULL;
	tim11OC_ch_gpios.Speed = GPIO_SPEED_FREQ_LOW;
	tim11OC_ch_gpios.Alternate = GPIO_AF3_TIM11;
	HAL_GPIO_Init(GPIOB, &tim11OC_ch_gpios);

	tim9OC_ch_gpios.Pin = GPIO_PIN_5;
	tim9OC_ch_gpios.Mode = GPIO_MODE_AF_PP;
	tim9OC_ch_gpios.Pull = GPIO_NOPULL;
	tim9OC_ch_gpios.Speed = GPIO_SPEED_FREQ_LOW;
	tim9OC_ch_gpios.Alternate = GPIO_AF3_TIM9;
	HAL_GPIO_Init(GPIOE, &tim9OC_ch_gpios);


	//3. nvic settings
	HAL_NVIC_SetPriority(TIM5_IRQn,15,0);
	HAL_NVIC_EnableIRQ(TIM5_IRQn);
	HAL_NVIC_SetPriority(TIM2_IRQn,15,0);
	HAL_NVIC_EnableIRQ(TIM2_IRQn);
	HAL_NVIC_SetPriority(TIM3_IRQn,15,0);
	HAL_NVIC_EnableIRQ(TIM3_IRQn);
	HAL_NVIC_SetPriority(TIM8_TRG_COM_TIM14_IRQn,15,0);
	HAL_NVIC_EnableIRQ(TIM8_TRG_COM_TIM14_IRQn);
	HAL_NVIC_SetPriority(TIM1_CC_IRQn,15,0);
	HAL_NVIC_EnableIRQ(TIM1_CC_IRQn);
	HAL_NVIC_SetPriority(TIM4_IRQn,15,0);
	HAL_NVIC_EnableIRQ(TIM4_IRQn);
	HAL_NVIC_SetPriority(TIM1_TRG_COM_TIM11_IRQn,15,0);
	HAL_NVIC_EnableIRQ(TIM1_TRG_COM_TIM11_IRQn);
	HAL_NVIC_SetPriority(TIM1_BRK_TIM9_IRQn,15,0);
	HAL_NVIC_EnableIRQ(TIM1_BRK_TIM9_IRQn);
}

 

 

1 REPLY 1

Cube is open source, so simply debug this as your own code - place a breakpoint at the line where you change what you want to change, then single-step and observe what and how gets written into the timers' registers.

JW