Спасибо. И хотя Вы настраиваете отличные от моей комбинации инвертирование/прерывание
Спасибо. И хотя Вы настраиваете отличные от моей комбинации инвертирование/прерывание
у него в тексте нет задержки на 20 мс. поэтому он не сможет получить такие же результаты, как и у тебя.dfxman писал(а):но практически уверен, получите такие же результаты, как и у меня.
Хотел донести до Вас - особенностей в работе всех таймеров (T0, T1 и T2) при одинаково корректных установках нет. В архиве программа работы таймеров Т2 режим 7 и Т1 режим15. На фотке в архивеdfxman писал(а):...вижу подтверждение моих наблюдений. Осталось протестировать оставшиеся FastPWM режимы, но практически уверен, получите такие же результаты, как и у меня.
Код: Выделить всё
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
}
Код: Выделить всё
#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();
}
}