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

[ATMEGA16][C] - Problem z przerwaniami.

mslech 09 Wrz 2009 00:03 2145 25
  • #1 6997264
    mslech
    Poziom 10  
    Witam!!


    Chce zbadać długość przerwy pomiędzy bitami na INT0. Napisałem coś takiego, ale nie wiem czy ma prawo działać?? Jak to zmodyfikować?

    Kod:
    
    ISR(INT0_vect)
    {
    
    int start_DCF=0;
    int licznik_50ms=0;
    int czas_przerwy;
    
    while(start_DCF==0)
       {
       TCCR0 |= ((1 << CS00)); // Ustawienie timera T0
       TCNT0 = 0; //zerowanie licznika 0
       MCUCR |= (1<<ISC01); //przerwanie wyzwolone zboczem opadającym
       if(TCNT0 >= 160) licznik_50ms++;
         
       
       MCUCR |= ((1<<ISC01)|(1<<ISC00)); //przerwanie wyzwolone zboczem narastającym
       TCCR0 |= ((0<<CS00)|(0<<CS01)|(0<<CS02)); // wyłączenie timera T0
       
       if (licznik_50ms>=30) start_DCF=1;
       
       };
    


    Jeżeli przerwa wynosi minimum 1500ms wtedy program przechodzi dalej.

    Kolejna wersja tego samego przy czym nic nie chce działać:
    Kod:
    
    IGNAL(SIG_INTERRUPT0)
    {
    //TCCR0 |= ((1 << CS00)); // Ustawienie timera T0
    //TcNT0 = 160; // odlicza odcinki po 50ms
    int start_DCF=0;
    int licznik_50ms=0;
    int flaga_DCF;
    
    
    while(start_DCF==0)
       {
       MCUCR |= (1<<ISC01);  //przerwanie wyzwolone zboczem opadającym
       
       if(INTF0==1)
       {
       GIFR|= (1<<INTF0); //zerowanie flagi wystapienia przerwania
       MCUCR |= ((1<<ISC01) | (1<<ISC00)); //przerwanie wyzwolone zboczem narastającym
       TCCR0 |= ((1 << CS00)); // Ustawienie timera T0
       TCNT0 = 0; //zerowanie licznika 0
       if(TCNT0 >= 160) licznik_50ms++;
       
       if(INTF0==1)
       {
       TCCR0 |= ((0<<CS00)|(0<<CS01)|(0<<CS02)); // wyłączenie timera T0
       
       if (licznik_50ms>=30) (start_DCF=1  & flaga_DCF++);
         else licznik_50ms=0;
       
       GIFR|= (1<<INTF0); //zerowanie flagi wystapienia przerwania
       }
       }
       
     
       }
    return flaga_DCF;
    
    }
     




    Bardzo Was proszę o pomoc bo sam już nie mam pomysłów a kończy mi się czas...
  • #2 6997340
    kwesoly
    Poziom 15  
    TCCR0 |= ((0<<CS00)|(0<<CS01)|(0<<CS02)); // wyłączenie timera T0 


    Nie wnikam w całość w tej chwili (pętle trwające po 1500ms nie do końca pasują do mojej wizji przerwań:P), ale powyższy kod na pewno nie wyłącza timera - poczytaj o operacjach bitowych, (bitwise operators), bo w tej chwili powyższa linijka wygląda tak:

    TCCR0 = TCCR0 | 0b00000000;


    Dodano po 1 [minuty]:

    Po drugie przerwania nie mogą nic zwracać, po trzecie do wklejania kodu służą znaczniki
    Cytat:
    [code ][ /code]
    :)

    Dodano po 21 [minuty]:

    And po czwarte:)
    SIGNAL(SIG_INTERRUPT0)
    {
    //TCCR0 |= ((1 << CS00)); // Ustawienie timera T0
    //TcNT0 = 160; // odlicza odcinki po 50ms
    int start_DCF=0;


    zwróć uwagę że start DCF nie jest globalna - ta zmienna znika gdy przerwanie się kończy

    Dodano po 36 [minuty]:

    Miałem coś podobnego na komputerze, chyba będzie lepsza bazą do przeróbek niż twój kod. Wartości Timera0 policzone dla kwarcu 16MhZ, ale powinieneś dać rade przeliczyć. Komentarzy odrobinę ale nazwy zmiennych opisooowe :)
  • #3 6997722
    tmf
    VIP Zasłużony dla elektroda
    A BTW, zamiast robic takie dziwne kombinacje nie lepiej ustawic prescaler timera tak, zeby timer sie nie przepelnial p[omiedzy impulsami, a potem w przerwaniu wywolywanym zboczem zapamietywac stan. To bedzie pare linii kodu. Nie zapominaj tez o resetowaniu prescalera, inaczej pierwszy pomiar bedzie losowy.
  • #4 6998393
    kwesoly
    Poziom 15  
    tmf napisał:
    A BTW, zamiast robic takie dziwne kombinacje nie lepiej ustawic prescaler timera tak, zeby timer sie nie przepelnial p[omiedzy impulsami, a potem w przerwaniu wywolywanym zboczem zapamietywac stan. To bedzie pare linii kodu. Nie zapominaj tez o resetowaniu prescalera, inaczej pierwszy pomiar bedzie losowy.


    Jeśli można by użyć Timer1 to oczywiście że tak, założyłem że jest do czegoś innego potrzebny. Odnośnie losowości - największy prescaler to 1024, co nawet przy prędkości 1Mhz daje maksymalny błąd 1ms. A resetowanie prescalera resetuje go dla wszystkich liczników co nie zawsze jest porzadane.
  • #5 6998754
    mslech
    Poziom 10  
    kwesoly - po pierwsze dzięki za ten program. Teraz wszystko powinno być dużo łatwiejsze.
    Nie rozumiem tylko na jakiej zasadzie program wie czy występuje zbocze narastające czy opadające??

    Definicje z programu:
    
    #define INT0PIN PORTD
    #define INT0NUM PD2
    #define GetINT0Pin() (INT0PIN & (1<<INT0NUM))
    
    volatile bool lowState1500msDetected=false;
    volatile uint8_t ovf_counted=0;
    
    #define NEEDED_OVFS 93 //62Hz and needed time 1500ms
    


    Przerwanie ze zboczami:
    
    
    ISR(INT0_vect) //INT0 Handling routine
    {
    	if(GetINT0Pin())	//rising edge
    		stopCounting();
    	else				//falling edge
    		if	(!lowState1500msDetected)			//flag cleared
    			startCounting();
    


    Nie za bardzo wiem o co chodzi w tej linijce:
    
    if(GetINT0Pin())	//rising edge
    

    Możesz mi wytłumaczyć??
  • #6 6999529
    kwesoly
    Poziom 15  
    Drobna pomyłka faktycznie:
    Zamiast
    #define INT0PIN PORTD 
    powinno być:
    #define INT0PIN PIND 
    Zakładam że wejście INT0 jest na porcie D, konkretnie na
    #define INT0NUM PD2 

    Ustawienie przerwania nie zmienia faktu, że można po prostu odczytywać stan pinu - więc jeśli właśnie wystąpiło zbocze (bo jesteśmy w przerwaniu), i stan wejścia wynosi 1 (GetINT0Pin() == (INT0PIN & (1<<INT0NUM)) == PIND & (1<<PD2) ) to zbocze musiało być narastające - w przeciwnym wypadku byłoby opadające.
  • #7 6999822
    mslech
    Poziom 10  
    Przede wszystkim kwesoly- wielkie dzięki za pomoc.
    Przerobiłem ten Twój program ale ciągle nie wiem co jest źle.

    
    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <stdbool.h>
    
    #define INT0PIN PIND 
    #define INT0NUM PD2
    #define GetINT0Pin() (INT0PIN & (1<<INT0NUM)) 
    #define Potrzebne_50ms 30
    
    
    volatile bool flaga_odbioru_DCF=false;
    volatile int licznik50ms=0; 
     
    inline static void inicjacja()
    { 
    GICR |= (1<<INT0); // odblokowania  przerwania INT0
    MCUCR |= (1<<ISC00); // przerwania załaczone na obydwa zbocza
    TCCR1B |= ((1 << CS11 | 1 << CS10)); //preskaler 64 z wartoscia 6250 daje 50ms czyli 20 hz
    TIMSK |= (1<<TOIE0); // odblkoowanie od przepełnienia licznika 1
    }
    
    inline static void StartZliczania()
    {
    licznik50ms=0;
    TCCR1B |= ((1 << CS11 | 1 << CS10)); //preskaler 64 z wartoscia 6250 daje 50ms czyli 20 hz
    }
    
    inline static void StopZliczania()
    {
    licznik50ms=0;
    TCCR1B &= ~((1 << CS11 & 1 << CS10));
    }
    
    ISR(INT0_vect) //obsługa przerwania od INT0
    {
    if(GetINT0Pin())   // zbocze narastające
         StopZliczania();
    	else                   // zbocze opadające
      if (!flaga_odbioru_DCF) 
      StartZliczania();
    }
    
    ISR(TIMER1_OVF_vect) // przerwanie od przepełnienia
    {
    TCCR1B=6250;
    licznik50ms++;
    	if(licznik50ms>=Potrzebne_50ms)
    		{
    			flaga_odbioru_DCF=true;
    			StopZliczania();
    		}
    }
    		 
    
    
    int main (void){       
    DDRB=0xff; //PORT diody
    DDRC=0xff; //ustawienie portu sterowania wyświetlaczami
    DDRD=0xf0; //ustawienie portu przycisków
    DDRA=0xff; //ustawienie portu sterowania segmantami
    PORTB=0xfe; //kiedy jest zasilanie swieci dioda
    
    
    
    unsigned char cyfry[6][10] = {
    {0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xf6},
    {0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xf6},
    {0xfd,0x61,0xdb,0xf3,0x67,0xb7,0xbf,0xe1,0xff,0xf7},
    {0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xf6},
    {0xfd,0x61,0xdb,0xf3,0x67,0xb7,0xbf,0xe1,0xff,0xf7},
    {0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xf6},
    }; 
    
    // deklaracja tablicy cyfr dla każdego wyświetlacza
    
    
    int wsk_cyfr[6]; // deklaracja zmiennej pomocniczej okreslającej jaka cyfra wystapi na danym wyświetlaczu
    unsigned char wys[6] = { 0xef,0xf7,0xfb,0xfd,0xfe,0xdf }; //adresy wyświetlaczy
         
     
       wsk_cyfr[0]=0; //
       wsk_cyfr[1]=5; //
       wsk_cyfr[2]=9; //    POCZĄTKOWE CYFRY NA WYŚWIETLACZACH
       wsk_cyfr[3]=5; //
       wsk_cyfr[4]=3; //
       wsk_cyfr[5]=2; //
    
    inicjacja();  
       
       
      
       while(!flaga_odbioru_DCF)  //PETLA Z ODBIOREM DCF
       {
       PORTC=wys[3];
       PORTA=cyfry[3][3];
       };
       
       
       
       while(1){   // POCZATEK GŁÓWNEJ PĘTLI 
       
       cli();
       int i=0;
       int k=0; 
       
       TCCR0 |= ((1 << CS00 | 1 <<CS01)); // Ustawienie timera T0 do podstawy  dla wyświetlaczy prseskaler 64
       TCCR1B |= (1 << CS12); //ustawienie timera T1 do odliczania 1s presacalekr 256
        
    	
    	if (TCNT1 >=31250) // odliczanie sekund
    	{
    	
    	wsk_cyfr[0]++; // kontrola nad wyświetlaczami
    	
    	  if (wsk_cyfr[0]>=10) (wsk_cyfr[0]=0 & wsk_cyfr[1]++);
    	        if (wsk_cyfr[1]>=6) (wsk_cyfr[1]=0 & wsk_cyfr[2]++);
    				if (wsk_cyfr[2]>=10) (wsk_cyfr[2]=0 & 	wsk_cyfr[3]++);
    					if (wsk_cyfr[3]>=6) (wsk_cyfr[3]=0 & wsk_cyfr[4]++);
    					if (wsk_cyfr[4]==9) (wsk_cyfr[4]=0 & wsk_cyfr[5]++);
    						if (wsk_cyfr[5]>=2 && wsk_cyfr[4]>=4) (wsk_cyfr[4]=0 & wsk_cyfr[5]-- & wsk_cyfr[5]--);
    						
    							
    
    	
    	TCNT1=0; // Zeruje wartość timera T1
     
    	  };
    	  
    	  
        if (TCNT0 >= 250)	// odliczanie x herców
    	{
        PORTC= wys[i];
        PORTA= cyfry[i][wsk_cyfr[k]];	
    	i++;
    	k++;
    
    	
    	TCNT0 = 0; // Zeruje wartość timera T0	
    		
    	if (i==6) (i=0);
    	if (k==6) (k=0);
    	
    	}
         } 
    return 0;
    }  
    



    W tym kodzie od Ciebie zmieniłem TCCR1B na TCTNT1 ponieważ jak wpisuje wartość zadaną do TCCR1B program nie startuje. Zapewne tu jest błąd gdyż nie za bardzo rozumiem linijke

    z twojego programu.
    Da się zapisać ustaloną wartość do rejestru tak żeby przerwanie od przepełnienia występowało właśnie od tej zadanej wartości, a nie od przepełnienia max rejestru. Myślę, że to by załatwiło sprawę.

    
    ISR(TIMER1_OVF_vect) // przerwanie od przepełnienia
    {
    TCCR1B=6250;
    licznik50ms++;
    	if(licznik50ms>=Potrzebne_50ms)
    		{
    			flaga_odbioru_DCF=true;
    			StopZliczania();
    		}
    }


    W programie chodzi o to, żeby dalsza część programu ruszyła dopiero jak wystąpi przerwa 1,5 sekundy czyli zastaje spełniony ten warunek...

    
      while(!flaga_odbioru_DCF)  //PETLA Z ODBIOREM DCF
       {
       PORTC=wys[3];
       PORTA=cyfry[3][3];
       };
    



    Reszta kodu jest OK. Chodzi mi tylko o policzeniu tego czasu żeby program mógł dalej działać.
    Widzisz co znowu źle zrobiłem??
    Pozdrawiam!
  • #8 7000356
    kwesoly
    Poziom 15  
    Na pewno:
    
    TCCR1B |= ((1 << CS11 | 1 << CS10)); //preskaler 64 z wartoscia 6250 daje 50ms czyli 20 hz 
    


    Kolejność operatorów, powinno być
    ((1 << CS11) | (1 << CS10)) 


    Dodano po 5 [minuty]:

    Kolejny błąd - tak to się kończy jak sie pisze z głowy :/

    Zamiast

    Powinno być


    Z kolei ty powtórzyłeś mój błąd:

    Powinno być:



    GICR |= (1<<INT0); // odblokowania przerwania INT0

    To jest nie potrzebne - nie odblokowuje przerwanie tylko ewentualnie likwiduje flagę gdyby przerwanie nastąpiło wcześniej.

    Napisz jaki masz kwarc/częstotliwość wewnętrznego, bo z Timerem1 nawet nie musisz się bawić w takie zliczanie.
  • #10 7000719
    Freddie Chopin
    Specjalista - Mikrokontrolery
    tmf napisał:
    Dlatego zamiast stosowac (1<<costam) lepiej zastosowac gotowe makra _BV(CS11) itd.

    Ja się chętnie dowiem, co takiego cudownego jest w tym makro, a co takiego beznadziejnego jest w standardowej rotacji?

    Potem gdy przyjdzie coś robić na innym układzie niż AVR, to pierwsze co jest na górze : #define _BV(x) (1<<x)

    bezsensu.

    4\/3!!
  • #11 7000792
    mslech
    Poziom 10  
    Kwarc którego używam to zewnętrzny 8Mhz. A ta się zastanawiam czy zamiast przerwania od przepełnienia ie powinno się użyć jakiegoś porównania wartości timera z w wartością w rejestrze??
  • #13 7000887
    kwesoly
    Poziom 15  
    mslech napisał:
    Kwarc którego używam to zewnętrzny 8Mhz. A ta się zastanawiam czy zamiast przerwania od przepełnienia ie powinno się użyć jakiegoś porównania wartości timera z w wartością w rejestrze??

    Tak, przy opadającym zboczu wyzerować i wyłączyć timer, przy rosnącym wyłączyć (i ewentualni wyzerować), gdziekolwiek w kodzie

    while(TCNT1<0xB71B); (Czekanie aż timer naliczy 1.5s). I rzeczywiście zapoznanie się datasheetem i rejestrami obsługującymi ułatwi znacznie pisanie.
  • #14 7000986
    mslech
    Poziom 10  
    Freddie Chopin - ja wiem, że w datasheet wszystko JEST NAPISANE, ale jest to mój pierwszy program i stąd mam wątpliwość ,ale nie do REJESTRÓW które powinienem użyć bo te sobie znajduje w dokumentacji, a do tego JAK mam ich użyć, a tego już w dokumentacji nie ma.
    Nie mam doświadczenia dlatego liczę na ludzi którzy już to robili i są w tym dobrzy.
  • #15 7001270
    Freddie Chopin
    Specjalista - Mikrokontrolery
    mslech napisał:
    Freddie Chopin - ja wiem, że w datasheet wszystko JEST NAPISANE, ale jest to mój pierwszy program i stąd mam wątpliwość ,ale nie do REJESTRÓW które powinienem użyć bo te sobie znajduje w dokumentacji, a do tego JAK mam ich użyć, a tego już w dokumentacji nie ma.

    Oczywiście, że jest napisane w dokumentacji jak używać układu / rejestrów. Chyba że szukasz tam gotowego kodu, który nadawałby się na Ctrl + C - Ctrl + V - taki faktycznie ciężko tam znaleźć.

    4\/3!!
  • #16 7001517
    tmf
    VIP Zasłużony dla elektroda
    Freddie Chopin napisał:
    tmf napisał:
    Dlatego zamiast stosowac (1<<costam) lepiej zastosowac gotowe makra _BV(CS11) itd.

    Ja się chętnie dowiem, co takiego cudownego jest w tym makro, a co takiego beznadziejnego jest w standardowej rotacji?

    Potem gdy przyjdzie coś robić na innym układzie niż AVR, to pierwsze co jest na górze : #define _BV(x) (1<<x)

    bezsensu.

    4\/3!!


    Wlasnie to jest cudownego, ze masz problemu z priorytetem operatorow.
    Moze jest to bez sensu, ale w takim wypadku myli sie tez wielu developerow WinAVR. Widze, ze masz kolego niezle ego.
  • #17 7001743
    Freddie Chopin
    Specjalista - Mikrokontrolery
    A ktoś ma problem z priorytetem operatorów? Ja po prostu wszystko zawsze piszę w nawiasie i problem nie istnieje.

    Takie rzeczy jak _BV, bit_is_set() i tym podobne to jak dla mnie jest mnożenie bytów ponad potrzebę - cokolwiek poważniejszego potem trzeba zrobić i już proste sprawdzenie bitu jest niesamowicie skomplikowane. I nie wyskakuj mi tu z jakimś "niezłym ego", bo to nie ma żadnego znaczenia.

    4\/3!!
  • #18 7002216
    mslech
    Poziom 10  
    warning: function declaration isn't a prototype
    - wyskakują mi takie 3 warningi, odnoszą się one do funkcji inline static void, czyli inicjacja, StartZliczania i StopZliczania.
    Szukałem odpowiedzi w dokumentacji, ale nic nie znalazłem. Wiecie co może być źle??
  • #20 7003843
    mslech
    Poziom 10  
    W poprzednim programie zmieniłem przerwanie od przepełnienia na przerwanie od porównania, ale program ciągle nie działa. Przy kompilacji nie ma już warningów i errorów. Siedzę nad tym kolejny dzień i już nie wiem co mam zrobić. Chyba za wysokie progi jak dla mnie. Widzicie gdzie tutaj jest jakiś błąd??

    
    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <stdbool.h>
    
    
    #define INT0PIN PIND 
    #define INT0NUM PD2
    #define GetINT0Pin() (INT0PIN & (1<<INT0NUM)) 
    #define Potrzebne_50ms 30
    
    volatile bool flaga_odbioru_DCF=false;
    volatile int licznik50ms=0; 
     
    inline static void inicjacja(void)
    { 
    GICR |= (1<<INT0); // odblokowania  przerwania INT0
    MCUCR |= (1<<ISC00); // przerwania załaczone na obydwa zbocza
    TCCR1B |= ((1 << CS11 | 1 << CS10)); //preskaler 64 z wartoscia 6250 daje 50ms czyli 20 hz
    TCCR1B |= (1 << WGM12); // tryb CTC
    OCR1A = 6250; //ustalona wartosc
    //OCR1A = 0xB71B;; //ustalona wartosc
    //TIMSK |= (1<<TOIE0); // odblkoowanie od przepełnienia licznika 1
    TIMSK |= (1 << OCIE1A); //przerwania od ctc
    }
    
      
    inline static void StartZliczania(void)
    {
    licznik50ms=0;
    TCCR1B |= ((1 << CS11) | (1 << CS10)); //preskaler 64 z wartoscia 6250 daje 50ms czyli 20 hz
    }
    
    inline static void StopZliczania(void)
    {
    licznik50ms=0;
    TCCR1B &= ~((1 << CS11) & (1 << CS10));
    }
    
    ISR(INT0_vect) //obsługa przerwania od INT0
    {
    if(GetINT0Pin())   // zbocze narastające
         StopZliczania();
    	else                   // zbocze opadające
      if (!flaga_odbioru_DCF) 
      StartZliczania();
    }
    
    ISR(TIMER1_COMPA_vect) // przerwanie od przepełnienia
    {
    
    
    licznik50ms++;
    	if(licznik50ms >= Potrzebne_50ms)
    		{
    			flaga_odbioru_DCF=true;
    			StopZliczania();
    		}
    }
    		 
    
    
    	
    int main (void){       
    DDRB=0xff; //PORT diody
    DDRC=0xff; //ustawienie portu sterowania wyświetlaczami
    DDRD=0xff;
    DDRA=0xff; //ustawienie portu sterowania segmantami
    PORTB=0xfe; //kiedy jest zasilanie swieci dioda
    
    
    
    unsigned char cyfry[6][10] = {
    {0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xf6},
    {0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xf6},
    {0xfd,0x61,0xdb,0xf3,0x67,0xb7,0xbf,0xe1,0xff,0xf7},
    {0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xf6},
    {0xfd,0x61,0xdb,0xf3,0x67,0xb7,0xbf,0xe1,0xff,0xf7},
    {0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xf6},
    }; 
    
    // deklaracja tablicy cyfr dla każdego wyświetlacza
    
    
    int wsk_cyfr[6]; // deklaracja zmiennej pomocniczej okreslającej jaka cyfra wystapi na danym wyświetlaczu
    unsigned char wys[6] = { 0xef,0xf7,0xfb,0xfd,0xfe,0xdf }; //adresy wyświetlaczy
         
     
     
    
    inicjacja();  
       
       
      
    if(!flaga_odbioru_DCF)  //PETLA Z ODBIOREM DCF
       {
       PORTC=wys[3];
       PORTA=cyfry[3][3];
       }
       else
       {
       
       
       
       while(1){   // POCZATEK GŁÓWNEJ PĘTLI 
       
       wsk_cyfr[0]=0; //
       wsk_cyfr[1]=5; //
       wsk_cyfr[2]=9; //    POCZĄTKOWE CYFRY NA WYŚWIETLACZACH
       wsk_cyfr[3]=5; //
       wsk_cyfr[4]=3; //
       wsk_cyfr[5]=2; //
       
       cli();
       int i=0;
       int k=0; 
       
       TCCR0 |= ((1 << CS00 | 1 <<CS01)); // Ustawienie timera T0 do podstawy  dla wyświetlaczy prseskaler 64
       TCCR1B |= (1 << CS12); //ustawienie timera T1 do odliczania 1s presacalekr 256
        
    	
    	if (TCNT1 >=31250) // odliczanie sekund
    	{
    	
    	wsk_cyfr[0]++; // kontrola nad wyświetlaczami
    	
    	  if (wsk_cyfr[0]>=10) (wsk_cyfr[0]=0 & wsk_cyfr[1]++);
    	        if (wsk_cyfr[1]>=6) (wsk_cyfr[1]=0 & wsk_cyfr[2]++);
    				if (wsk_cyfr[2]>=10) (wsk_cyfr[2]=0 & 	wsk_cyfr[3]++);
    					if (wsk_cyfr[3]>=6) (wsk_cyfr[3]=0 & wsk_cyfr[4]++);
    					if (wsk_cyfr[4]==9) (wsk_cyfr[4]=0 & wsk_cyfr[5]++);
    						if (wsk_cyfr[5]>=2 && wsk_cyfr[4]>=4) (wsk_cyfr[4]=0 & wsk_cyfr[5]-- & wsk_cyfr[5]--);
    							
    	TCNT1=0; // Zeruje wartość timera T1
     
    	  };
    	  	  
        if (TCNT0 >= 250)	// odliczanie x herców
    	{
        PORTC= wys[i];
        PORTA= cyfry[i][wsk_cyfr[k]];	
    	i++;
    	k++;
    	
    	TCNT0 = 0; // Zeruje wartość timera T0	
    		
    	if (i==6) (i=0);
    	if (k==6) (k=0);	
    	}
         }
    		}
    return 0;
    }   
    


    Pomożecie ostatni raz??
  • #21 7003905
    Freddie Chopin
    Specjalista - Mikrokontrolery
    1. Inicjacja to może być seksualna, zmienne, procesory i tym podobne się inicjaLIZUje - init to skrót od init_ialize, a nie od init_iate.

    2. Czemu wszyscy chcą pisać programy po polsku? Jakbyś teraz chciał to wrzucić na zagraniczne forum i spytać o pomoc to zapomnij...

    3. Wcięcia w tym kodzie to tragedia, gdyby nie edytory z podświetleniem to nikt by tego nie zrozumiał. Oczywiście poza wcięciami to kod jest napisany skrajnie nieczytelnie...

    4. zasadniczo:

    
    ...
    volatile bool flaga_odbioru_DCF=false; 
    ...
    int main (void){
    ...
    if(!flaga_odbioru_DCF)
       { 
       PORTC=wys[3]; 
       PORTA=cyfry[3][3]; 
       }
    else
    {
    ...
    }
    return 0; 
    } 
    


    skoro flaga jest fałszem, to twój kod zalicza ciągły reset po wyjściu z funkcji main. A tak BTW to przerwania nigdy ci nie zadziałają, bo masz je wyłączone (cli())

    Następny kod do analizy napisz po ludzku i sformatuj jakoś normalnie, bo tego to się czytać nie da. Sam się już chyba pogubiłeś w tym milionie poziomów zagłębienia.

    4\/3!!
  • #22 7005976
    mslech
    Poziom 10  
    Ponownie załączam kod który mi ciągle nie rusza. Wydaje mi się, że problem jest w tym, że zmienna flaga_odbioru_DCF nie zmienia wartości i przez to program nie rusza dalej.

    Fredie Chopin - staram się jak mogę, ale jest to mój pierwszy program, ty też się kiedyś uczyłeś i twoje progi od początku też nie wyglądały pięknie więc bądź trochę bardziej dla mnie wyrozumiały. Według twoich sugestii pozmieniałem kod, ale eni wiem czy o to Ci chodziło.

    Wiem też, że problem nie jest sprzętowy(ponieważ proste programy potwierdzą obecność sygnału), kompilator też jest dobry(sprawdzałem bo czytałem, że w niektórych wersjach avr gcc był problem z przerwaniami).

    Stawiam skrzynkę piwa dla tego kto znajdzie błąd.

    
    #include <avr/io.h>
    #include <avr/interrupt.h>
    
    #define INT0PIN PIND 
    #define INT0NUM 2
    #define GetINT0Pin() (INT0PIN & (1<<INT0NUM)) 
    #define Potrzebne_50ms 25
    
    
    
    volatile int licznik50ms=0; 
    volatile int flaga_odbioru_DCF=0; 
      
     
    inline static void init(void)
    { 
    GICR |= (1<<INT0); // odblokowania  przerwania INT0
    MCUCR |= (1<<ISC00); // przerwania załaczone na obydwa zbocza
    TCCR1B |= ((1 << CS11 | 1 << CS10)); //preskaler 64 z wartoscia 6250 daje 50ms czyli 20 hz
    TCCR1B |= (1 << WGM12); // właczenie trybu CTC
    OCR1A = 6250; //wpisanie wartosći do porównania
    TIMSK |= (1 << OCIE1A); //właczenie przerwań od przerwania ctc
    sei();
    }
    
      
    inline static void StartZliczania(void)
    {
    licznik50ms=0;
    TCCR1B |= ((1 << CS11) | (1 << CS10)); //preskaler 64 z wartoscia 6250 daje 50ms czyli 20 hz
    }
    
    
    inline static void StopZliczania(void)
    {
    licznik50ms=0;
    TCCR1B &= ~((1 << CS11) & (1 << CS10));
    }
    
    
    ISR(INT0_vect) //obsługa przerwania od INT0
    {
    if(GetINT0Pin())   // zbocze narastające 
         StopZliczania();
    	else                   // zbocze opadające
      if (flaga_odbioru_DCF==0) 
      StartZliczania();
    }
    
    
    ISR(TIMER1_COMPA_vect) // przerwanie od przepełnienia
    {
    licznik50ms++;
    	if(licznik50ms >= Potrzebne_50ms)
    		{
    			flaga_odbioru_DCF++;
    			StopZliczania();			
    		}
    }
    		 
    
    
    	
    int main (void){       
    DDRB=0xff; //PORT diody
    DDRC=0xff; //ustawienie portu sterowania wyświetlaczami
    DDRD=0xff;
    DDRA=0xff; //ustawienie portu sterowania segmantami
    PORTB=0xfe; //kiedy jest zasilanie swieci dioda
    
    int i=0;  ///
    int k=0;  ///ZMIENNE POMOCNICZE
    
    
    int wsk_cyfr[6]; // deklaracja zmiennej pomocniczej okreslającej jaka cyfra wystapi na danym wyświetlaczu
    unsigned char wys[6] = { 0xef,0xf7,0xfb,0xfd,0xfe,0xdf }; //adresy wyświetlaczy
         
    
    unsigned char cyfry[6][10] = {
    {0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xf6},
    {0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xf6},
    {0xfd,0x61,0xdb,0xf3,0x67,0xb7,0xbf,0xe1,0xff,0xf7},
    {0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xf6},
    {0xfd,0x61,0xdb,0xf3,0x67,0xb7,0xbf,0xe1,0xff,0xf7},
    {0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xf6},
    }; 
    
    // deklaracja tablicy cyfr dla każdego wyświetlacza
    
    
     
     
    
    init();  
       
        
    if(flaga_odbioru_DCF==0)  //PETLA Z ODBIOREM DCF
       {
       PORTC=wys[3];
       PORTA=cyfry[3][3];
       }   
    // PROGRAM OD TEGO MOMENTU DZIAŁA I NIE TUTAJ JEST RACZEJ PROBLEM PONIEWAZ PRZY WPISANIU
    // NA SZTYWNO 1 DO ZMIENNEJ flaga_odbioru_DCF PROGRAM RUSZA DALEJ. COŚ MUSI BYĆ NIE TAK
    // W KODZIE POWYŻEJ TEGO KOMENTARZA I NIE WIEM Co.
       else
       {
       
       
       
     while(1){   // POCZATEK GŁÓWNEJ PĘTLI 
       
       wsk_cyfr[0]=0; //
       wsk_cyfr[1]=5; //
       wsk_cyfr[2]=9; //    POCZĄTKOWE CYFRY NA WYŚWIETLACZACH
       wsk_cyfr[3]=5; //
       wsk_cyfr[4]=3; //
       wsk_cyfr[5]=2; //
       
      // cli();
    
       
       TCCR0 |= ((1 << CS00 | 1 <<CS01)); // Ustawienie timera T0 do podstawy  dla wyświetlaczy prseskaler 64
       TCCR1B |= (1 << CS12); //ustawienie timera T1 do odliczania 1s presacalekr 256
        
    	
    	if (TCNT1 >=31250) // odliczanie sekund
    	{
    	
    	wsk_cyfr[0]++; // kontrola nad wyświetlaczami
    	
    	if (wsk_cyfr[0]>=10) (wsk_cyfr[0]=0 & wsk_cyfr[1]++);
    		if (wsk_cyfr[1]>=6) (wsk_cyfr[1]=0 & wsk_cyfr[2]++);
    			if (wsk_cyfr[2]>=10) (wsk_cyfr[2]=0 & wsk_cyfr[3]++);
    				if (wsk_cyfr[3]>=6) (wsk_cyfr[3]=0 & wsk_cyfr[4]++);
    					if (wsk_cyfr[4]==9) (wsk_cyfr[4]=0 & wsk_cyfr[5]++);
    if (wsk_cyfr[5]>=2 && wsk_cyfr[4]>=4) (wsk_cyfr[4]=0 & wsk_cyfr[5]-- & wsk_cyfr[5]--);
    							
    	TCNT1=0; // Zeruje wartość timera T1
     
    	};
    	if (TCNT0 >= 250)	// odliczanie x herców
    	{
    		PORTC= wys[i];
    		PORTA= cyfry[i][wsk_cyfr[k]];	
    		i++;
    		k++;	
    		TCNT0 = 0; // Zeruje wartość timera T0	
    	           if (i==6) (i=0);
    		  if (k==6) (k=0);
    		}
         }
      }
    return 0;
    }   
    

    POMOCY!!!
  • #23 7006362
    Freddie Chopin
    Specjalista - Mikrokontrolery
    Nie sądzisz chyba że dojście od końca funkcji init() - czyli tego miejsca:

    init();
    ->

    Do tego warunku:

    if(flaga_odbioru_DCF==0) //PETLA Z ODBIOREM DCF

    zajmuje twojemu mikrokontrolerowi 6250 * 64 cykli?

    Zanim wystąpi przerwanie sprawdzasz czy flaga == 0 -> skoro jest, wykonujesz dwie instrukcje, return 0, wyjście z main, reset i od poczatku. Ten program jest źle napisany. Pomijam już nawet kwestię formatowania (tragedia!) - błąd masz w swoich założeniach. Twój program NIGDY nie dojdzie do tej "pętli głównej", skoro wejście do niej uzależniasz od pewnego warunku, a w przeciwnym wypadku następuje reset.

    Pętla główna powinna być ZEWNĘTRZNA, a nie zabezpieczona warunkami, których następstwem jest reset.

    Skoro to twoje początki, to może pomyśl nad czymś prostszym.

    Zrozum to - nie przerabiaj tego programu, tylko wykasuj go i napisz od nowa, dobrze.

    4\/3!!
  • #24 7006633
    BoskiDialer
    Poziom 34  
       if (wsk_cyfr[0]>=10) (wsk_cyfr[0]=0 & wsk_cyfr[1]++); 
          if (wsk_cyfr[1]>=6) (wsk_cyfr[1]=0 & wsk_cyfr[2]++); 
             if (wsk_cyfr[2]>=10) (wsk_cyfr[2]=0 & wsk_cyfr[3]++); 
                if (wsk_cyfr[3]>=6) (wsk_cyfr[3]=0 & wsk_cyfr[4]++); 
                   if (wsk_cyfr[4]==9) (wsk_cyfr[4]=0 & wsk_cyfr[5]++); 
    if (wsk_cyfr[5]>=2 && wsk_cyfr[4]>=4) (wsk_cyfr[4]=0 & wsk_cyfr[5]-- & wsk_cyfr[5]--);

    Nie chce mi się czytać całego tematu, ale razi mnie ten zapis. W jakim kursie uczą takiego zapisu? Klamry i średniki a nie nawiasy i "&". Taki zapis jest "błędo-genny" - od strony składni wygląda to jak przypisanie (analizując pierwszą linię) wartości "0 & wsk_cyfr[1]++" do wsk_cyfr[0] - po zamianie 0 po prawej stronie na pewno nie zawsze zostanie przypisana żądana wartość.
  • #25 7020968
    mslech
    Poziom 10  
    Program napisałem mniej więcej od nowa.
    Wygląda tak:
    
    #include <avr/io.h>
    #include <avr/interrupt.h>
    
    #define Potrzebne_50ms 33
    
    volatile int licznik50ms=0; 
    volatile int SygnalDCF=0; //0 - szukamy szczeliny początku transmisji, 1 - dekodujemy sygnał, 2 -koniec ramki DCF
    volatile int zbocze1=0;  //0 - szukamy opadającego, 1 - narastającego 
    volatile int zbocze2=0;  //0 - szukamy opadającego, 1 - narastającego 
    volatile int ramkaDCF[58];
    volatile int nrbitu=0;
    volatile int j_m; 	//jednostki minut			
    volatile int d_m; 	//dziesiątki minut		
    volatile int j_h; 	//jednostki godzin		
    volatile int d_h; 	//dziesiątki godzin
    
    
    ////////////////////////////INICJALIZACJA////////////////////////
    inline static void init(void)
    { 
    
    DDRB=0xff; //PORT diody
    DDRC=0xff; //ustawienie portu sterowania wyświetlaczami
    DDRD=0xff;
    DDRA=0xff; //ustawienie portu sterowania segmantami
    PORTB=0xfe; //kiedy jest zasilanie swieci dioda
    
    MCUCR=0;
    MCUCR |= (1<<ISC01); //przerwanie na zbocze opadajace
    GICR |= (1<<INT0); // odblokowania  przerwania INT0
    
    OCR1B=50000; //wartosc do porownania
    TCCR1B |= (1<<WGM12); //w tryb ctc
    TIMSK =0;
    TIMSK	|= (1<<OCIE1B); // odblokowanie przerwan od porownania COMP B
    
    sei(); //globalne odblokowanie przerwań
    }
    
    
    
    ////////////////////////PRZEŁĄCZ NA ZBOCZE NARASTAJĄCE//////////////////
    inline static void ZboczeNarastajace(void)
    {	 
     MCUCR=0;
     MCUCR |= ((1<<ISC00) | (1<<ISC01)); //załaczenie przerwania na zbocze narastajce
    }
    
    
    
    
    ////////////////////////PRZEŁĄCZ NA ZBOCZE OPADAJĄCE//////////////////
    inline static void ZboczeOpadajace(void)
    {	 
     MCUCR=0;
     MCUCR |= (1<<ISC01); //zalaczenia na zbocze opadajace;
    }
    
    
    
    
    ////////////////////////START TIMERA//////////////////
    inline static void StartZliczania(void)
    {
    licznik50ms=0;
    TCCR1B |= (1 << CS11); //właczenie licznika z preskalerem 8
    }
    
    
    
    
    ////////////////////////STOP TIMERA//////////////////
    inline static void StopZliczania(void)
    {
    licznik50ms=0;
    TCCR1B &= ~(1 << CS11); //wyłączenie licznika
    }
    
    
    
    ////////////////////////START TIMERA2//////////////////
    inline static void StopZliczania2(void)
    {
    TCCR1B &= ~(1 << CS11); //wyłączenie licznika
    }
    
    
    
    
    
    ////////////////////////ROZKODOWANIE BITU//////////////////
    inline static void RozkodujBit(void)
    {
    float czas,czas_z_rejestru;
    czas_z_rejestru=TCNT1;
    czas=(50*licznik50ms)+(czas_z_rejestru*0.001);
    
    if(czas>50 && czas<150) {ramkaDCF[nrbitu]=0;}
    else if(czas>150 && czas<250) {ramkaDCF[nrbitu]=0;}
      else SygnalDCF=0;
    }
    
    
    
    
    //////////////////////////////ZAMIENIA Z DWOJKOWEGO NA DZIESIETNY////////////
    inline static void ZdwojkowegoNadziesietny(void)
    {   if (ramkaDCF[25]==0 && ramkaDCF[24]==0 && ramkaDCF[23]==0 && ramkaDCF[22]==0)
        {j_m=0;} else 
    	if (ramkaDCF[25]==0 && ramkaDCF[24]==0 && ramkaDCF[23]==0 && ramkaDCF[22]==1)
        {j_m=1;} else 
    	if (ramkaDCF[25]==0 && ramkaDCF[24]==0 && ramkaDCF[23]==1 && ramkaDCF[22]==0)
        {j_m=2;} else 
    	if (ramkaDCF[25]==0 && ramkaDCF[24]==0 && ramkaDCF[23]==1 && ramkaDCF[22]==1)
        {j_m=3;} else 
    	if (ramkaDCF[25]==0 && ramkaDCF[24]==1 && ramkaDCF[23]==0 && ramkaDCF[22]==0)
        {j_m=4;} else 
    	if (ramkaDCF[25]==0 && ramkaDCF[24]==1 && ramkaDCF[23]==0 && ramkaDCF[22]==1)
        {j_m=5;} else 
    	if (ramkaDCF[25]==0 && ramkaDCF[24]==1 && ramkaDCF[23]==1 && ramkaDCF[22]==0)
        {j_m=6;} else 
    	if (ramkaDCF[25]==0 && ramkaDCF[24]==1 && ramkaDCF[23]==1 && ramkaDCF[22]==1)
        {j_m=7;} else 
    	if (ramkaDCF[25]==1 && ramkaDCF[24]==0 && ramkaDCF[23]==0 && ramkaDCF[22]==1)
        {j_m=8;} else 
    	if (ramkaDCF[25]==1 && ramkaDCF[24]==0 && ramkaDCF[23]==0 && ramkaDCF[22]==1)
        {j_m=9;} else SygnalDCF=0;
    	
    	if (ramkaDCF[28]==0 && ramkaDCF[27]==0 && ramkaDCF[26]==0)
        {d_m=0;} else 
    	if (ramkaDCF[28]==0 && ramkaDCF[27]==0 && ramkaDCF[26]==1)
        {d_m=0;} else
    	if (ramkaDCF[28]==0 && ramkaDCF[27]==1 && ramkaDCF[26]==0)
        {d_m=0;} else
    	if (ramkaDCF[28]==0 && ramkaDCF[27]==1 && ramkaDCF[26]==1)
        {d_m=0;} else
    	if (ramkaDCF[28]==1 && ramkaDCF[27]==0 && ramkaDCF[26]==0)
        {d_m=0;} else
    	if (ramkaDCF[28]==1 && ramkaDCF[27]==0 && ramkaDCF[26]==1)
        {d_m=0;} else SygnalDCF=0;
    	
    	if (ramkaDCF[33]==0 && ramkaDCF[32]==0 && ramkaDCF[31]==0 && ramkaDCF[30]==0)
        {j_h=0;} else 
    	if (ramkaDCF[33]==0 && ramkaDCF[32]==0 && ramkaDCF[31]==0 && ramkaDCF[30]==1)
        {j_h=1;} else 
    	if (ramkaDCF[33]==0 && ramkaDCF[32]==0 && ramkaDCF[31]==1 && ramkaDCF[30]==0)
        {j_h=2;} else 
    	if (ramkaDCF[33]==0 && ramkaDCF[32]==0 && ramkaDCF[31]==1 && ramkaDCF[30]==1)
        {j_h=3;} else 
    	if (ramkaDCF[33]==0 && ramkaDCF[32]==1 && ramkaDCF[31]==0 && ramkaDCF[30]==0)
        {j_h=4;} else 
    	if (ramkaDCF[33]==0 && ramkaDCF[32]==1 && ramkaDCF[31]==0 && ramkaDCF[30]==1)
        {j_h=5;} else 
    	if (ramkaDCF[33]==0 && ramkaDCF[32]==1 && ramkaDCF[31]==1 && ramkaDCF[30]==0)
        {j_h=6;} else 
    	if (ramkaDCF[33]==0 && ramkaDCF[32]==1 && ramkaDCF[31]==1 && ramkaDCF[30]==1)
        {j_h=7;} else 
    	if (ramkaDCF[33]==1 && ramkaDCF[32]==0 && ramkaDCF[31]==0 && ramkaDCF[30]==1)
        {j_h=8;} else 
    	if (ramkaDCF[33]==1 && ramkaDCF[32]==0 && ramkaDCF[31]==0 && ramkaDCF[30]==1)
        {j_h=9;} else SygnalDCF=0; 
    	
    	if (ramkaDCF[35]==0 && ramkaDCF[34]==0 )
        {j_h=0;} else 
    	if (ramkaDCF[34]==0 && ramkaDCF[35]==1 )
        {j_h=9;} else 
    	if (ramkaDCF[35]==1 && ramkaDCF[34]==0 )
        {j_h=0;} else SygnalDCF=0; 
    	
    }
    
    
    
    
    ////////////////////////SPARWDZENIE POPRAWNOŚCI ODEBRANJE RAMKI//////////////////
    inline static void SprawdzPoprawnosc(void)
    {
    }
    
     
    //////////////////////START ZEGARA/////////////////////////
    inline static void Zegar(void)
    {
    int i=0;  /// ZMIENNE POMOCNICZE
    int k=0;
    
    
    int wsk_cyfr[6]; // deklaracja zmiennej pomocniczej okreslającej jaka cyfra wystapi na danym wyświetlaczu
    unsigned char wys[6] = { 0xef,0xf7,0xfb,0xfd,0xfe,0xdf }; //adresy wyświetlaczy
         
    
    unsigned char cyfry[6][10] = {
    {0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xf6},
    {0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xf6},
    {0xfd,0x61,0xdb,0xf3,0x67,0xb7,0xbf,0xe1,0xff,0xf7},
    {0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xf6},
    {0xfd,0x61,0xdb,0xf3,0x67,0xb7,0xbf,0xe1,0xff,0xf7},
    {0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xf6},
    }; 
    
    // deklaracja tablicy cyfr dla każdego wyświetlacza
    
     wsk_cyfr[0]=0; 			//
     wsk_cyfr[1]=0; 				//
     wsk_cyfr[2]=j_m; 				//    POCZĄTKOWE CYFRY NA WYŚWIETLACZACH
     wsk_cyfr[3]=d_m; 			//
     wsk_cyfr[4]=j_h; 			//
     wsk_cyfr[5]=d_h; 			//
    
    
    
     TCCR0 |= ((1 << CS00 | 1 <<CS01)); // Ustawienie timera T0 do podstawy  dla wyświetlaczy prseskaler 64
     TCCR1B |= (1 << CS12); //ustawienie timera T1 do odliczania 1s presacalekr 256
    
    
    
    if (TCNT1 >=31250) // odliczanie sekund
    		{
    	
    		wsk_cyfr[0]++; // kontrola nad wyświetlaczami
    	
    			if (wsk_cyfr[0]>=10) {wsk_cyfr[0]=0;
    								  wsk_cyfr[1]++;};
    				if (wsk_cyfr[1]>=6) {wsk_cyfr[1]=0; 
    									 wsk_cyfr[2]++;};
    					if (wsk_cyfr[2]>=10) {wsk_cyfr[2]=0;
    											wsk_cyfr[3]++;};
    						if (wsk_cyfr[3]>=6) {wsk_cyfr[3]=0;
    											  wsk_cyfr[4]++;};
    							if (wsk_cyfr[4]==9) {wsk_cyfr[4]=0;
    												  wsk_cyfr[5]++;};
    								if (wsk_cyfr[5]>=2 && wsk_cyfr[4]>=4) {wsk_cyfr[4]=0;
    																		 wsk_cyfr[5]=0;};
    						
    							
    
    	
    			TCNT1=0; // Zeruje wartość timera T1
     
    		};
    		
    		
    		if (TCNT0 >= 250)	// odliczanie x herców
    		{
    			PORTC= wys[i];
    			PORTA= cyfry[i][wsk_cyfr[k]];	
    			i++;
    			k++;
    			
    			TCNT0 = 0; // Zeruje wartość timera T0			
    			if (i==6) (i=0);
    			if (k==6) (k=0);
    	
    		}
    }
    
    
    
    
    ////////////////////////PRZERWANIE OD INT0////////////////// 
    ISR(INT0_vect) //obsługa przerwania od INT0
    {
     switch(SygnalDCF)
      {
       
       case 0:
    		{
    		  if (zbocze1==0) 
    			{ StartZliczania();
    			ZboczeNarastajace();
    			zbocze1=1;
    			} 
    			else
    			{ StopZliczania();
    			ZboczeOpadajace();
    			zbocze1=0;
    			};
    		break;
    		}
       case 1:
    		{
    			if (zbocze2==1) 
    			{
    			TCNT1=0;
    			StartZliczania();
    			ZboczeOpadajace();
    			zbocze2=0;
    			} 
    			else
    			{ StopZliczania2();
    			nrbitu++;
    			if(nrbitu==58)
    				{ SygnalDCF=2;
    				  ZdwojkowegoNadziesietny();
    				  SprawdzPoprawnosc();
    				  RozkodujBit();};
    			ZboczeNarastajace();
    			zbocze2=1;
    			};
    		break;
    		}
    		
    	case 2:
    		{
    	      cli();
    		break;  
    		}  
        }
    }
    
    
    
    ////////////////////////PRZERWANIE OD TIMER1 POROWNANIE//////////////////
    
    ISR(TIMER1_COMPB_vect) // przerwanie od przepełnienia
    {
     switch(SygnalDCF)
       {
        case 0:
    	{
    	licznik50ms++; //licznik + 1
    	TCNT1=0;       //zerowanie rejestru
    	if (licznik50ms>=Potrzebne_50ms) 
    		{ SygnalDCF=1;
    		  ZboczeNarastajace();
    		  zbocze2=1;};
    	break;
    	}
    	case 1:
    	{
    	licznik50ms++;
    	TCNT1=0;	 
    	break;
    	}
    	case 2:
    	{
    	cli();
    	break;
    	}
       }
    }
    
    
    ////////////////////////PĘTLA GŁÓWNA/////////////////
    int main (void)
    {
    init();
    
    while(1)
     {
    	switch(SygnalDCF)
       { 
       case 0:
       {
       PORTA=0xfc;
       PORTC=0xfb;
       break;
       }
       case 1:
       {
       PORTA=0xb6;
       PORTC=0xfb;
       break;
       }
       case 2:
       {
       Zegar();
       break;
       }
       }	
     }
    
    
    return 0; 
    } 
    


    Jak miałem same przerwania to program działał. Po dopisaniu kilku funkcji, program znowu nie znajduje mi szczeliny 1500ms, albo znajduje ją ale nie zmienia zmiennej SygnalDCF na 1 tylko ciągle ma wartość 0.
    Widzicie błąd??
  • #26 7021001
    Freddie Chopin
    Specjalista - Mikrokontrolery
    Skoro działało i nagle przestało działać, to proponuję dodawać funkcje po jednej, a nie 100 na raz i potem dziwić się, że przestaje działać.

    P.S. nad wcięciami wciąż musisz popracować - chyba sam nie rozumiesz tego kodu... Z tego względu raczej nie licz na specjalną pomoc, ponieważ to wszystko jest tak napisane, że w ogóle nie wiadomo o co chodzi ani "co z czym".

    4\/3!!
REKLAMA