Elektroda.pl
Elektroda.pl
X
Testo
Proszę, dodaj wyjątek dla www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

Licznik energii - ADE7753, ATmega32 (odczyt rejestrów).

25 Lis 2017 23:28 981 4
  • Poziom 2  
    Witam!
    Realizuję układ do pomiaru energii elektrycznej pobieranej przez odbiorniki z sieci domowej 230V. W tym celu wykorzystałam układ ADE7753 oraz ATmegę32.
    Początkowo, aby sprawdzić czy układ działa poprawne postanowiłam zainicjować komunikację SPI oraz odczytać rejestry napięcia i prądu (bez wcześniejszej kalibracji). Wyniki pomiarów wyświetlane są na wyświetlaczu LCD. Pomiar prądu zdaje się że jest wykonywany poprawnie, ponieważ otrzymany wynik ma w miarę stałą wartość, a po podłączeniu odbiornika (lampka) jego wartość zawsze wzrasta o taką samą liczbę. Natomiast mam problem z odczytem napięcia, ponieważ otrzymany wynik wydaje się być losowym, a wartości wahają się od np. 80 - 16500. Po podłączeniu odbiornika odczyt z rejestru napięcia jest taki sam, liczby wciąż są losowe i nie widzę pomiędzy nimi żadnej zależności.
    Dodam, że kod programu jest taki sam dla prądu jak i napięcia, zmienia się tylko adres rejestru. Podejrzewam zatem, że takie zachowanie układu może się wiązać z błędem w schemacie, a konkretnie w okolicy kanału napięciowego ADE.

    Czy ktoś ma doświadczenie z układem ADE7753 i byłby w stanie powiedzieć mi skąd wynika losowość otrzymywanych wyników?
    Załączam fragment schematu (w kanale napięciowym, w dzielniku, użyłam innych rezystorów niż na schemacie: 1k i 787k (łączna wartość wynikająca z połączenia szeregowego)
    Licznik energii - ADE7753, ATmega32 (odczyt rejestrów).
  • Testo
  • Poziom 10  
    Myślę, że na początek powinnaś sprawdzić ścieżki płytki montażowej, aby wyeliminować możliwość występowania zwarć lub przerw a także zweryfikować, czy przebieg ścieżek jest zgodny z projektem. Ponadto sprawdź jeszcze pod kątem zwarć zamontowane w układzie kondensatory, często zdarza się, że to one właśnie są przyczyną nieprawidłowego działania całego układu. Co do prawidłowości samego schematu, to za wiele ci nie pomogę, ale z pewnością na forum znajdą się osoby, które udzielą fachowej porady w tym zakresie i ocenią, czy załączony schemat nie zawiera błędów.
  • Testo
  • Poziom 2  
    Ciągłość ścieżek dokładnie sprawdziłam miernikiem. Wszystko zdaje się być w porządku.
    Niestety trzeba szukać problemu gdzie indziej.

  • Poziom 28  
    Wklej proszę całość kodu - możliwe że niepoprawnie konfigurujesz rejestry układu.
  • Poziom 2  
    Od czasu napisania posta zmieniłam częstotliwość SCK (w fukcji "InitSpiMaster") z fosc/128 na fosc/4 . Teraz otrzymywane wartości z rejestru napięcia zachowują pewną zależność: pierwszy odczyt to liczba ok 20 000, następnie z każdym kolejnym odczytem liczba spada aż do wartości ujemnych i ponownie rośnie.
    Sprawdziłam też zachowanie układu w przypadku zasilania go stałym napięciem 5V. Wtedy wartość odczytywana z rejestru napięcia jest stała. Do obniżenia napięcia z 230V AC na 5V DC użyłam gotowej przetwornicy, czy może ona mieć wpływ na brak stabilności odczytu?
    Kod programu:

    Code:

    void InitSpiMaster(void)
    {
       DDRB = ( 1 << DDB5 ) | ( 1 << DDB7 )| ( 1 << DDB4 );
       DDRB &= ~(1 << DDB6);
       SPCR = ( 1 << SPE ) | ( 1 << MSTR ) | ( 0 << SPR1 ) | ( 0 << SPR0 );
       SPSR = 0x00;
    }
    unsigned char spi_txrx(unsigned char data)
    {
       SPDR = data;
       while(!(SPSR & (1<<SPIF)));
       return SPDR;
    }
    void spi_start(void)
    {
       spi_end();
       PORTB &= ~(1 << PB4);
       return;
    }
    void spi_end(void)
    {
       PORTB = (1 << PB4);
       return;
    }
    unsigned long ade7753_write_read3( char addr)
    {   
       unsigned char rv1,rv2,rv3;
       unsigned long regval;
       spi_start();
       _delay_us(10);
       spi_txrx(addr);
       _delay_us(5);
       rv1= spi_txrx(0x00);
       _delay_us(5);
       rv2= spi_txrx(0x00);
       _delay_us(5);
       rv3= spi_txrx(0x00);
       spi_end();
       regval = (unsigned long)(rv1<<16) | (unsigned long)(rv2<<8) | (unsigned long)rv3;
       return regval;
    }


    int main(void)
    {
       InitSpiMaster();
    lcd_init(LCD_DISP_ON);
       lcd_clrscr();
       _delay_ms(1000);
       char bresult [100];
    unsigned long rr2, rr3;
    while (1)
    {
          for (int i =1; i<=2; i++)
          {
             if (i==1)
             {
                rr2 = ade7753_write_read3(0x17);
                lcd_gotoxy(0,0);
                sprintf(bresult,"u=%d ",rr2);
                lcd_puts(bresult);
                _delay_ms(500);
             }
             if (i==2)
             {
                rr3 = ade7753_write_read3(0x16);
                lcd_gotoxy(0,1);
                sprintf(bresult,"i=%d ",rr3);
                lcd_puts(bresult);
                _delay_ms(500);
             }
    }
    _delay_ms(500);
    }
    }