2024-05-17 12:13 PM
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);
}
2024-05-18 01:53 AM
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