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

[atmega][avrgcc]przerwanie INT0 z PCF8583

jacekr 20 Sty 2010 11:53 3603 7
  • #1 7562945
    jacekr
    Poziom 12  
    Witam
    Na początek napisze ze jestem początkujący w C. "Napisałem" program który czyta czas i datę z PCF8583 i pokazuje to na LCD.I wszystko byłoby ok gdyby nie to ze dla testu na przerwaniu procesor ma generować krotki sygnał dźwiękowy co 1 sek. i "prawie" jest ok TYLKO raz na jakiś czas nie chce piknąć na mijającą sekundę, tak jakby gubił te sekundę. Nadmienię ze od strony PCB jest wszystko OK bo w Bascomie to działa.Problem mam w C
    Uzywam WinAVR-20100110

    
    #include <avr/io.h>
    #include <inttypes.h>
    #include <avr/pgmspace.h>
    #include "delay.h"
    #include <avr/interrupt.h>
    #include <pcf8583.h>
    #include <hd44780.c>
    
    
    /* ------------------------------------------------------------------------- */
    /*			Deklaracje tablic i zmiennych			     */
    /* ------------------------------------------------------------------------- */
    
    uint8_t ssek,sek,min,godz,dzien,mies;   /* aktualny czas                       */
    int16_t rok;
    
    volatile unsigned char fzegar; //flaga odswieTenia stanu zegara na LCD
    
    SIGNAL(SIG_INTERRUPT0)
    {
    fzegar=1; //ustaw flage odczytania danych
    }
    
    
    int main(void)
    {
    /* PB1 wyjście - buzzer z generatorem */
      DDRB = 0x02;
      _delay_ms(200);
    	PORTB^=0x02;				//ustawia bit 0x02
    
    GIMSK=1<<INT0; //włacz przerwanie zewnetrzne INT0
    MCUCR=0x02; //przerwania INT0 wyzwalane opadajacym zboczem
    
     PCF8583_init();			// inicjowanie ukladu PCF8583
    LCD_Initalize();
    LCD_Clear();
     PCF8583_start();		// uruchomienie zegara w ukladzie PCF8583
    sei();		//wlacz przerwania
    while(1)
    {
    
    
    
    	LCD_GoTo(0,0);
    	lcd_put_time();
    	LCD_GoTo(0,1);
    	lcd_put_date();
    
    
    if(fzegar) //czy moTna odswieTyc czas na LCD
    {
    fzegar=0;
    		PORTB^=0x02;
           _delay_ms(25);
    		PORTB^=0x02;
    
    }	
    
    
    }
    return 0;
    }
    
    
    
    
  • #2 7563249
    mirekk36
    Poziom 42  
    Po pierwsze bardzo ciekawy jestem po co ci to _dela_ms(xx) w poniższym kawałku kodu , chociaż to akurat nie ma większego związku z tematem ale:

      DDRB = 0x02; 
      _delay_ms(200); 
       PORTB^=0x02;


    po drugie , kto wie co ty masz w tych swoich procedurach typu:

    PCF8583_init();


    po trzecie - używaj konstrukcji przerwania ISR a nie SIGNAL

    po czwarte jak ja bym miał na chwilkę "pipnąć" buzzerem to bym to napisał tak:

    #define BUZZER (1<<PB2)
    
         PORTB |= BUZZER; 
           _delay_ms(25); 
          PORTB &= ~BUZZER; 


    zakładając że aktywujesz go JEDYNKą

    po kolejne sprawdź właśnie czy poprawnie inicjalizujesz PCFxxxx odpowiednio ustawiając jego rejestr kontrolny - bo tego tu nie widać
  • #3 7563346
    jacekr
    Poziom 12  
    już uzupełniam :

    a.d.1 to pozostało po przeróbkach ;)
    a.d.2 to jest z Rklibavr Autor: Robert Krysztof
    
    void PCF8583_init(void)
    {
      PCF8583_status=0;
      PCF8583_alarm=0;
      PCF8583_write(0,0);
      PCF8583_write(4,PCF8583_read(4)&0x3f);
      PCF8583_write(8,0x90);
    }
    


    a.d.3 jako ze jestem początkujący to po prostu robię kopiuj i wklej z innych przykładów ;) nie do końca rozumiejąc o co chodzi (C to czarna magia na razie jeszcze).prosiłbym o przykład konstrukcji przerwania ISR.

    a.d.4 można i tak, I tak "pipka" sobie moja atmega tylko ze raz na jakiś czas gubi "pipniecie" i 1-2 sekundy na lcd uciekną a pipniecia nie ma.

    w załączeniu cały katalog tego "projektu"
  • Pomocny post
    #4 7563909
    mirekk36
    Poziom 42  
    jacekr napisał:
    jako ze jestem początkujący to po prostu robię kopiuj i wklej z innych przykładów ;) nie do końca rozumiejąc o co chodzi (C to czarna magia na razie jeszcze).


    dlatego przydałby ci się jakiś dobry kurs C ;)

    A w uproszczeniu jak zamienić SIGNAL na ISR - po prostu na razie zamiast SIGNAL pisz ISR tylko podawaj nieco inne nazwy wektorów tych przerwań. .... Oj do omawiania z tobą byłoby tyle że można by książkę napisać albo jakiś kurs przeprowadzić ;) ...... bo ciężko jest uczyć się tak metodą "copy & past" jeśli chodzi o używanie jakiś tam czasem dziwacznych bibliotek z netu.

    powodzenia
  • #5 7564544
    Krauser
    Poziom 26  
    Piszesz, że co sekundę odświeżasz LCD a po sprawdzeniu poniższego warunku są tylko linie odpowiedzialne za buzzer.
    if(fzegar) //czy mozna odswiezyc czas na LCD 

    Wyświetlacz odświeżany jest cały czas i pewnie to zajmuje więcej niż 1 sekundę.
    Przykład na sterowanie buzzerem który podał mirekk36 jest bardziej czytelny, a to zmiana stanu PORTB.1 na przeciwny. Tak działa operator bitowy ^ - suma modulo w takim układzie tzn. tam gdzie 1 zmienia na przeciwny a tam gdzie 0 nic nie zmienia.
  • #6 7564559
    mirekk36
    Poziom 42  
    poza tym daj to swoje odświeżanie czasu:

       LCD_GoTo(0,0); 
       lcd_put_time(); 
       LCD_GoTo(0,1); 
       lcd_put_date(); 


    także w tym if(fzegar)

    żeby wyświetlanie było co sekundę a nie "milion razy na sekundę" w pętli głównej tak jak w tej chwili
  • Pomocny post
    #7 7564571
    Einherjer
    Poziom 12  
    Dziwię się, że makro SIGNAL w ogóle działa, u mnie w nowszych wersjach avr-gcc nie generowało kodu, mimo, że przy kompilacji nie było błędu. Zamiast makr SIGNAL i INTERRUPT wprowadzono makro ISR (od Interrupt Service Routine), piszesz po prostu ISR(nazwa_przerwania_z_dokumentacji_vect). W Twoim przypadku to będzie ISR(INT0_vect)
    {
    ...
    }
  • #8 7564710
    jacekr
    Poziom 12  
    Dziękuje wszystkim za pomoc a zwłaszcza za wskazanie do nowego sposobu odwołania się do przerwań "ISR". Nigdzie tego nie dało się wyczytać nawet w książkach ;)
    I dlatego ze był problem z przerwaniem to wyświetlanie było "milion razy na sek" w głównej pętli , bo w przerwaniu nie chciało mi nic pokazać na lcd a po zmianie na ISR DZIALA :)

    p.s.
    Tak wogole nie jestem aż tak zielony bo ale tylko co nieco z ASM tez kumam :) , ale przyszedł czas na przesiadkę na C ze względu ze w bascomie w skomplikowanych projektach zaczynało brakować po prostu miejsca.
REKLAMA