2024-05-02 10:35 AM
Hi everyone,
I am currently working on controlling a stepper motor using a PWM signal. I want to dynamically update the speed of the motor using different ARR and CCR1 values. Controlling the stepper works fine until an uncertain amount of time when the PWM signal appears to disappear completely.
I have read that something like enabling the preload register should help but this still doesn't fix my problem.
Here is my code so far:
#include "main.h"
#define C
#define F_CLK 24000000
uint16_t arr_from_freq(uint16_t freq){
return F_CLK/(freq*(TIM2->PSC+1)) - 1;
}
int main(void){
EPL_SystemClock_Config();
// Enable the GPIOA and TIM2 peripherals
RCC->AHBENR |= RCC_AHBENR_GPIOAEN;
RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
// Set the mode of the GPIOA pin 5 to alternate function mode 2
GPIOA->MODER |= GPIO_MODER_MODER5_1;
GPIOA->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR5;
GPIOA->AFR[0] |= 0b0010 << 20;
// Disable the timer before setting the prescaler and overflow values
TIM2->CR1 &= ~TIM_CR1_CEN;
// Set the prescaler and overflow values
TIM2->PSC = 3; // 10 seems to be optimal for now
TIM2->ARR = 64000;
TIM2->CCR1 = 0;
// Set the PWM mode 1
TIM2->CCMR1 |= TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1;
TIM2->CCMR1 |= TIM_CCMR1_OC1PE;
// Set the output polarity to active high
TIM2->CCER |= TIM_CCER_CC1E;
// Enable the main output
TIM2->BDTR |= TIM_BDTR_MOE;
// Enbable the timer
// Set the center-aligned mode
TIM2->CR1 |= TIM_CR1_CMS_0 | TIM_CR1_CEN;
uint16_t lower_limit = 1000; // One rotation per minute because of step/8 microstepping
uint16_t upper_limit = 3000;
uint16_t pwm_frequency = lower_limit;
uint16_t duty = arr_from_freq(lower_limit)/2;
uint8_t state = 0;
for(;;){
if (pwm_frequency <= upper_limit && state == 0){
pwm_frequency += 1;
} else {state = 1;}
if (pwm_frequency >= lower_limit && state == 1){
pwm_frequency -= 1;
} else {state = 0;}
TIM2->ARR = arr_from_freq(pwm_frequency);
duty = arr_from_freq(pwm_frequency)/2;
TIM2->CCR1 = duty;
delay(5000);
}
}
Thanks in advance for anyone willing to help!
Cheers
Solved! Go to Solution.
2024-05-02 01:12 PM - edited 2024-05-02 01:13 PM
Which STM32?
> I have read that something like enabling the preload register should help but this still doesn't fix my problem.
You mean setting TIMx_CR1.ARPE did not help?
Show how did you try.
JW
PS TIM2 does not have BDTR.
2024-05-02 01:12 PM - edited 2024-05-02 01:13 PM
Which STM32?
> I have read that something like enabling the preload register should help but this still doesn't fix my problem.
You mean setting TIMx_CR1.ARPE did not help?
Show how did you try.
JW
PS TIM2 does not have BDTR.
2024-05-02 02:26 PM
Setting TIMx_CR1_ARPE did actually manage to fix this, I must have either tried the wrong register or just a completely wrong one. I am very new to programming on a low level basis, so thanks a lot for the quick and easy fix!