Спасибо. И хотя Вы настраиваете отличные от моей комбинации инвертирование/прерывание
Таймеры/счётчики в AVR
Re: Таймеры/счётчики в AVR
[uquote="akl",url="/forum/viewtopic.php?p=4793181#p4793181"]Проверил режим 7 таймера 2 с разными прерываниями.[/uquote]
Спасибо. И хотя Вы настраиваете отличные от моей комбинации инвертирование/прерывание
, вижу подтверждение моих наблюдений. Осталось протестировать оставшиеся FastPWM режимы, но практически уверен, получите такие же результаты, как и у меня.
Спасибо. И хотя Вы настраиваете отличные от моей комбинации инвертирование/прерывание
- Starichok51
- Модератор
- Сообщения: 19042
- Зарегистрирован: Сб авг 14, 2010 15:05:51
- Откуда: г. Озерск, Челябинская обл.
Re: Таймеры/счётчики в AVR
у него в тексте нет задержки на 20 мс. поэтому он не сможет получить такие же результаты, как и у тебя.dfxman писал(а):но практически уверен, получите такие же результаты, как и у меня.
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Re: Таймеры/счётчики в AVR
Хотел донести до Вас - особенностей в работе всех таймеров (T0, T1 и T2) при одинаково корректных установках нет. В архиве программа работы таймеров Т2 режим 7 и Т1 режим15. На фотке в архивеdfxman писал(а):...вижу подтверждение моих наблюдений. Осталось протестировать оставшиеся FastPWM режимы, но практически уверен, получите такие же результаты, как и у меня.
верхний луч - импульсы на лапе PD3/OC2B
нижний луч - импульсы на PB2/OC1B
внешняя синхронизация по фронту PD2
скорость развертки 10мкс/дел.
- Вложения
-
- TEST_M168_T2_T1.zip
- (36.5 КБ) 16 скачиваний
Re: Таймеры/счётчики в AVR
akl, спасибо, что тратите время на эксперименты. Но Вы меня не до конца поняли, возможно, я стал плохо формулировать... Я не сравниваю таймеры между собой в одних и тех же режимах. Я столкнулся с разной работой таймера в разных подрежимах (назовём так) внутри режима Fast PWM. У таймера 0 и 2 таких подрежимов 2 - 3 и 7, у таймера 1 - 5 (5, 6, 7, 14, 15). По даташиту, принципиальная разница между подрежимами только в значении TOP. Оно либо фиксированное, либо задаётся в регистре OCRxA, либо (у таймера 1) ICR1. Так вот на практике, подрежим TOP=OCRxA работает не так, как остальные, и как я читаю в даташите. В чем разница - я уже писал, скрины с осциллографа приводил. Что может быть понятнее последних скринов и кода, я уж и не знаю.
P.S. Т.е. сравнивать надо 15 и (14 или 7, 6, 5) внутри таймера 1, или 15 таймера 1 и 3 таймера 2. Или 7 таймера 2 и 5 таймера 1. Надеюсь, смысл понятен.
P.S. Т.е. сравнивать надо 15 и (14 или 7, 6, 5) внутри таймера 1, или 15 таймера 1 и 3 таймера 2. Или 7 таймера 2 и 5 таймера 1. Надеюсь, смысл понятен.
Re: Таймеры/счётчики в AVR
stm8 ведет себя похоже основным режимам:
ну и вариант "уравнивания" режимов (1 канал - таймер 1, 15 режим, 2 канал - таймер 2, 3 режим с предварительной установкой TCNT2 в максимальное значение):
Спойлер
Спойлер
Спойлер
Код: Выделить всё
void startBothTimers(void) {
cli();
GTCCR = (1 << TSM) | (1 << PSRASY) | (1 << PSRSYNC);
// timer 2
TCCR2A = 0; TCCR2B = 0; TIMSK2 = 0; TIFR2 = 0;
TCNT2 = 0; OCR2A = 0; OCR2B = 0;
TCCR2A |= (1 << COM2B1) | (1 << WGM21) | (1 << WGM20);
TIMSK2 |= (1 << OCIE2B); // COMP interrupt to count pulses
OCR2B = 63;
TCCR2B |= (1 << CS22); // 64
///////////////
TCNT2 = 0xff; // try
///////////////
t2_counts = 5;
// timer 1
TCCR1A = 0; TCCR1B = 0; TIMSK1 = 0; TIFR1 = 0;
TCNT1 = 0; OCR1A = 0; OCR1B = 0; ICR1 = 0; // 16 bit regs
TCCR1A |= (1 << COM1B1) | (1 << WGM11) | (1 << WGM10);
TCCR1B |= (1 << WGM13) | (1 << WGM12);
OCR1A = 0xff; // period / frequency
TIMSK1 |= (1 << OCIE1B); // COMP interrupt to count pulses
OCR1B = 63; // duty
TCCR1B |= (1 << CS11) | (1 << CS10); // 64
t1_counts = 5;
sei();
GTCCR = (1 << PSRASY) | (1 << PSRSYNC); // less instructions
}
- Вложения
-
- t1_15_t2_3_ff.png
- (21.39 КБ) 264 скачивания
-
- t2_c1.png
- (18.83 КБ) 268 скачиваний
Re: Таймеры/счётчики в AVR
Ну и еще немного эмпирики. Имеет значение последовательность инициализации регистров (где бы еще про это указывалось...). Таймер 2, режимы 3 и 7. 4 варианта инициализации. Функции написал на ассемблере, чтобы компилятор не сильно вмешивался. ISR остались такими же, в сишной части, t2_counts всегда 5.




