Tryb CTC

To forum jest dla wszystkich pasjonatów mikrokontrolerów AVR Atmela. Wymiana doświadczeń i pomoc dla początkujących w pisaniu programów zarówno w C, Asemblerze jak i BASCOM. Zapraszam znawców tematu, aby pomogli wszystkim początkującym!
ODPOWIEDZ
kaliska5
Użytkownik
Posty: 348
Rejestracja: 01 maja 2008, 8:24
Lokalizacja: z nienacka
Kontakt:

Tryb CTC

Post autor: kaliska5 » 27 lut 2011, 22:00

Witam. Próbuje uzyskać na attiny2313 jak najszybszy przebieg z wykorzystaniem Timera1 w trybie CTC i mam problem.Procesor popędzam kwarcem 12Mhz dzielnik przez 8 wyłączony,prescaler wyłączony a max częstotliwość jaka uzyskuje to 142Khz.Co jest złe lub co trzeba poprawić by uzyskać ~500khz??Pozdrawiam i z góry dziękuje.

Kod: Zaznacz cały

\
#include <avr/io.h>               
#include <avr/interrupt.h>   
#include <util/delay.h>   	

int main(void)               
{
	DDRB=0b11111100;    
	PORTB=0;		
    TCCR1B |= (1 << WGM12); 
	TIMSK |= (1 << OCIE1A);      
	OCR1A   = 1000 ; 
	TCCR1B |= (1 << CS10); 
	TCCR1B&=~((1<<CS11)|(1<<CS12));
	sei();  
	for(;;)
	{
	if(!(PINB & 0b00000001))
	{
	OCR1A++;
	}
	if(!(PINB & 0b00000010))
	{
	OCR1A--;
	}
	_delay_ms(1);
	}		

}


ISR(TIMER1_COMPA_vect)   
{
	PORTB^=_BV(2);
}


keruseykaryu

Post autor: keruseykaryu » 27 lut 2011, 22:40

Przerwanie kompilator robi dość długie:

Kod: Zaznacz cały

0000005e <__vector_4>:

} 


ISR(TIMER1_COMPA_vect)    
{ 
  5e:	1f 92       	push	r1
  60:	0f 92       	push	r0
  62:	0f b6       	in	r0, 0x3f	; 63
  64:	0f 92       	push	r0
  66:	11 24       	eor	r1, r1
  68:	8f 93       	push	r24
  6a:	9f 93       	push	r25
    PORTB^=_BV(2); 
  6c:	88 b3       	in	r24, 0x18	; 24
  6e:	94 e0       	ldi	r25, 0x04	; 4
  70:	89 27       	eor	r24, r25
  72:	88 bb       	out	0x18, r24	; 24
}
  74:	9f 91       	pop	r25
  76:	8f 91       	pop	r24
  78:	0f 90       	pop	r0
  7a:	0f be       	out	0x3f, r0	; 63
  7c:	0f 90       	pop	r0
  7e:	1f 90       	pop	r1
  80:	18 95       	reti
Stąd nie możesz przeskoczyć granicy 157kHz, tyle dokładnie wychodzi matematycznie, bo ten ISR ma swój czas "realizacji" zmiany stanu pinu równy 3,17us @12MHz. Tj. odcinek czasu od bieżącego do poprzedniego OUT-a z wcześniejszego przerwania.

Trzeba wymyślić coś sprzętowego. Np. połączenie CTC ze zmianą stanu pinu OC1A. Wtedy mógłbyś "podjechać" pod parę MHz.
Załączniki
ctc_clk.jpg

kaliska5
Użytkownik
Posty: 348
Rejestracja: 01 maja 2008, 8:24
Lokalizacja: z nienacka
Kontakt:

Post autor: kaliska5 » 27 lut 2011, 23:09

W tym problem ze potrzebuje zmiany 2 pinów i jeszcze małe przesuniecie fazowe miedzy nimi.Czyli zostaje mi popędzić szybciej procka ??

keruseykaryu

Post autor: keruseykaryu » 27 lut 2011, 23:16

kaliska5 pisze:Czyli zostaje mi popędzić szybciej procka ??
To nic nie da, bo i tak musiałbyś go popędzić 4 razy szybciej, a 40MHz tiny2313 nie wytrzyma. Można by próbować z tiny261 bo ma PLL i trochę lepiej rozbudowany tajmer.

I jeszcze jedna możliwość zabawy. Niebezpieczna dla reszty kodu. Dodać do ISR parametr ISR_NAKED i całą prockę przerwania napisać kończąc obowiązkowo przez reti().
Zrobiłem sobie test na tiny25 i przy 8MHz już dało się wyciągnąć 284kHz. Ale procka była naprawdę krótka.

ISR(TIM0_COMPA_vect, ISR_NAKED)
{
PORTB ^= (1<<PB0);
reti();
}
Załączniki
ctc25tny.PNG
ctc25tny.PNG (2.28 KiB) Przejrzano 3458 razy

ODPOWIEDZ