2023-12-30 03:28 PM
Hello, I am trying to write a routine, that takes an array of structures as input and sets the timer 1 parameters. This function is called after each overflow of timer 1. I turn off the respective channels, then set the parameters, as seen in the following ISR:
void TIM1_UP_TIM16_IRQHandler(void)
{
htim1.Instance->CCER &= ~(TIM_CCER_CC1E | TIM_CCER_CC1NE | TIM_CCER_CC2E | TIM_CCER_CC2NE | TIM_CCER_CC3E | TIM_CCER_CC3NE);
HAL_GPIO_WritePin(TIM1_UP_GPIO_Port, TIM1_UP_Pin, GPIO_PIN_SET);
HAL_TIM_IRQHandler(&htim1);
HAL_GPIO_WritePin(TIM1_UP_GPIO_Port, TIM1_UP_Pin, GPIO_PIN_RESET);
if (currentPattern < NUM_PATTERNS) {
setconfig(&durations[currentPattern]);
currentPattern++;
}
The setconfig function looks as follows:
:
void setconfig(TIM_SU const* const timersetup) {
// Function that takes a pointer to a TIM_SU structure as an argument
htim2.Instance->ARR = timersetup->tim2_period;
// Period of timer 1, i.e. the duration of the second pulse
htim1.Instance->ARR = timersetup->tim1_period;
// Duration of the first pulse (positive or negative)
htim1.Instance->CCR1 = timersetup->tim1_channel1_pwm_duration;
htim1.Instance->CCR2 = timersetup->tim1_channel2_pwm_duration;
htim1.Instance->CCR3 = timersetup->tim1_channel3_pwm_duration;
// Dead time, sets only the lower 8 bits (see page 1280)
htim1.Instance->BDTR &= ~TIM_BDTR_DTG; // Mask to clear the DTG bits
htim1.Instance->BDTR |= (uint32_t)(timersetup->dead_time & 0xFF);
htim1.Instance->CCMR1 &= ~TIM_CCMR1_OC1M; //channel 1 clearing
htim1.Instance->CCMR1 &= ~TIM_CCMR1_OC2M; //channel 2 clearing
htim1.Instance->CCMR2 &= ~TIM_CCMR2_OC3M; //channel 3 clearing
switch (timersetup->tim1_channel1_pwm_mode) {
case PWM_MODE_1:
TIM1->CCMR1 |= (TIM_OCMODE_PWM1 << TIM_CCMR1_OC1M_Pos);
break;
case PWM_MODE_2:
TIM1->CCMR1 |= (TIM_OCMODE_PWM2 << TIM_CCMR1_OC1M_Pos);
}
switch (timersetup->tim1_channel2_pwm_mode) {
case PWM_MODE_1:
TIM1->CCMR1 |= (TIM_OCMODE_PWM1 << TIM_CCMR1_OC2M_Pos);
break;
case PWM_MODE_2:
TIM1->CCMR1 |= (TIM_OCMODE_PWM2 << TIM_CCMR1_OC2M_Pos);
}
switch (timersetup->tim1_channel3_pwm_mode) {
case PWM_MODE_1:
TIM1->CCMR2 |= (TIM_OCMODE_PWM1 << TIM_CCMR2_OC3M_Pos);;
break;
case PWM_MODE_2:
TIM1->CCMR2 |= (TIM_OCMODE_PWM2 << TIM_CCMR2_OC3M_Pos);
}
}
Just as an example, one structure of the "durations" array:
TIM_SU durations[NUM_PATTERNS]= {
// Array of TIM_SU structures. NUM_PATTERNS defines the number of patterns. Each element is initialized with specific settings.
{
.tim2_period = 50000-1,
.tim1_channel1_pwm_duration =8000-1,
.tim1_channel2_pwm_duration =8000-1,
.tim1_channel3_pwm_duration =8000-1,
.tim1_period = 30000-1,
.dead_time = 200,
.tim1_channel1_pwm_mode = PWM_MODE_1,
.tim1_channel2_pwm_mode = PWM_MODE_1,
.tim1_channel3_pwm_mode = PWM_MODE_1,
},....
However, I am not able to change the PWM during runtime. I can change every other parameter with this code, the PWM Mode for each channel remains unchanged.
Is there any obvious reason I am missing? I turn the channels of, clear the respective bit-field and set it according to the desired PWM mode...
Thank you in advance for your help!
Ruan!
Solved! Go to Solution.
2023-12-30 03:43 PM - edited 2023-12-30 03:45 PM
> TIM1->CCMR1 |= (TIM_OCMODE_PWM1 << TIM_CCMR1_OC1M_Pos);
TIM_OCMODE_PWM1 is already shifted to the appropriate bits for the OC1M field within CCMR1. You're shifting it more, so other bits are being modified instead of what you want.
Definition:
#define TIM_OCMODE_PWM1 (TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1) /*!< PWM mode 1 */
For channels 2 and 4, you will need to left-shift it by (TIM_CCMR1_OC2M_Pos - TIM_CCMR1_OC1M_Pos) bits.
2023-12-30 03:32 PM
I am using the STM32L433 Nucleo Board!
2023-12-30 03:43 PM - edited 2023-12-30 03:45 PM
> TIM1->CCMR1 |= (TIM_OCMODE_PWM1 << TIM_CCMR1_OC1M_Pos);
TIM_OCMODE_PWM1 is already shifted to the appropriate bits for the OC1M field within CCMR1. You're shifting it more, so other bits are being modified instead of what you want.
Definition:
#define TIM_OCMODE_PWM1 (TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1) /*!< PWM mode 1 */
For channels 2 and 4, you will need to left-shift it by (TIM_CCMR1_OC2M_Pos - TIM_CCMR1_OC1M_Pos) bits.
2023-12-31 03:48 AM
Right, that did the trick!
Thank you TDK! :)