Elektroda.pl
Elektroda.pl
X

Wyszukiwarki naszych partnerów

Wyszukaj w ofercie 200 tys. produktów TME
Proszę, dodaj wyjątek elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

[ATMEGA32][C]Gdzie zapisać ustaw. czasu do PCF8583 czy 24C02

margas4542 27 Paź 2010 19:11 2369 23
  • #1 27 Paź 2010 19:11
    margas4542
    Poziom 16  

    Witam ponownie. Mówią nie chwal dnia przed zachodem słońca...jak z jednym się uporałem to znów co innego mi mąci. Kłopot z wyborem gdzie zapisać nastawy dwukanałowego timera bo zmiennych jednocyfrowych jest łącznie 4x4 dziesiątki godzin , jednostki godzin , dziesiątki minut , jednostki minut osobno dla włącz osobno wyłącz razy dwa kanały.Ma do wyboru PCF8583 ale obawiam się że to się nie zmieści albo eeproma 24C02 co do którego też mam małe wątpliwości....druga sprawa to kłopoty w programie z lokalnymi zmiennymi [komunikatami txt] wyświetlanymi z zależności od spełnienia warunków danej funkcji...wrzucam cały kod programu który w 90% procentach chodzi.....programistów zapewne zaboli głowa...ale może poradzą jak go zoptymalizować......gwiazdki to problemy...

    Code:

    //#######################################
    //########## A T M E G A _ 3 2 ##########
    //#######################################
    #include <stdint.h>
    #include <avr/io.h>
    #include <stdlib.h>
    #include <avr/interrupt.h>
    #include "HD44780.h"
    #include <avr/pgmspace.h>
    //-----define przetwornik ADC
    char buffer_n[16];
    volatile uint16_t pomiar[6] __attribute__((section(".noinit")));
    void inline SetAdcKanal(unsigned char kanal)
    {
     ADMUX = ((ADMUX&0xE0)+ kanal);
    }
    double aku,lad,sol,out,power,inpower;
    //-----define progi napięciowe
    float aku_min = 11.5;
    float aku_max = 14.2;
    float aku_stab = 14.0;
    float sol_ref = 13.0;
    float zas_ref = 10.0;
    //-----obsługa TWI dla PCF8583 oraz 24C02
    #define ACK 1
    #define NOACK 0
    #define eeprom ?????
    #define zegar 0xA2             // A0 PCF8583 do plusa
    //-----
    static void TWI_start(void)
    {
     TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
     while (!(TWCR & (1<<TWINT)));
    }
    //-----
    static void TWI_stop(void)
    {
     TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
    }
    //-----
    void TWI_write(unsigned char scalak,unsigned char adres_rejestru,unsigned char liczba)
     {
      TWCR =(1 << TWINT) | (1 << TWSTA) | ( 1 << TWEN );
      while(!(TWCR & (1 << TWINT)));
      TWDR =scalak;
      TWCR =(1 << TWINT) | (1 << TWEN);
      while(!(TWCR & (1 << TWINT)));
      TWDR =adres_rejestru;
      TWCR =(1 << TWINT) | (1 << TWEN);
      while(!(TWCR & (1 << TWINT)));




      TWDR =liczba;
      TWCR =(1 << TWINT) | (1 << TWEN);
      while(!(TWCR & (1 << TWINT)));
      TWCR =(1 << TWINT) | (1<<TWEN) | (1<<TWSTO);
    }
    //-----
    unsigned char TWI_read(unsigned char scalak,unsigned char adres_rejestru)
     {
      unsigned char odczyt;     
      TWCR =(1 << TWINT) | (1 << TWSTA) | ( 1 << TWEN );
      while(!(TWCR & (1 << TWINT)));
      TWDR =scalak;
      TWCR =(1 << TWINT) | (1 << TWEN);
      while(!(TWCR & (1 << TWINT)));
      TWDR =adres_rejestru;
      TWCR =(1 << TWINT) | (1 << TWEN);
      while(!(TWCR & (1 << TWINT)));
      TWCR =(1 << TWINT) | (1 << TWSTA) | ( 1 << TWEN );
      while(!(TWCR & (1 << TWINT)));
      TWDR =scalak | 0x01;
      TWCR =(1 << TWINT) | (1 << TWEN);
      while(!(TWCR & (1 << TWINT)));
      TWCR =(1 << TWINT) | (1 << TWEN);
      while(!(TWCR & (1 << TWINT)));
      odczyt =TWDR;     
      TWCR =(1 << TWINT) | (1<<TWEN) | (1<<TWSTO);
      return(odczyt);
    }
    //-----konwersja dcd na dec
    char dec_na_bcd(char num)
    {
     return ((num/10 * 16) + (num % 10));
    }
    //-----konwersja dec na bcd
    char bcd_na_dec(int num)
    {
     return ((num/16 * 10) + (num % 16));
    }
    //-----define obsługa przerwań
    int IRQ=0;
    void INT1_init(void)
    {
     GICR |= (1 << INT1);         //obsługa zewnętrznych przerwań
     MCUCR = _BV(ISC01)|_BV(ISC11);   //przez opadające zbocze na INT0 INT1
    }
    ISR(INT1_vect)
    {
     IRQ=1;
    }
    //-----define nastaw i wyświetlania czasu zegara
    unsigned char PCF8583;
    unsigned char buffer_t[16];
    unsigned int rtc_bin[10];      //czas i data bierząca binarnie
    unsigned int rtc_dec[10];      //czas i data bierząca dziesiętnie
    unsigned int set_rtc[4];      //czas i data ustawiany dziesiętnie
    unsigned int rtc_temp[4];      //data i czas po konwersji przed zapisem do PCF
    //-----tablica czasów zał/wył
    unsigned int kanal_1_on[4];
    unsigned int kanal_2_on[4];
    unsigned int kanal_3_on[4];
    unsigned int kanal_4_on[4];
    unsigned int kanal_1_off[4];
    unsigned int kanal_2_off[4];
    unsigned int kanal_3_off[4];
    unsigned int kanal_4_off[4];
    unsigned int kanal_tryb[4];

    //-----define tablica komunikatów
    unsigned char komunikat;//******* do poprawy nie wyświetlają się na LCD
    unsigned char *info[5]={
                   ("     "),   //info[0]
                   ("-----"),   //info[1]- oczekiwanie
                   ("SOLAR"),   //info[2]- zasialanie z solara
                   ("ZAS_1"),   //info[3]- zasialanie z zasialcza głównego
                   ("ZAS_2"),   //info[4]- zasialanie z zasilacza rezerwowego
                   ("AUTO  "),   //info[6]- tryb automatyczny sterowanie przez timer
                   ("MANUAL"),   //info[7]- tryb manual sterowanie z klawiatury
                   ("ON "),      //info[8]- status obwód załączony
                   ("OFF"),      //info[9]- status obwód wyłaczony
                  };
    //-----define LCD menu
    unsigned int ekran=0;
    unsigned int menu;

    //***** MAIN
    int main()
    {
     DDRA=0xC0;      //flaga PA6
     PORTA=0x80;    //pul-up klawisza podświetlenia LCD
     DDRB=0x01;      //podświetlenie LCD (reszta pinów 4 bity,RS,RW,E pod LCD)
     DDRC=0xFC;      //wyjścia sterujące oraz SCL SDA układu PCF8583 oraz 24C04
     PORTC=0x03;   //pul-up dla SCL SDA INT1 układu PCF8583 oraz 24C04
     DDRD=0x00;      //wejścia klawiatura oraz INT1 układu PCF8583
     PORTD=0xF8;   //pull-up klawiatura oraz INT1 układu PCF8583
    //----- LCD init LCD_menu init
     LCD_Initalize();
     _delay_ms(200);
     ekran=0;
    //----- ADC init
     ADMUX = _BV(REFS0)|_BV(REFS1)|_BV(ADLAR);
     ADCSRA = _BV(ADEN)|_BV(ADPS0)|_BV(ADPS1)|_BV(ADPS2);
    //----- TWI init
     TWSR=0x00;            //preskaler I2C
     TWBR=0x48;            //((F_CPU / 100000UL - 16) / 2);
     INT1_init();         //inicjacja przerwań
     sei();
     while(1)
     {
      if(!(PIND & _BV(4)))
      {

       while(!(PIND & _BV(4)))
       {
        PORTB |= _BV(0);   //włącza podświetlenie LCD
        ekran++;
        _delay_ms(600);
        LCD_GoTo(0,0);  LCD_WriteText("                                       ");
        LCD_GoTo(0,1);  LCD_WriteText("                                       ");
        if(ekran>7)
        {
         ekran=0;
        }
       }
      }   
      switch(ekran)
      {
       case 0:   //EKRAN GLOWNY-----WYŚWIETLANIE-----DANYCH
        LCD_GoTo(1,0);   LCD_WriteText(dtostrf(rtc_bin[6],1,0,buffer_t));   //dziesiątki dni
        LCD_GoTo(2,0);   LCD_WriteText(dtostrf(rtc_bin[7],1,0,buffer_t));   //jednostki dni
        LCD_GoTo(3,0);   LCD_WriteText("-");
        LCD_GoTo(4,0);   LCD_WriteText(dtostrf(rtc_bin[8],1,0,buffer_t));   //dziesiątki miesięcy
        LCD_GoTo(5,0);   LCD_WriteText(dtostrf(rtc_bin[9],1,0,buffer_t));   //jednostki miesięcy
        LCD_GoTo(6,0);   LCD_WriteText("-");
        LCD_GoTo(7,0);   LCD_WriteText("10");
        LCD_GoTo(11,0);  LCD_WriteText(dtostrf(rtc_bin[0],1,0,buffer_t));   //jednostki godzin
        LCD_GoTo(12,0);  LCD_WriteText(dtostrf(rtc_bin[1],1,0,buffer_t));   //dziesiatki godzin
        LCD_GoTo(13,0);  LCD_WriteText(":");                        //dwukropek
        LCD_GoTo(14,0);  LCD_WriteText(dtostrf(rtc_bin[2],1,0,buffer_t));   //jednostki minut
        LCD_GoTo(15,0);  LCD_WriteText(dtostrf(rtc_bin[3],1,0,buffer_t));   //dziesiatki minut
        LCD_GoTo(16,0);  LCD_WriteText(":");                        //dwukropek
        LCD_GoTo(17,0);  LCD_WriteText(dtostrf(rtc_bin[4],1,0,buffer_t));   //jednostki sekund
        LCD_GoTo(18,0);  LCD_WriteText(dtostrf(rtc_bin[5],1,0,buffer_t));   //dziesiatki sekund
        LCD_GoTo(0,1);   LCD_WriteText("AKU");
        LCD_GoTo(4,1);   LCD_WriteText(dtostrf(aku=aku,4,1,buffer_n));
        LCD_GoTo(8,1);   LCD_WriteText("V");                  //napięcie akumulatora
        LCD_GoTo(10,1);  LCD_WriteText("SOL");
        LCD_GoTo(14,1);  LCD_WriteText(dtostrf(sol=sol,4,1,buffer_n));
        LCD_GoTo(18,1);  LCD_WriteText("V");                  //napięcie solara
    //*********************
        LCD_GoTo(21,0);  LCD_WriteText(komunikat);               //status zasilania
    //*********************
        LCD_GoTo(20,1);  LCD_WriteText(dtostrf(lad=lad,4,1,buffer_n));
        LCD_GoTo(24,1);  LCD_WriteText("A");                  //prąd ładowania
        LCD_GoTo(28,0);  LCD_WriteText("AKUM");
        LCD_GoTo(27,1);  LCD_WriteText(dtostrf(inpower=inpower,4,1,buffer_n));
        LCD_GoTo(31,1);  LCD_WriteText("A");                  //prąd akumulatora
        LCD_GoTo(35,0);  LCD_WriteText("OBCI");
        LCD_GoTo(34,1);  LCD_WriteText(dtostrf(out=out,4,1,buffer_n));
        LCD_GoTo(38,1);  LCD_WriteText("A");                  //prąd obciążenia
       if(!(PINA & _BV(7)))
       {
        _delay_ms(30);
        PORTB ^=_BV(0);   //podświetlenie LCD
        _delay_ms(30);
       }
       break;//-----koniec ekran główny
       case 1://-----indywidualne przełączanie trybu pracy kanałów [auto/manual]
              //gdy auto włączaniem i wyłaczaniem kanałów steruje zegar
            //gdy reczny można z poziomu menu sterować nimi indywidualnie
              //-----ale zdrowo namieszałem i to nie chodzi  *********
       LCD_GoTo(0,0);   LCD_WriteText("Obw.1");
       if(kanal_tryb[1]=0)
       {
        LCD_GoTo(10,0);   LCD_WriteText("reczny");
       }
       if(kanal_tryb[1]=1)
       {
        LCD_GoTo(10,0);   LCD_WriteText("automat");
       }//---------------------------------------
       LCD_GoTo(0,1);   LCD_WriteText("Obw.2");
       if(kanal_tryb[2]=0)
       {
        LCD_GoTo(10,1);   LCD_WriteText("reczny");
       }
       if(kanal_tryb[2]=1)
       {
        LCD_GoTo(10,1);   LCD_WriteText("automat");
       }//---------------------------------------
       LCD_GoTo(20,0);   LCD_WriteText("Obw.3");
       if(kanal_tryb[3]=0)
       {
        LCD_GoTo(30,0);   LCD_WriteText("reczny");
       }
       if(kanal_tryb[3]=1)
       {
        LCD_GoTo(30,0);   LCD_WriteText("automat");
       }//---------------------------------------
       LCD_GoTo(20,1);   LCD_WriteText("Obw.4");
       if(kanal_tryb[3]=0)
       {
        LCD_GoTo(30,1);   LCD_WriteText("reczny");
       }
       if(kanal_tryb[3]=1)
       {
        LCD_GoTo(30,1);   LCD_WriteText("automat");
       }
    // LCD_WriteCommand(0x0E);//cursor no flash
    // LCD_WriteCommand(0x0F);//cursor flash   
       break;//-----koniec indywidualne przełączanie trybu pracy kanałów


       case 2://-----programowanie czasu załączenia kanał nr.1
       LCD_GoTo(1,0);  LCD_WriteText("KANAL nr.1 WLACZ");
       LCD_GoTo(1,1);  LCD_WriteText("ODCZYT");
       LCD_GoTo(11,1); LCD_WriteText(dtostrf(rtc_bin[0],1,0,buffer_t));
       LCD_GoTo(12,1); LCD_WriteText(dtostrf(rtc_bin[1],1,0,buffer_t));
       LCD_GoTo(13,1); LCD_WriteText(":");
       LCD_GoTo(14,1); LCD_WriteText(dtostrf(rtc_bin[2],1,0,buffer_t));
       LCD_GoTo(15,1); LCD_WriteText(dtostrf(rtc_bin[3],1,0,buffer_t));
       if(!(PIND & _BV(5)))
       {
        if(++set_rtc[0] >= 24)
       {
        set_rtc[0]++;
         set_rtc[0] = 0;
        }
       }
       if(!(PIND & _BV(6)))
       {
        if(++set_rtc[1] >= 60)
       {
        set_rtc[1]++;
         set_rtc[1] = 0;
        }
       }
       LCD_GoTo(21,0); LCD_WriteText("USTAW");
       LCD_GoTo(31,0); LCD_WriteText(dtostrf(set_rtc[0],2,0,buffer_n));
       LCD_GoTo(33,0); LCD_WriteText(":");
       LCD_GoTo(34,0); LCD_WriteText(dtostrf(set_rtc[1],2,0,buffer_n));
       rtc_temp[0]= dec_na_bcd(set_rtc[0]);
       rtc_temp[1]= dec_na_bcd(set_rtc[1]);
       if(!(PIND & _BV(7)))
        {//do zrobienia zapis ustawinego czasu do PCF8583 lub 24C02*********
    //    TWI_write       
    //    TWI_write        
       _delay_ms(50);
       }
       break;
       case 3://-----programowanie czasu wyłączenia kanał nr.1
       LCD_GoTo(1,0);   LCD_WriteText("KANAL nr.1 WYLACZ");
       LCD_GoTo(1,1);  LCD_WriteText("ODCZYT");
       LCD_GoTo(11,1); LCD_WriteText(dtostrf(rtc_bin[0],1,0,buffer_t));
       LCD_GoTo(12,1); LCD_WriteText(dtostrf(rtc_bin[1],1,0,buffer_t));
       LCD_GoTo(13,1); LCD_WriteText(":");
       LCD_GoTo(14,1); LCD_WriteText(dtostrf(rtc_bin[2],1,0,buffer_t));
       LCD_GoTo(15,1); LCD_WriteText(dtostrf(rtc_bin[3],1,0,buffer_t));
       if(!(PIND & _BV(5)))
       {
        if(++set_rtc[0] >= 24)
       {
        set_rtc[0]++;
         set_rtc[0] = 0;
        }
       }
       if(!(PIND & _BV(6)))
       {
        if(++set_rtc[1] >= 60)
       {
        set_rtc[1]++;
         set_rtc[1] = 0;
        }
       }
       LCD_GoTo(21,0); LCD_WriteText("USTAW");
       LCD_GoTo(31,0); LCD_WriteText(dtostrf(set_rtc[0],2,0,buffer_n));
       LCD_GoTo(33,0); LCD_WriteText(":");
       LCD_GoTo(34,0); LCD_WriteText(dtostrf(set_rtc[1],2,0,buffer_n));
       rtc_temp[0]= dec_na_bcd(set_rtc[0]);
       rtc_temp[1]= dec_na_bcd(set_rtc[1]);
       if(!(PIND & _BV(7)))
        {//do zrobienia zapis ustawinego czasu do PCF8583 lub 24C02*********
    //    TWI_write       
    //    TWI_write     
       _delay_ms(50);
       }
       break;
       case 4://-----programowanie czasu załączenia kanał nr.2
       LCD_GoTo(1,0);   LCD_WriteText("KANAL nr.2 WLACZ");
       LCD_GoTo(1,1);  LCD_WriteText("ODCZYT");
       LCD_GoTo(11,1); LCD_WriteText(dtostrf(rtc_bin[0],1,0,buffer_t));
       LCD_GoTo(12,1); LCD_WriteText(dtostrf(rtc_bin[1],1,0,buffer_t));
       LCD_GoTo(13,1); LCD_WriteText(":");
       LCD_GoTo(14,1); LCD_WriteText(dtostrf(rtc_bin[2],1,0,buffer_t));
       LCD_GoTo(15,1); LCD_WriteText(dtostrf(rtc_bin[3],1,0,buffer_t));
       if(!(PIND & _BV(5)))
       {
        if(++set_rtc[0] >= 24)
       {
        set_rtc[0]++;
         set_rtc[0] = 0;
        }
       }
       if(!(PIND & _BV(6)))
       {
        if(++set_rtc[1] >= 60)
       {
        set_rtc[1]++;
         set_rtc[1] = 0;
        }
       }
       LCD_GoTo(21,0); LCD_WriteText("USTAW");
       LCD_GoTo(31,0); LCD_WriteText(dtostrf(set_rtc[0],2,0,buffer_n));
       LCD_GoTo(33,0); LCD_WriteText(":");
       LCD_GoTo(34,0); LCD_WriteText(dtostrf(set_rtc[1],2,0,buffer_n));
       rtc_temp[0]= dec_na_bcd(set_rtc[0]);
       rtc_temp[1]= dec_na_bcd(set_rtc[1]);
       if(!(PIND & _BV(7)))
        {//do zrobienia zapis ustawinego czasu do PCF8583 lub 24C02*********
    //    TWI_write     
    //    TWI_write     
       _delay_ms(50);
       }
       break;
       case 5://-----programowanie czasu wyłączenia kanał nr.2
       LCD_GoTo(1,0);   LCD_WriteText("KANAL nr.2 WYLACZ");
       LCD_GoTo(1,1);  LCD_WriteText("ODCZYT");
       LCD_GoTo(11,1); LCD_WriteText(dtostrf(rtc_bin[0],1,0,buffer_t));
       LCD_GoTo(12,1); LCD_WriteText(dtostrf(rtc_bin[1],1,0,buffer_t));
       LCD_GoTo(13,1); LCD_WriteText(":");
       LCD_GoTo(14,1); LCD_WriteText(dtostrf(rtc_bin[2],1,0,buffer_t));
       LCD_GoTo(15,1); LCD_WriteText(dtostrf(rtc_bin[3],1,0,buffer_t));
       if(!(PIND & _BV(5)))
       {
        if(++set_rtc[0] >= 24)
       {
        set_rtc[0]++;
         set_rtc[0] = 0;
        }
       }
       if(!(PIND & _BV(6)))
       {
        if(++set_rtc[1] >= 60)
       {
        set_rtc[1]++;
         set_rtc[1] = 0;
        }
       }
       LCD_GoTo(21,0); LCD_WriteText("USTAW");
       LCD_GoTo(31,0); LCD_WriteText(dtostrf(set_rtc[0],2,0,buffer_n));
       LCD_GoTo(33,0); LCD_WriteText(":");
       LCD_GoTo(34,0); LCD_WriteText(dtostrf(set_rtc[1],2,0,buffer_n));
       rtc_temp[0]= dec_na_bcd(set_rtc[0]);
       rtc_temp[1]= dec_na_bcd(set_rtc[1]);
       if(!(PIND & _BV(7)))
        {//do zrobienia zapis ustawinego czasu do PCF8583 lub 24C02*********
    //    TWI_write       
    //    TWI_write     
       _delay_ms(50);
       }
       break;
       case 6://programowanie daty
       LCD_GoTo(0,0);  LCD_WriteText(" PROGRAMOWANIE DATA");
       LCD_GoTo(1,1);  LCD_WriteText("ODCZYT");
       LCD_GoTo(9,1); LCD_WriteText(dtostrf(rtc_bin[6],1,0,buffer_t));
       LCD_GoTo(10,1); LCD_WriteText(dtostrf(rtc_bin[7],1,0,buffer_t));
       LCD_GoTo(11,1); LCD_WriteText("-");
       LCD_GoTo(12,1); LCD_WriteText(dtostrf(rtc_bin[8],1,0,buffer_t));
       LCD_GoTo(13,1); LCD_WriteText(dtostrf(rtc_bin[9],1,0,buffer_t));
       LCD_GoTo(14,1); LCD_WriteText("-2010");
       if(!(PIND & _BV(5)))
       {
        if(++set_rtc[0] >= 24)
       {
        set_rtc[0]++;
         set_rtc[0] = 0;
        }
       }
       if(!(PIND & _BV(6)))
       {
        if(++set_rtc[1] >= 60)
       {
        set_rtc[1]++;
         set_rtc[1] = 0;
        }
       }
       LCD_GoTo(21,0); LCD_WriteText("USTAW");
       LCD_GoTo(29,0); LCD_WriteText(dtostrf(set_rtc[0],2,0,buffer_n));
       LCD_GoTo(31,0); LCD_WriteText("-");
       LCD_GoTo(32,0); LCD_WriteText(dtostrf(set_rtc[1],2,0,buffer_n));
       LCD_GoTo(34,0); LCD_WriteText("-2010");
       rtc_temp[0]= dec_na_bcd(set_rtc[0]);
       rtc_temp[1]= dec_na_bcd(set_rtc[1]);
       if(!(PIND & _BV(7)))
        {//zapis ustawinej daty do PCF8583
        TWI_write(zegar,0x06,rtc_temp[0]);       
        TWI_write(zegar,0x05,rtc_temp[1]);        
       _delay_ms(50);
       }
       break;//-----koniec programowania daty

       case 7://-----programowanie czasu
       LCD_GoTo(0,0); LCD_WriteText(" PROGRAMOWANIE CZAS");
       LCD_GoTo(1,1);  LCD_WriteText("ODCZYT");
       LCD_GoTo(11,1); LCD_WriteText(dtostrf(rtc_bin[0],1,0,buffer_t));
       LCD_GoTo(12,1); LCD_WriteText(dtostrf(rtc_bin[1],1,0,buffer_t));
       LCD_GoTo(13,1); LCD_WriteText(":");
       LCD_GoTo(14,1); LCD_WriteText(dtostrf(rtc_bin[2],1,0,buffer_t));
       LCD_GoTo(15,1); LCD_WriteText(dtostrf(rtc_bin[3],1,0,buffer_t));
       LCD_GoTo(16,1); LCD_WriteText(":");
       LCD_GoTo(17,1); LCD_WriteText(dtostrf(rtc_bin[4],1,0,buffer_t));
       LCD_GoTo(18,1); LCD_WriteText(dtostrf(rtc_bin[5],1,0,buffer_t));
       if(!(PIND & _BV(5)))
       {
        if(++set_rtc[0] >= 24)
       {
        set_rtc[0]++;
         set_rtc[0] = 0;
        }
       }
       if(!(PIND & _BV(6)))
       {
        if(++set_rtc[1] >= 60)
       {
        set_rtc[1]++;
         set_rtc[1] = 0;
        }
       }

       LCD_GoTo(21,0); LCD_WriteText("USTAW");
       LCD_GoTo(31,0); LCD_WriteText(dtostrf(set_rtc[0],2,0,buffer_n));
       LCD_GoTo(33,0); LCD_WriteText(":");
       LCD_GoTo(34,0); LCD_WriteText(dtostrf(set_rtc[1],2,0,buffer_n));
       LCD_GoTo(36,0); LCD_WriteText(":00");
       rtc_temp[0]= dec_na_bcd(set_rtc[0]);
       rtc_temp[1]= dec_na_bcd(set_rtc[1]);
       if(!(PIND & _BV(7)))
        {//zapis ustawinego czasu do PCF8583
        TWI_write(zegar,0x04,rtc_temp[0]);       
        TWI_write(zegar,0x03,rtc_temp[1]);   
        TWI_write(zegar,0x02,0x00);     
       _delay_ms(50);
       }
       break;
      }
      if(!(PIND & _BV(7)))
      {
       _delay_ms(10);
       while(!(PIND & _BV(7)))
       {
        LCD_GoTo(0,0);  LCD_WriteText("                                       ");
        LCD_GoTo(0,1);  LCD_WriteText("                                       ");
        LCD_GoTo(0,0);  LCD_WriteText("   ZAPISUJE DANE   ");
        _delay_ms(1500);
        ekran=0;
        LCD_GoTo(0,0);  LCD_WriteText("                   ");
       }
      }
    //---------------------------------------pomiary napięć i prądów
      int kan;
      for(kan = 0; kan<5; kan++)
      {
       SetAdcKanal(kan);
       ADCSRA |= (1 << ADSC);
       while(ADCSRA & (1 << ADSC));
       pomiar[kan] = (ADC | ADCH<<8);     
       aku = (pomiar[0]/2.54)/1024;         //napięcie akumulatora
       lad = (pomiar[1]/2.54)/1024;         //prąd akumulatora
       sol = (pomiar[2]/2.54)/1024;         //napięcie ogniwa słonecznego
       out = (pomiar[3]/2.54)/1024;         //prąd obciążenia [obwody 12V]
       power = (pomiar[4]/2.54)/1024;      //monitorowanie zasialacza głównego
       _delay_ms(40);
       {
        inpower =(lad-out);               //prąd wejściowy
    //---------------------------------------monitorowanie napięć
        unsigned char bbb=10;
        for(bbb=10; bbb<15; bbb++)   
        {   
         switch(bbb)
         {
          case 10://-------------------------zasilacz główny
          if(power > zas_ref)
          {
           if((aku < aku_min)&&(sol < sol_ref))
             {
            PORTC &=~ 0x04;               //enable kanal 1
             PORTC |= 0x08;               //disable kanal 2
            komunikat=info[3];           //text zas-1
             }
          }
          break;
          case 11:
          if(power > zas_ref)
          {
           if((aku > aku_max)||(sol > sol_ref))
          {
            PORTC |= 0x04;               //disable kanal 1
           PORTC |= 0x08;               //disable kanal 2               
          }
          }   
          break;
          case 12://------------------------zasilacz rezerwowy
          if(power < zas_ref)
          {
           if((aku < aku_min)&&(sol < sol_ref))
           {
           PORTC |= 0x04;               //disable kanal 1
            PORTC &=~ 0x08;               //enable kanal 2
            komunikat=info[4];           //text zas-2
           }
          }
          break;
          case 13:
          if(power < zas_ref)
          {
           if((aku > aku_max)&&(sol > sol_ref))
           {
            PORTC |= 0x08;               //disable kanal 2
            PORTC |= 0x04;               //disable kanal 1
           }
          } 
          break;
          case 14://------------------------status zasilania
          if (sol > sol_ref)
          {
           komunikat=info[2];            //text solar
          }
          if((aku > aku_stab)&&(sol < sol_ref))
          {
           komunikat=info[1];            //text -----
          }
          break;
          default:
          break;//--------------------------koniec pomiarów i monitorowania napięc
          }
         }
        }   
        if(IRQ==1)//------------------------odczyt czasu oraz daty
        {
         PCF8583=TWI_read(zegar,0x04);      //dziesiatki i jednostki godzin 
         rtc_bin[0]=(PCF8583 & 0x30)>>4;        
         rtc_bin[1]=PCF8583 & 0x0F;
         PCF8583=TWI_read(zegar,0x03);      //dziesiatki i jednostki minut
         rtc_bin[2]=PCF8583 >> 4;         
         rtc_bin[3]=PCF8583 & 0x0F;
         PCF8583=TWI_read(zegar,0x02);      //dziesiatki i jednostki sekund
         rtc_bin[4]=PCF8583 >> 4;      
         rtc_bin[5]=PCF8583 & 0x0F;
         PCF8583=TWI_read(zegar,0x05);      //dziesiatki i jednostki dni
         rtc_bin[6]=PCF8583 >> 4;         
         rtc_bin[7]=PCF8583 & 0x0F;
         PCF8583=TWI_read(zegar,0x06);      //dziesiatki i jednostki miesięcy
         rtc_bin[8]=PCF8583 >> 4;          
         rtc_bin[9]=PCF8583 & 0x0F;
         IRQ==0;     
        }//---------------------------------koniec odczytu czasu oraz daty
        unsigned char ccc=21;
        for(ccc=21; ccc<25; ccc++)   
        {   
         switch(ccc)//----------porównanie czasu zegara z nastawami timera
         {
          case 21://sprawdzanie czy kanał 1 włączyć lub wyłączyć
          if(kanal_tryb[1]=1)//jeżeli automatyczny to sprawdz nastawy
         {
          if(((rtc_dec[0])&&(rtc_dec[1]))==((kanal_1_on[0])&&(kanal_1_on[1])))
          {
            if(((rtc_dec[3])&&(rtc_dec[4]))==((kanal_1_on[3])&&(kanal_1_on[4])))
           {
           PORTC |=0x10;
           }
          }
         }
          if(((rtc_dec[0])&&(rtc_dec[1]))==((kanal_1_off[0])&&(kanal_1_off[1])))
         {
           if(((rtc_dec[3])&&(rtc_dec[4]))==((kanal_1_off[3])&&(kanal_1_off[4])))
          {
          PORTC &=~0x10;
          }
         }
          case 22://sprawdzanie czy kanał 2 włączyć lub wyłączyć
          if(kanal_tryb[1]=1)
         {
          if(((rtc_dec[0])&&(rtc_dec[1]))==((kanal_2_on[0])&&(kanal_2_on[1])))
          {
            if(((rtc_dec[2])&&(rtc_dec[3]))==((kanal_2_on[2])&&(kanal_2_on[3])))
           {
            PORTC |=0x20;
           }
          }
           if(((rtc_dec[0])&&(rtc_dec[1]))==((kanal_2_off[0])&&(kanal_2_off[1])))
          {
            if(((rtc_dec[2])&&(rtc_dec[3]))==((kanal_2_off[2])&&(kanal_2_off[3])))
           {
           PORTC &=~0x20;
           }
          }
          }
          case 23://sprawdzanie czy kanał 3 włączyć lub wyłączyć
          if(kanal_tryb[1]=1)
         {
          if(((rtc_dec[0])&&(rtc_dec[1]))==((kanal_3_on[0])&&(kanal_3_on[1])))
          {
            if(((rtc_dec[2])&&(rtc_dec[3]))==((kanal_3_on[2])&&(kanal_3_on[3])))
           {
           PORTC |=0x40;
           }
          }
           if(((rtc_dec[0])&&(rtc_dec[1]))==((kanal_3_off[0])&&(kanal_3_off[1])))
          {
            if(((rtc_dec[2])&&(rtc_dec[3]))==((kanal_3_off[2])&&(kanal_3_off[3])))
           {
           PORTC &=~0x40;
           }
          }
          }
          case 24://sprawdzanie czy kanał 4 włączyć lub wyłączyć
          if(kanal_tryb[1]=1)
         {
          if(((rtc_dec[0])&&(rtc_dec[1]))==((kanal_4_on[0])&&(kanal_4_on[1])))
          {
            if(((rtc_dec[2])&&(rtc_dec[3]))==((kanal_4_on[2])&&(kanal_4_on[3])))
           {
           PORTC |=0x80;
           }
          }
           if(((rtc_dec[0])&&(rtc_dec[1]))==((kanal_4_off[0])&&(kanal_4_off[1])))
          {
            if(((rtc_dec[2])&&(rtc_dec[3]))==((kanal_4_off[2])&&(kanal_4_off[3])))
           {
           PORTC &=~0x80;
           }
          }
         }
          default:
         break;
        }
       }
       }
      }
     return;
     }
    //********** END MAIN **********

  • #2 27 Paź 2010 20:05
    1428163
    Usunięty  
  • #3 27 Paź 2010 20:53
    mirekk36
    Poziom 42  

    margas4542 napisał:
    ...wrzucam cały kod programu który w 90% procentach chodzi.....programistów zapewne zaboli głowa...


    Mnie tylko głowa rozbolała (generalnie cały kod jest idealnym przykładem skrajnego przypadku jak nie należy pisać kodu w języku C). Żeby dostać dobrą i porządną odpowiedź na konkretne pytanie to trzeba jeszcze nauczyć się zadawać takie pytania panie kolego. Jak to dobrze, że twój kod nie był dla np ATmega128 bo stołu by nie starczyło żeby myszką przesuwać w dół i dojść do końca.

  • #4 27 Paź 2010 21:22
    gaskoin
    Poziom 38  

    mirekk36 napisał:
    margas4542 napisał:
    ...wrzucam cały kod programu który w 90% procentach chodzi.....programistów zapewne zaboli głowa...


    Mnie tylko głowa rozbolała (generalnie cały kod jest idealnym przykładem skrajnego przypadku jak nie należy pisać kodu w języku C). Żeby dostać dobrą i porządną odpowiedź na konkretne pytanie to trzeba jeszcze nauczyć się zadawać takie pytania panie kolego. Jak to dobrze, że twój kod nie był dla np ATmega128 bo stołu by nie starczyło żeby myszką przesuwać w dół i dojść do końca.


    Przeczytałeś cały kod ? :P

  • #5 27 Paź 2010 21:27
    mirekk36
    Poziom 42  

    gaskoin --> nie, bo zabrakło mi stołu i myszka spada zanim dociągnę do końca ;)

  • #6 27 Paź 2010 21:29
    gdL
    Poziom 27  

    Trzeba przyznać, że brzydki kod. Nikt jednak nie napisał, jak powinien wyglądać. Proceduralny kod, powinien być złożony z małych funkcji wykonywanych w odpowiedniej kolejności, najlepiej nie wywołujących siebie nawzajem.

    Cytat:

    "Programowanie proceduralne to paradygmat programowania zalecający dzielenie kodu na procedury, czyli fragmenty wykonujące ściśle określone operacje.

    Procedury nie powinny korzystać ze zmiennych globalnych (w miarę możliwości), lecz pobierać i przekazywać wszystkie dane (czy też wskaźniki do nich) jako parametry wywołania."

    pl/wikipedia

    Pomyśl jakby Ci się czytało, gdybyś do tego kodu wrócił za pół roku ?

  • #7 27 Paź 2010 21:34
    mirekk36
    Poziom 42  

    gdL --> ależ ten kod posiada wiele małych funkcji ;) a już podpowiedź, że powinny się wykonywać w odpowiedniej kolejności to w zasadzie nic nie mówi. Z kolei to że nie powinny wywoływać samych siebie to już nawet lekka niedorzeczność chyba hmmm?

    Generalnie gdyby chcieć opisać tu jak nie powinien wyglądać ten konkretny kod to podejrzewam że zabrałoby to więcej miejsca niż sam kod ;) .... Lepiej więc chyba uczyć się mniejszymi kroczkami i od razu porządnie.

  • #8 27 Paź 2010 22:26
    gdL
    Poziom 27  

    -> mirekk36 :

    Cytat:
    ależ ten kod posiada wiele małych funkcji a już podpowiedź, że powinny się wykonywać w odpowiedniej kolejności to w zasadzie nic nie mówi. Z kolei to że nie powinny wywoływać samych siebie to już nawet lekka niedorzeczność chyba hmmm?

    Jest tu kilka dobrych małych funkcji, takich, że od razu wiadomo o co chodzi. Ale jak sie spojrzy na funkcję main, to już nic nie wiadomo. Ja tam zginąłem.
    Dobrze jest unikać łańcuszków kilku wywołujących się funkcji, bo trudno się to śledzi. Lepiej zamiast tego uprościć strukturę. Przynajmniej ja się staram tak pisać.

    Wywoływanie w odpowiedniej kolejności, no rzeczywiście. Tak oczywiste, że nie ma po co o tym pisać. Ale clue działania celowego, to właśnie wywoływanie w odpowiedniej kolejności :P

  • #9 27 Paź 2010 23:00
    mirekk36
    Poziom 42  

    gdL -> nie, no co do ogólnych uwag to całkowicie podzielam twoje zdanie.

  • #10 28 Paź 2010 10:24
    margas4542
    Poziom 16  

    Opinii starych wyjadaczy że ten kod jest "niezręczny" można był się spodziewać ale panowie nie dziwcie się facetowi który dwa miesiące temu zaczął pisać w C...mówicie o dobrych nawykach i przykładach "jak nie pisać" ale informacje jak pisać poprawnie jaką konstrukcję powinien mieć taki program gdzie zacząć blok funkcji a gdzie skończyć....tego raczej w książce nie znajdę bo tego tylko można się nauczyć praktycznie. Nie mam doświadczenia i napisałem jak napisałem ale zamieszczając kod miałem cichą nadzieję że poza krytyką bardziej doświadczonych kolegów pojawią się głosy na zasadzie ty napisałeś tak a można napisać tak bo wtedy [komentarz].
    To forum moim zdaniem najlepsze , istnieje bo korzystają z niego ludzie tacy jak ja głównie hobbyści szukający informacji , wsparcia i pomocy w zrozumieniu nie raz banalnie prostych funkcji...ale wszyscy się uczymy i może któregoś dnia będę potrafił napisać programik zgodnie ze "sztuką". Pozdrawiam.

  • #11 28 Paź 2010 11:17
    mirekk36
    Poziom 42  

    margas4542 --> ogólnie masz rację w przedstawionych tu przemyśleniach. Ale zrozum też , że stawianie w ten sposób pytania "it's madness". Ja bardzo dobrze rozumiem problemy ludzi stawiających pierwsze kroki szczególnie przy nauce języka C. Sam ile mogę to zawsze pomagam. Ale spokojnie, po woli i mniejszymi krokami. Bo ty się wręcz sam dławisz tym co robisz. Ja bym na twoim miejscu zaczynał tę naukę właśnie od doczytanie, podpatrzenia czy wręcz dopytania jak w ogóle pisać programy. Wprawdzie takie pytanie na elektrodzie spowodowałoby burzę i milony postów a każdy przekonywałby cię do swojego. Jednak czasem czytając to wszystko można byłoby wysnuć własne wnioski.

    Przede wszystkim to co daje C wporównaniu do np Bascoma to możliwość pięknego podziału kodu programu na wydzielone fragmenty w wielu plikach. Nie trzeba zatem pisać 50tys linii kodu w jednym!!!!

    Poza tym choćby nie wiem co to już dawno powinieneś przeczytać gdzieś o głupich wcięciach w programie !!! to co ty tu wkleiłeś to jakaś porażka. I gdybyś wkleił jakiś króciutki fragmencik, kilka linii to uszłoby to w tłoku, ale jeśli wklejasz tutaj chyba najdłuższy kod na elektrodzie w jednym poście i jest on bez wcięć - to sam sobie robisz strzał w stopę ;) ... Chcesz żeby komuś zachciało się to w ogóle jakoś analizować? Gdyby były głupie wcięcia to już można byłoby na pierwszy rzut oka więcej powiedzieć,no ale to nie oznacza, że wkleja się takie hetolitry kodu a jak już to jako załącznik a nie do postu bo to masakra.

    Wbrew pozorom nauka C powinna zacząć się właśnie od takich podstaw dobrego pisania, czyli powinieneś jak najszybciej doczytać sobie (już nie wspomnę o tych kocich wcięciach) o:

    1. deklaracjach i definicjach funkcji i zmiennych
    2. sposobach gdzie powinno się deklarować funkcje i gdzie je umieszczać w kodzie
    3. podziale na pliki czyli także o znaczeniu plików nagłówkowych *.h

    już chociażby to bardzo dużo by dało tobie - bo ja się nie dziwię, że ty sam nie możesz okiełznać tak napisanego kodu, zresztą to wygląda prawie jak kod w Bascomie a nie w C.

    Reasumując nikt na takim forum nie będzie żmudnie na przykładzie kodu z 1000 linii wypisywał ci krok po kroku co źle zrobiłeś bo to jest chore postawienie sprawy. Szybciej niestety byłoby się samemu nauczyć i porządnie go napisać niż w ten sposób dochodzić do tego. I tylko dlatego pojawiła się krytyka wklejenia takiego przepastnego kodu!

    Czyw innch swoich postach, gdzie zadałeś, krótsze i konkretniejsze pytania nie otrzymałeś jasnych i precyzyjnych odpowiedzi? wydaje mi się że tak - bo sam chyba w jakimś twoim temacie odpowiadałem.

    No i dlatego na samym poczatku i teraz też powiem jedno.

    Żeby uzyskać dobrą i fachową poradę, odpowiedź na pytanie trzeba także umieć zadać to konkretne pytanie a nie wrzucać tu grochu z kapustą do posegregowania. to tyle.

  • #12 28 Paź 2010 12:26
    margas4542
    Poziom 16  

    Rozumiem..fakt przesadziłem z tym kodem.....przepraszam......w sprawie wcięć to proszę o weryfikację czy tak ma wyglądać...to wyrwany z całości kawałek...

    Code:

    //***** MAIN
    int main()
    {
        DDRA=0xC0;      //jakieś ustawinie portów
    //***** LCD init LCD_menu init
        LCD_Initalize();
        _delay_ms(200);
    //***** ADC init

    //***** TWI init
        while(1)
        {   
    //***** odczyt czasu i daty
            if(IRQ==1)//jeżeli przerwanie odczyt czasu i daty
            {
                //odczyt z PCF8583
                IRQ==0;     
            }//koniec odczytu czasu oraz daty
         int sprawdz_1;//sprawdzanie czy czas zgodny z nastawą TIMERA_STERUJĄCEGO
         sprawdz_1=dec_na_bcd(rtc_bin[4]);
         if(sprawdz_1=0)//co minute sprawdza zależności
         {
             //
       }
         int sprawdz_2;//aktualizacja pomiarów ADC
         sprawdz_2=dec_na_bcd(rtc_bin[5]);
         if(sprawdz_2=0)//co 10 sekund odczyt ADC
         {
             int kan;//pomiary napięć i prądów
             for(kan = 0; kan<5; kan++)
             {
              //odczyt kanałów ADC
             } 
             unsigned char napiecia;//monitorowanie napięć
             for(napiecia=1; napiecia<6; napiecia++)   
             {   
              switch(napiecia)
              {
                  //w pętli sprawdzanie if-ami zleżności
              }   
              if(PINA & _BV(6)))//jeżeli PORTA PIN6 pzrskocz do menu
              {
                  goto menu:
              }
                //wyświetlanie czasów pomiarów i komunikatów na LCD
           if(!(PINA & _BV(7)))
           {
               _delay_ms(30);
               PORTB ^=_BV(0);   //włącza podświetlenie LCD
               _delay_ms(30);
           }
       {}menu;
       {
          //nastawy czasu zegara timera sterującego
       }
       }
      }
     }
    return;
    }

  • Pomocny post
    #13 28 Paź 2010 14:53
    rpal
    Poziom 27  

    temat jest o zupie a wy o d...
    Pomijając wywody natury ogólnej masz kolego do wyboru wewnętrzną pamięć RAM od pcf-a i to nie małą bo 240 bajtów albo stałą od eeproma. Jedno i drugie jest dobre bo pcf ma podtrzymywanie bateryjne (chyba go uzywasz) ale kiedy bateria padnie to zapisy znikną więc pewniejsze jest umieszczenie tych informacji w pamięci eeprom. A sam zapis jest praktycznie taki sam bo po i2c i wiele się od siebie nie różni. Są tu przykłady więc tylko poszukać. Na inne tematy się nie wypowiadam ale pamiętaj że życzliwość też ma swoje granice :) bo tu matki z kalkuty raczej nie pisują.
    Ilości potrzebnej pamięci ja za ciebie nie policzę bo to już jest z twojej strony nadużycie ale jak się z tym uporasz to łatwo będzie porównać czy starczy czy też nie dla ułatwienia tylko podam że liczba typu char lub unsigned char to jeden bajt danych resztę zrób sobie sam.

  • #14 02 Lis 2010 18:52
    margas4542
    Poziom 16  

    Fakt to nie było takie trudne...wykorzystałem PCF-a z podtrzymaniem akumulatorkiem od adresu 08 do 0F i spokojnie cztery nastawy w nim lokuje...dziękuje za owocną sugestie. Nurtuje mnie jeszcze jak dobrać się do trzech bitów BCD odpowiadających za numer dnia w tygodniu...

  • #15 02 Lis 2010 19:05
    mirekk36
    Poziom 42  

    margas4542 napisał:
    Nurtuje mnie jeszcze jak dobrać się do trzech bitów BCD odpowiadających za numer dnia w tygodniu...


    Zamaskować pozostałe bity i przesunąć w prawo albo nie w ogóle nie trzeba maskować przesunąć je w prawo o 5 i już masz dostępną bezpośrednio liczbę dni.

  • #16 02 Lis 2010 19:34
    margas4542
    Poziom 16  

    Zamaskować czyli ustawić bit maski rej. 0x00 bit 3 i odczytać trzy najstarsze bity z 0x06 ?

    Code:

    PCF8583=TWI_read(zegar,0x06);      
            pcf_mc[1] = PCF8583 >> 4; dziesiątki miesięcy to odczytany bit 5
            pcf_mc[0] = PCF8583 & 0x0F;jednostki miesięcy

    //to jeżeli jeżeli teraz
            dzien = PCF8583 >> 5;   //to powinny być bity 8,7,6

  • #17 02 Lis 2010 19:40
    mirekk36
    Poziom 42  

    dlaczego powinny????

    Cytat:
    dzien = PCF8583 >> 5; //to powinny być bity 8,7,6


    będą bity tylko że nie 8,7,6 a 7,6,5 - czyli właśnie dzień (nr dnia) tygodnia

    w czym problem?

    Poza tym pisałem że nie trzeba nawet nic maskować bo podczas przesuniecia w prawo o 5 pozostałe wsunięte bity będą miały zawsze wartość 0

  • #18 02 Lis 2010 19:47
    margas4542
    Poziom 16  

    Fakt sorry policzyłem od 1 zamiast od 0..ale tak już próbowałem i efektem było wyświetlenie zera na LCD...

    Code:

    PCF8583=TWI_read(zegar,0x06);      
    pcf_dzien = PCF8583 >> 5;      
    dec_dzien = bcd_na_dec(pcf_dzien);//konwersja na dec

  • #19 02 Lis 2010 20:49
    mirekk36
    Poziom 42  

    po choinkę robisz na tym jeszcze konwersję z bcd na dec ??? To wprawdzie nie przeszkadza ale potrzebne jest jak dziura w moście ;) skoro w starszej połówce bajtu masz same zera.

    jeśli i tak całość daje ci wciąż zero to masz coś nieteges z odczytem albo może wartość ta nie była wcześniej ustawiona i dlatego jest zero.

    Co za problem załadować tam np wartość 4, następnie ustawić godzinę na:

    23:59:55

    poczekać aż się przekręci na 0:00:00 i wtedy sprawdzić ponownie, powinna być już tam liczba 5

  • #20 03 Lis 2010 09:56
    margas4542
    Poziom 16  

    Z konwersji korzystałem w celach testowych ale z twojej wypowiedzi wynika że numer dnia tygodnia nie jest wyliczany "automatycznie" przez pcf-a tylko wartość początkową trzeba zdeklarować..nie wiem może nie uważnie czytam datascheta ale pewne operacje są nieco skąpo opisane...

  • Pomocny post
    #21 03 Lis 2010 10:15
    mirekk36
    Poziom 42  

    Z konwersji BCD_na_DEC w przypadku tak przesuniętej wartości dnia tygodnia możesz oczywiście korzystać tylko po co? przeanalizuj sobie kod tej funkcji to zrozumiesz dlaczego o tym mówię.

    A odnośnie automatycznego wyliczania - to podaj mi jeden przykład co w tym RTC jest automatycznie wyliczane jak piszesz? NIC ;)

    wszystko jest automatycznie inkrementowane i ew RTC dba tylko nad tym aby nie przekroczyło w trakcie tejże inkrementacji odpowiednich wartości. No gdy masz 59 sekund to po inkrementacji nie będzie przecież 60 tylko 0

    ale jak się uprzesz i wpiszesz w miejsce minut 60 czy 72 to RTC będzie grzecznie inkrementował tę wartość aż się licznik nie przekręci i nie dojdzie znowu do 59

    Podobnie jest z numerem dnia tygodnia tyle że z uwagi na to iż zapisany jest na 3 bitach to nawet RTC nie musi dbać o pilnowanie zmiany wartości z 7 na 8 bo do tego nigdy nie może dojść przy 3 bitach.

    Reasumując po co miałoby być opisane w PDF, że np godzinę czy datę możesz sobie ustawiać a np dnia tygodnia już nie. Przecież takie rozgraniczenie byłoby bez sensu. Masz pamięć RAM w RTC i możesz ją zapisać dowolnymi wartościami jakie ci przyjdą do głowy. A RTC sam "nie wymyśli" ci niczego ;)

  • #22 03 Lis 2010 17:48
    margas4542
    Poziom 16  

    Zrezygnowałem z męczenia się z ustawianiem bitów i kombinowaniem z odczytem....rozwiązanie proste i skuteczne znalazłem w sieci a co za tym idzie teraz mogę zdefiniować że od poniedziałku do piątku zegara sterujący ma reagować na nastawy czasu dla dni "roboczych" a soboty i niedziele na nastawy dla dni "wolnych"...sprawę załatwił ten kawałek kodu..

    Code:

    m=((pcf_mc[1]*10)+(pcf_mc[0]));//do postaci dwucyfrowej miesiące
    d=((pcf_dni[1]*10)+(pcf_dni[0]));//do postaci dwucyfrowej dni
    y=2010;//rok na stałe ja się zmieni to skoryguje program
    pcf_dzien=(d+=m<3?y--:y-2,23*m/9+d+4+y/4-y/100+y/400)%7-1;//wyliczanka i na LCD

  • #23 03 Lis 2010 18:16
    rpal
    Poziom 27  

    Po latach, stwierdzam że jedynym plusem tego zegara jest to że podtrzymywanie bateryjne pozwala zachować nastawy czasu i daty i w zasadzie to jedyny pożytek z tego scalaka. Jeśli co sekunde masz zamiar odczytywać czas i coś z nim robić to to jest pomyłka bo ciągnei dane po I2C a to wcale nie jest demon szybkości.Taniej i szybciej(dostep do daty i czasu) będzie jak użyjesz sobie Timer0 i zrealizujesz czas na wewnętrzym oscylatorze od atmega32. Walczyłem niedawno z czasem UNIX-owym i m.i dzieki kol.mirekk36 jakoś pokonałem ten kod więc służe gotowcem :) także z zamianą w drugą stronę czyli data->czas UNIX. To chyba sensowniejsze rozwiązanie niż ten PCF.

  • #24 04 Lis 2010 09:50
    margas4542
    Poziom 16  

    Choć to nie najnowszy scalak to na moje potrzeby w tym projekcie domowej automatyki nadzorującej ogniwo fotowoltaiczne,akumulator oraz zasilacze buforowe jest wystarczający i ma jak wspomniałeś ten atut że posiada podtrzymanie akumulatorkiem co wykorzystuje do "zapamiętania" nastaw dwu kanałowego timera sterującego który wyłącza na noc kilka będących na stend-by urządzeń zabezpieczając je przed przepięciami w sieci w przypadku krótkotrwałego zaniku napięcia.Co do pamięci to mógłbym skorzystać z 24C02 ale nie byłaby to jedyna kostka "chodząca" po I2C... a i kodu trochę by przybyło.Reasumując osiągnięty rezultat jest dla mnie zadowalający ale może któregoś dnia pokuszę się na wykorzystanie wzorca czasu DCF.Pozdrawiam i dziękuje za wszystkie posty.

 Szukaj w ofercie
Zamknij 
Wyszukaj w ofercie 200 tys. produktów TME