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

[AVR-gcc] Atmega16 i PCF8563 - błędny odczyt czasu, problem z rejestrami godzin i sekund

Pagodin 23 Paź 2007 12:06 2145 1
REKLAMA
  • #1 4406329
    Pagodin
    Poziom 10  
    Posty: 48
    Witam,


    Problem polega na tym, że chcę odczytać prawidłowo czas z PCF8563 jednak nie udaje mi się to z pełnym powodzeniem. Z PCFa odczytuję 3 rejestry: godziny, minuty i sekundy

    gdy sekundy osiągną liczbę 40 wtedy w miejsce godzin również pojawia się liczba 40

    po przekręceniu się rejestru godziny z powrotem wracają do normalnego stanu

    jeżeli natomiast godziny posiadają już jakąś wartość np.20

    wtedy gdy sekundy osiągną wartość 40 to ta wartość dodaje się do godzin


    Nie mam pojęcia na czym polega błąd. Poniżej podaje listing najważniejszych funkcji programu.

    
    #define F_CPU 12000000UL
    #define SCL_CLOCK  400000L
    
    /****************************************************************************/
    // I2C
    /****************************************************************************/
    
    void i2c_init(void)
    {
       
      TWSR = 0;                         
      TWBR = ((F_CPU/SCL_CLOCK)-16)/2;  
    
    }
    unsigned char twi_start(void) 
    {      
      TWCR |= 0b11100100; 
      while (!(TWCR & 0b10000000)); 
      TWCR &= 0b01011111; 
      return 0; 
    } 
    void twi_stop(void) 
    {    
      TWCR |= 0b10010100;
    } 
    unsigned char twi_wr(unsigned char data_byte) 
    {      
      TWDR = data_byte; 
      TWCR |= 0b10000000; 
      while (!(TWCR & 0b10000000));  
      return 0; // zwroc kod !error    
    } 
    unsigned char twi_rd(unsigned char ack) 
    { 
      if (ack == 1) 
        { 
          TWCR |= 0b10000000;  
        } 
      else 
        {  
          TWCR &= 0b10111111;  
        }; 
      while (!(TWCR & 0b10000000)); 
      return TWDR; 
    }
    
    /****************************************************************************/
    // z BCD
    /****************************************************************************/
    
    unsigned char FROMBCD(unsigned char in)
    {
    return (((in) >>4) * 10 + ((in) & 0xf));
    }
    
    
    /****************************************************************************/
    // odczyt z pcf
    /****************************************************************************/
    
    
    							twi_start();
    							twi_wr(0xA2);
    							twi_wr(0x04);
    							twi_start();
    							twi_wr(0xA3);
    							roboczy=twi_rd(0);
    							twi_stop();
    roboczy=roboczy&0x3F;
    godzina=FROMBCD(roboczy);
    
    							twi_start();
    							twi_wr(0xA2);
    							twi_wr(0x03);
    							twi_start();
    							twi_wr(0xA3);
    							roboczy=twi_rd(0);
    							twi_stop();
    roboczy=roboczy&0x7F;
    minuta=FROMBCD(roboczy);
    
    							twi_start();
    							twi_wr(0xA2);
    							twi_wr(0x02);
    							twi_start();
    							twi_wr(0xA3);
    							roboczy=twi_rd(0);
    						        twi_stop();
    roboczy=roboczy&0x7F;
    sekunda=FROMBCD(roboczy);
    


    Za wszelkie sugestie bardzo dziękuję.

    Pozdrawiam
  • REKLAMA
  • #2 4406615
    arturt134
    Poziom 27  
    Posty: 792
    Pomógł: 76
    Ocena: 24
    Wprowadź w swoim kodzie zmiany. oto one:

    twi_start:
    zmień 1 linię na:
    TWCR = TWINT + TWSTA + TWEN
    usuń 3 linię

    twi_stop:
    zmień na:
    TWCR = TWINT + TWSTO + TWEN

    twi_wr:
    zmień 2 linię na:
    TWCR = TWINT + TWEN

    twi_rd:
    zmień 3 linię na:
    TWCR = TWINT + TWEN + TWEA
    zmień 7 linię na:
    TWCR = TWINT + TWEN

    Dodatkowo powinieneś sprawdzać TWSR po każdym poleceniu, czy status jest jaki być powinien.

    To co napisałem jest dokładnie opisane w PDF-ie do ATmega16, na str. 185. Jeżeli się gdzieś pomyliłem (robiłem to na poczekaniu, więc łatwo o pomyłkę) to przepraszam.
REKLAMA