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

[atmega8][gcc]przerwanie od zbocza od przepełnienia

tomasz1987 11 Sty 2010 00:39 1607 3
  • #1 7517867
    tomasz1987
    Poziom 16  
    prosze oto kod mam problem z ogarnięciem dlaczego nie zlicza mi sygnałów z int0


    
    #include <avr/io.h>                // dostęp do rejestrów
    #include <avr/interrupt.h>        // funkcje sei(), cli()
    #include <avr/signal.h>                // definicje SIGNAL, INTERRUPT
    #include <util/delay.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include "char_code.h"
    #include "LCD_lib.h"
    #include <avr/io.h>
    #include <util/delay.h>
    
    void RozdzielLiczbe(uint32_t Liczba,const uint8_t LCDGotoX,const uint8_t LCDGotoY);
    unsigned char str_a[16];
    unsigned char num_a;
    unsigned char str[16];
    unsigned char num;
    float value_a = 0;
    float overflow = 0;
    
    
    SIGNAL (SIG_OVERFLOW2)                 // obsługa przerwania od licznika 2
    {PORTB^=_BV(PB1);
    value_a++;
    	num_a = sprintf(str_a,"uplynelo: %ds",(unsigned char)(value_a));
    	LCDGotoXY(0,0);
        LCDstring(str_a,num_a);
    	RozdzielLiczbe(overflow,0,1);}
    
    
    SIGNAL (SIG_OVERFLOW0)
    {
      overflow++;                // inkrementuj licznik przepełnień
      
    
    }
    
    
    int main(void)                // program główny
    {
      DDRB |=_BV(1)	;			   // PORTB pin 1 jako wyjście
      PORTB &=~_BV(1);			  //  PORTB pin 1 stan niski
     TIMSK &=~_BV(TOIE2);        // Wyłącz przerwania TC2
      ASSR |= _BV(AS2);        // przełącz TC2 z taktowania zegarem CPU
                              // na generator asynchoniczny 32768 Hz
      TCCR2 = _BV(CS22)|_BV(CS20);         // ustaw preskaler na podział przez 128
                              // aby generować przerwania dokładnie co 1 sekundę
      while(ASSR&0x07);        // czekaj na uaktualnienie TC2
      TIMSK |= _BV(TOIE2)|_BV(TOIE0);        // włącz przerwania z TC2 i TC0
      TCNT0 = 0x00;         // wartość początkowa TC0
      TCCR0 = _BV(CS01)|_BV(CS02);// wyzwalanie z T0 opad. zboczem
    
    
                           
    	
    
    LCDinit();					// inicjalizacja wyświetlacza
    LCDcursorOFF();				// wyłaczenie kursora
      sei();                // włącz obsługę przerwań
    
      while(1)   ;             // pętla nieskończona
     
     
     }


    dodam że TIMER2 mapędza kwarc zegarkowy
  • #2 7518089
    Konto nie istnieje
    Konto nie istnieje  
  • #3 7518939
    OlekM
    Poziom 17  
    Wpierw drobny komentarz do postu użytkownika albertb:

    1. Zmienne, których używasz w przerwaniu i których jednocześnie używasz w "zwykłym kodzie" powinny być deklarowane jako volatile. Dzięki temu kompilator nie wykonuje na nich niektórych optymalizacji.

    2. Należy unikać stosowania typów zmiennoprzecinkowych (jak float) w mikrokontrolerach bez jednostki FPU (jak AVR'y). Ponadto jeśli zamierzasz zmienną jedynie zmieniać o całkowite wartości (np. operatorem ++), to sensowniejszy jest typ całkowitoliczbowy (np. unsigned int, unsigned char).

    3. Tu jest drobne przeoczenie, bowiem używasz tej zmiennej w innym miejscu - i kompilator nie ma prawa jej wyciąć.

    I kilka innych uwag:

    Proponuję przejść na nowe nazewnictwo przerwań, SIGNAL(...) jest już przestarzałe, obecnie stosowane jest ISR(...) - więcej na ten temat w manualu avr-libc.

    
    nie zlicza mi sygnałów z int0
    


    Bo stara się liczyć sygnały z timera :-)

    Proponuję powtórzyć trick z: PORTB^=_BV(PB1); w drugim przerwaniu i upewnić się, że w ogóle jest ono wywoływane.
  • #4 7524328
    tomasz1987
    Poziom 16  
    dzięki około 4 rano znalazłem proponowaną przez ciebie nowe nazewnictwo i zaczęło działać
REKLAMA