Плавны разгон шагового двигателя на прерыаниях таймера

ivan dsp

✩✩✩✩✩✩✩
12 Дек 2022
2
0
Оформи код соответствующим тэгом
Здравствуйте! У меня крайне нестабильно работает плавный разгон шагового двигателя по прерыванию таймера

TCCR1A = 0; // установить регистры в 0
TCCR1B = 0;
TCCR1B |= (1 << WGM12); // включение в CTC режим
// Установка битов CS10 и CS12 на коэффициент деления 1024
TCCR1B |= (1 << CS10);
TCCR1B |= (1 << CS12);
TIMSK1 |= (1 << OCIE1A); // включение прерываний по совпадению

OCR1A = переменная, изменяемая в цикле старта; // установка регистра совпадения
Кто - нибудь делал так? И можно ли так делать?
Без прерываний таймера не обойтись, так как процессе разгона задействованы другие функции, например, запрос гироскопа.
 

poty

★★★★★★✩
19 Фев 2020
3,233
942
@ivan dsp, главное, чтобы "другие функции" не использовали запрет прерываний.
 

rkit

★★★✩✩✩✩
5 Фев 2021
508
127
Несолько раз перечитал, не вижу ни плавного разгона, ни какой-либо возможной причины нестабильности.
 

ivan dsp

✩✩✩✩✩✩✩
12 Дек 2022
2
0
Оформи код соответствующим тэгом
Вот это работает, но работает скверно, моторы могут остановиться в процессе разгона.


void gohome ()
{
// инициализация Timer1
cli(); // отключить глобальные прерывания
TCCR1A = 0; // установить регистры в 0
TCCR1B = 0;
TCCR1B |= (1 << WGM12); // включить CTC режим
TCCR1B |= (1 << CS10); // Установить биты на коэффициент деления 64
TCCR1B |= (1 << CS11);
TIMSK1 |= (1 << OCIE1A); // включить прерывание по совпадению таймера
sei(); // включить глобальные прерывания

while ((digitalRead(2) == LOW) || (digitalRead(4) == LOW) )
{
gohomePwm = true;
OCR1A = START_STEP_TIME; // установка регистра совпадения
if (START_STEP_TIME > MIN_STEP_TIME)
{
START_STEP_TIME -= ACCELERATION_STEP;
delay(50);
}
}
START_STEP_TIME = 30;

if ((digitalRead(2) == HIGH) || (digitalRead(4) == HIGH) )
{
TCCR1A = 0; // установить регистры в 0
TCCR1B = 0;
TCCR1B &= ~(1 << WGM12); // отлючить CTC режим
TIMSK1 &= ~(1 << OCIE1A); // отлючить прерывание по совпадению таймера
Serial.println(TIMSK1);
START_STEP_TIME = 30;
gohomePwm = false;
}
}

ISR(TIMER1_COMPA_vect)
{
if (gohomePwm == true)
{
digitalWrite(6, !digitalRead(6));
digitalWrite(10, !digitalRead(10));
}
}