logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[ATMega128][C]Przerwanie SIG_OUTPUT_COMPARE3B

rafmos 01 Cze 2008 13:10 2202 8
REKLAMA
  • #1 5203124
    rafmos
    Poziom 13  
    Wykonuje przerwanie na procesorze Atmega128 pisząc program w C output compare i stosuje uchwyt w przerwaniu SIG_OUTPUT_COMPARE3A no i w tym trybie przerwanie mi działa jeżeli użyje uchwytu przerwania SIG_OUTPUT_COMPARE3B (odpowiednio) pozmieniam rejestry to niestety nie działa
    oto kod procedu najważniejszych:
    
    SIGNAL (SIG_OUTPUT_COMPARE3B)
    {		
    	tablica[i]+=(ADCH<< 8 ) ;
    	i++;
    }
    
    inicjalizacja timera:
    
    void timer_init(void)
    {	
    	ETIMSK=(1<<OCIE3B);	//Inicjalizacja timera 3 w tyrybie output compare
    	OCR3BH=5;		//  
    	OCR3BL=0;
    	TCCR3A=0; 		//
    	TCCR3B=8+presc;
    }
    
    
    pętla gówna:
                     presc=1;
                     sei();
    konwersja: if (i<256) goto konwersja;
                     cli();
    

    Czy ktoś może mi powiedzieć czego tutaj brakuje? lub co jest nie tak?

    Regulamin
    >Poprawiłem tytuł , kod ująłem w tagi , przeniosłem do właściwego działu<
    [zumek]
  • REKLAMA
  • REKLAMA
  • #3 5203606
    rafmos
    Poziom 13  
    Zamieniłem
    SIGNAL (SIG_OUTPUT_COMPARE3B) na ISR(TIMER3_COMPA_vect)
    no i nic nie pomogło, ale wystarczy przystosować to do
    ISR(TIMER3_COMPA_vect), czyli zamienić:
    ETIMSK=(1<<OCIE3A);
    OCR3AH=5;
    OCR3AL=0; i działa, więc nie wiem co jest nie tak?
  • REKLAMA
  • #4 5203721
    ZbeeGin
    Poziom 39  
    Niestety nie możesz użyć rejestru OCR3B by licznik pracował porawnie w trybie CTC. Musisz użyć OCR3A. Dlatego też pierwotna wersja programu jaką przedstawiłeś nie działa.
  • #5 5204686
    rafmos
    Poziom 13  
    No niestety, dokumentacja nie pozostawia złudzeń. Moim zamierzeniem było użycie timera 3 tak, aby wykonywał dwa osobne zadania w dwóch różnych przerwaniach. Timera 1 już używam. No niestety będe musiał sobie poradzić inaczej. Dzięki.
  • #6 5204920
    ZbeeGin
    Poziom 39  
    Jeśli wartości ładowane do rejestrów OCR3B i OCR3C będą mniejsze niż OCR3A to da się te wszystkie przerwania z porównań wykorzystać. Programik testowy (ASM):
    .include "m128def.inc"
    
    .cseg
    
        .org    0x00
        rjmp    start
    
        .org    OC3Aaddr
        rjmp    _ctc_isr
        
        .org    OC3Baddr
        rjmp    _oc3b_isr
        
        .org    OC3Caddr
        rjmp    _oc3c_isr
       
        .org    0x50
    start:
        ldi     r16, high(RAMEND)               ;stos
        out     SPH, r16
        ldi     r16, low(RAMEND)
        out     SPL, r16
    
        ldi     r16, 0x05                       ;ctc wartosc max
        sts     OCR3AH, r16                     ;(zeruje stan portow)
        ldi     r16, 0x00
        sts     OCR3AL, r16
        ldi     r16, 0x0F                       ;pierwsze porownanie
        sts     OCR3BL, r16                     ;(ustawia PB1)
        ldi     r16, 0x80                       ;drugie porownanie
        sts     OCR3CL, r16                     ;(ustawia PB2)
        ldi     r16,(1<<WGM32)|(1<<CS31)        ;licznik CTC, prescale 8
        sts     TCCR3B, r16
        ldi     r16,(1<<OCIE3A)|(1<<OCIE3B)|(1<<OCIE3C)
        sts     ETIMSK, r16                     ;porownania niech gen. przerwania
        sei                                     ;no! jadziem!
    
        ldi     r16, 0xFF                       ;a port jako wyjście
        out     DDRB, r16
    
    loop:
        nop                                     ;pętelka
        nop
        rjmp    loop
    
    _ctc_isr:
        cbi     PORTB, 1                        ;stan portow: zero
        cbi     PORTB, 2
        reti
    
    _oc3b_isr:
        sbi     PORTB, 1                        ;ustaw pb1 - porownanie 1
        reti
    
    _oc3c_isr:                                  
        sbi     PORTB, 2                        ;ustaw pb2 - porownanie 2
        reti
    

    Możesz go zapuścić w AVR Studio i zobaczysz co się będzie działo na porcie B.

    ps. Sorry, że znów wyszedł mi z tego programowy Fast PWM w Inverted Mode:)
  • #7 5205117
    KowalD
    Poziom 17  
    rafmos napisał:
    No niestety, dokumentacja nie pozostawia złudzeń. Moim zamierzeniem było użycie timera 3 tak, aby wykonywał dwa osobne zadania w dwóch różnych przerwaniach. Timera 1 już używam. No niestety będe musiał sobie poradzić inaczej. Dzięki.

    ale nie ma co panikowac ;)... da rade :)... tylko wylacz tryg CTC (jest to tryb z autozerowaniem po usatwieniu flagi porownania... czyli jesli chcesz uzywac dwoch przerwan to tak sie nie da :(... licznik bedzie zerowany zawsze po przerwaniu wywolanym od komparatora, ktory porownuje z mniejsza wartoscia... proste :))... timer ma 3 komparatory :) i mozna wykorzystywac wszystkie trzy przerwania... timera nie zeruj... niech chodzi w kolko :)... a gdy ktorys z komparatoryw zglosi przerwanie to w jego obsludze ustaw nowa wartosc do porownywania :)... np. OCR3BH=OCR3B+X... dzie X to ta Twoja wartosc do jakiej ma zliczac timer :)... nie musisz osobno wpisywac wartosci do OCR3BH i OCR3BL, mozna na raz, tak jak napisalem... oczywiscie w koncu przy takim dodawaniu skonczy sie zakres liczb 16bitowych... ale wtedy rejestr sie "przekreci", tak jak i licznik i nie bedzie problemu :)...
  • REKLAMA
  • #8 5208551
    rafmos
    Poziom 13  
    Dzięki. Poradziłem sobie, ten sposób z dodawaniem OCR3BH=OCR3B+X się sprawdził.
  • #9 5209571
    KowalD
    Poziom 17  
    rafmos napisał:
    Dzięki. Poradziłem sobie, ten sposób z dodawaniem OCR3BH=OCR3B+X się sprawdził.
    ooo... literowka... zamiast OCR3BH=OCR3B+X wystarczy: OCR3B=OCR3B+X... ale jak dziala to jest dobrze ;)...
REKLAMA