Спойлер
Спойлер
Код: Выделить всё
#include <avr/io.h>
.global start_timer0, start_timer1, start_timer2
#define TCC_A r18
#define TCC_B r19
#define DUTY r20
#define PERIOD r21
#define TMP r26
#define DLY_H r30
#define DLY_L r31
#define PMODE r24
#define PMIX r22
#define DUTY_VALUE 127
#define PERIOD_VALUE 255
start_timer0:
; in r24 - mode, r22 - mix
; clobbers r18-r27, r30-r31 (z)
; mix
; 1 - tccra - ocrx
; 2 - ocrx - tccra
; 3 - ocra - tccra - ocrb
; 4 - ocrb - tccra - ocra
; 3 7
ldi DUTY, DUTY_VALUE
ldi PERIOD, PERIOD_VALUE
cpi PMODE, 3
breq _t0_m3
cpi PMODE, 7
breq _t0_m7
jmp _t0_exit
_t0_m3:
ldi TCC_A, (1 << COM0B1) | (1 << WGM01) | (1 << WGM00)
ldi TCC_B, (1 << CS01) | (1 << CS00)
rjmp _t0_mix
_t0_m7:
ldi TCC_A, (1 << COM0B1) | (1 << WGM01) | (1 << WGM00)
ldi TCC_B, (1 << WGM02) | (1 << CS01) | (1 << CS00)
_t0_mix:
cli
ldi TMP, (1 << TSM) | (1 << PSRASY) | (1 << PSRSYNC)
sts GTCCR, TMP
clr TMP
sts TCCR0B, TMP
sts TCCR0A, TMP
sts OCR0A, TMP
sts OCR0B, TMP
sts TCNT0, TMP
sts TIMSK0, TMP
ldi TMP, 0x07
sts TIFR0, TMP
sts TCCR0B, TCC_B
cpi PMIX, 1
breq _t0_mix_1
cpi PMIX, 2
breq _t0_mix_2
cpi PMIX, 3
breq _t0_mix_3
cpi PMIX, 4
brne _t0_exit
_t0_mix_4:
sts OCR0B, DUTY
sts TCCR0A, TCC_A
sts OCR0A, PERIOD
rjmp _t0_start
_t0_mix_3:
sts OCR0A, PERIOD
sts TCCR0A, TCC_A
sts OCR0B, DUTY
rjmp _t0_start
_t0_mix_2:
sts OCR0A, PERIOD
sts OCR0B, DUTY
sts TCCR0A, TCC_A
rjmp _t0_start
_t0_mix_1:
sts TCCR0A, TCC_A
sts OCR0A, PERIOD
sts OCR0B, DUTY
_t0_start:
; sts TCCR0B, TCC_B
ldi TMP, (1 << OCIE0B)
sts TIMSK0, TMP
ldi TMP, (1 << PSRASY) | (1 << PSRSYNC)
;sbi _SFR_IO_ADDR(PINB), PB4
sbi _SFR_IO_ADDR(PIND), PD7
; 500us
ldi DLY_H, 11 ; 21 ; 1ms
ldi DLY_L, 99 ; 199
dly0:
dec DLY_L
brne dly0
dec DLY_H
brne dly0
;sbi _SFR_IO_ADDR(PINB), PB4
sbi _SFR_IO_ADDR(PIND), PD7
sei
; sts GTCCR, r26
sts GTCCR, TMP
_t0_exit:
ret
start_timer1:
; in r24 - mode, r22 - mix
; clobbers r18-r27, r30-r31 (z)
; 5 6 7 14 15
ret
start_timer2:
; in r24 - mode, r22 - mix
; clobbers r18-r27, r30-r31 (z)
; 3 7
ldi DUTY, DUTY_VALUE
ldi PERIOD, PERIOD_VALUE
cpi PMODE, 3
breq _t2_m3
cpi PMODE, 7
breq _t2_m7
jmp _t2_exit
_t2_m3:
ldi TCC_A, (1 << COM2B1) | (1 << WGM21) | (1 << WGM20)
ldi TCC_B, (1 << CS22)
rjmp _t2_mix
_t2_m7:
ldi TCC_A, (1 << COM2B1) | (1 << WGM21) | (1 << WGM20)
ldi TCC_B, (1 << WGM22) | (1 << CS22)
_t2_mix:
cli
ldi TMP, (1 << TSM) | (1 << PSRASY) | (1 << PSRSYNC)
sts GTCCR, TMP
clr TMP
sts TCCR2B, TMP
sts TCCR2A, TMP
sts OCR2A, TMP
sts OCR2B, TMP
sts TCNT2, TMP
sts TIMSK2, TMP
ldi TMP, 0x07
sts TIFR2, TMP
sts TCCR2B, TCC_B
cpi PMIX, 1
breq _t2_mix_1
cpi PMIX, 2
breq _t2_mix_2
cpi PMIX, 3
breq _t2_mix_3
cpi PMIX, 4
brne _t2_exit
_t2_mix_4:
sts OCR2B, DUTY
sts TCCR2A, TCC_A
sts OCR2A, PERIOD
rjmp _t2_start
_t2_mix_3:
sts OCR2A, PERIOD
sts TCCR2A, TCC_A
sts OCR2B, DUTY
rjmp _t2_start
_t2_mix_2:
sts OCR2A, PERIOD
sts OCR2B, DUTY
sts TCCR2A, TCC_A
rjmp _t2_start
_t2_mix_1:
sts TCCR2A, TCC_A
sts OCR2A, PERIOD
sts OCR2B, DUTY
_t2_start:
ldi TMP, (1 << OCIE2B)
sts TIMSK2, TMP
ldi TMP, (1 << PSRASY) | (1 << PSRSYNC)
;sbi _SFR_IO_ADDR(PINB), PB4
sbi _SFR_IO_ADDR(PIND), PD7
; 500us
ldi DLY_H, 11 ; 21 ; 1ms
ldi DLY_L, 99 ; 199
dly2:
dec DLY_L
brne dly2
dec DLY_H
brne dly2
;sbi _SFR_IO_ADDR(PINB), PB4
sbi _SFR_IO_ADDR(PIND), PD7
sei
; sts GTCCR, r26
sts GTCCR, TMP
_t2_exit:
ret
Спойлер
Код: Выделить всё
volatile uint16_t t2_counts;
static inline void stop_t2(void) {
TCCR2B &= 0xf8;
}
ISR(TIMER2_COMPB_vect) {
if(!--t2_counts) {
stop_t2();
}
}
- Вложения
-
- t2m7_3.png
- (7.96 КБ) 194 скачивания
-
- t2m7_2.png
- (8 КБ) 189 скачиваний
-
- t2m7_1.png
- (8.37 КБ) 187 скачиваний
-
- t2m3_2.png
- (8.26 КБ) 190 скачиваний
-
- t2m3_1.png
- (8.32 КБ) 195 скачиваний