[quote=“AlexTash, post:1, topic:17761, full:true”]
Добрый день всем. есть задача запускать DC мотор в разные стороны и останавливать по возможности в точных положениях, для этого пытаюсь использовать таймеры в режиме FastPWM. по каждому срабатыванию прерывания TIMER5_COMPA(B,C)_vect и TIMER5_OVF_vect происходит понижение подаваемого ШИМ на двигатель. контроллер ATMEGA2560.
Но вот какая непонятная ситуация, на первом вращении вообще не происходит прерываний TIMER5_COMPA(B,C)_vect , на втором всё начинает работать как нужно, но с параметрами OCR5A(B,C) из первого вращения, в третьем вращении используются параметры из второго, и так далее. уже всё препробовал играл с разрешениями глобальных прерываний, менял момент определения OCR5A(B,C), полностью при вызове функции преписывал настройки региистров. Ничего не помогает, действие параметров OCR5A(B,C) смещается ровно на цикл. Код такой
#define motorPin1 42
#define motorPin2 40
#define motorEn 5
#define encoder 47 //вход Т5 для внешнего тактирования от энкодера
unsigned int cnt = 1;
int Speed1 = 70;
int Speed2 = 50;
int Speed3 = 20;
int deceleration1 = 10;
int deceleration2 = 6;
int deceleration3 = 3;
bool moving = false;
bool direction = true;
void MoveMotor(bool dir, int lenght) {
cli();
TCCR5B = 0;
OCR5A = lenght - deceleration1;
OCR5B = lenght - deceleration2;
OCR5C = lenght - deceleration3;
ICR5 = lenght;
TCCR5B = 0b11111;
sei();
Serial.print("OCR5A =");
Serial.println(OCR5A);
Serial.print("OCR5B =");
Serial.println(OCR5B);
Serial.print("OCR5C =");
Serial.println(OCR5C);
Serial.print("ICR5 =");
Serial.println(ICR5);
Serial.print("TIMSK5 = ");
Serial.println(TIMSK5, BIN);
Serial.print("TCCR5A = ");
Serial.println(TCCR5A, BIN);
Serial.print("TCCR5B = ");
Serial.println(TCCR5B, BIN);
Serial.print("TIFR5 = ");
Serial.println(TIFR5, BIN);
Serial.print("TCNT5 = ");
Serial.println(TCNT5);
digitalWrite(motorEn, 1);
if (dir) {
digitalWrite(motorPin1, HIGH);
} else {
digitalWrite(motorPin2, HIGH);
}
moving = true;
}
//******************************************************************************
//Стартовые установки
//******************************************************************************
void setup() {
TCCR5A = 0;
TCCR5B = 0;
TIMSK5 = 0;
TIMSK5 |= (1 << OCIE5C) | (1 << OCIE5B) | (1 << OCIE5A) | (1 << TOIE5); // включить прерывание по совпадению таймера
TCCR5A |= (0 << COM5A1) | (1 << COM5A0) | (0 << COM5B1) | (1 << COM5B0) | (0 << COM5C1) | (1 << COM5C0) | (1 << WGM51) | (0 << WGM50);
TCCR5B |= (1 << WGM53) | (1 << WGM52) | (1 << CS52) | (1 << CS51) | (1 << CS50); // | (0 << 5);
pinMode(motorPin1, OUTPUT);
pinMode(motorPin2, OUTPUT);
pinMode(motorEn, OUTPUT);
pinMode(encoder, INPUT);
digitalWrite(motorPin1, 0);
digitalWrite(motorPin2, 0);
digitalWrite(motorEn, 0);
Serial.begin(115200);
sei(); // включить глобальные прерывания
MoveMotor(direction, 15);
}
void loop() {
if (TCNT5 != cnt) {
Serial.println(TCNT5);
cnt = TCNT5;
}
if (!moving) {
MoveMotor(direction, 20);
direction = !direction;
}
}
ISR(TIMER5_COMPA_vect) {
Serial.println("timerA");
analogWrite(motorEn, 255 * Speed1 / 100);
}
ISR(TIMER5_COMPB_vect) {
analogWrite(motorEn, 255 * Speed2 / 100);
Serial.println("timerB");
}
ISR(TIMER5_COMPC_vect) {
analogWrite(motorEn, 255 * Speed3 / 100);
Serial.println("timerC");
}
ISR(TIMER5_OVF_vect) {
Serial.println("timerOVF");
digitalWrite(motorPin1, 0);
digitalWrite(motorPin2, 0);
digitalWrite(motorEn, 0);
Serial.print("TCNT5 = ");
Serial.println(TCNT5);
moving = false;
}
лог из терминала
‘’’
OCR5A =5
OCR5B =9
OCR5C =12
ICR5 =15
TIMSK5 = 1111
TCCR5A = 1010110
TCCR5B = 11111
TIFR5 = 0
TCNT5 = 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
timerOVF
TCNT5 = 0
0
OCR5A =10
OCR5B =14
OCR5C =17
ICR5 =20
TIMSK5 = 1111
TCCR5A = 1010110
TCCR5B = 11111
TIFR5 = 100000
TCNT5 = 0
1
2
3
4
5
timerA
6
7
8
9
timerB
10
11
12
timerC
13
14
15
16
17
18
19
20
timerOVF
TCNT5 = 0
0
OCR5A =10
OCR5B =14
OCR5C =17
ICR5 =20
TIMSK5 = 1111
TCCR5A = 1010110
TCCR5B = 11111
TIFR5 = 100000
TCNT5 = 0
1
2
3
4
5
6
7
8
9
10
timerA
11
12
13
14
timerB
15
16
17
timerC
18
19
20
timerOVF
TCNT5 = 0
0
OCR5A =10
OCR5B =14
OCR5C =17
ICR5 =20
TIMSK5 = 1111
TCCR5A = 1010110
TCCR5B = 11111
TIFR5 = 100000
TCNT5 = 0
1
2
3
4
5
6
7
8
9
10
timerA
11
12
13
14
timerB
15
16
17
timerC
18
19
20
timerOVF
TCNT5 = 0
OCR5A =10
OCR5B =14
OCR5C =17
ICR5 =20
TIMSK5 = 1111
TCCR5A = 1010110
TCCR5B = 11111
TIFR5 = 100000
TCNT5 = 0
0
1
2
3
4
5
6
7
8
9
10
timerA
11
12
13
14
timerB
15
16
17
timerC
18
‘’’
может я что-то упускаю, а может Proteus какой-то в симуляции глюк выдает, возможности на реальном оборудовании проверить пока нет.