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

Atmega8 + PCF8574A, komunikacja ze sterownikiem magistrali.

Mateusz.K 17 Sie 2009 21:02 2760 4
  • #1 6903504
    Mateusz.K
    Poziom 10  
    Witam.

    Czy znajdzie się ktoś tak uprzejmy i podsunie jakieś źródło z którego można korzystać do stworzenia programu w języku C do komunikacji ze sterownikiem magistrali I2C(Jakiś tutorial prosty. Wszystkiego co szukałem to większość do obsługi LCD a chodzi mi o zwykłe wystawianie wartości na wyjściu)? Chodzi mi o najprostszy program do zapalania 8 diod. Jestem początkującym programistą a chciałem spróbować coś nowego. Proszę o pomoc. Chciałem podłączyć PCF'a przy pomocy portu PC4 i PC5.
  • #2 6903777
    sinuh3
    Poziom 17  
    Kiedyś to znalazłem i przerobiłem pod atmegę128. Dawno nie ruszałem, więc nie wiem czy zostawiłem w "działającym stanie".

    Wystawianie sygnałów na wyjścia odbywa się za pomocą funkcji pcf8574_set_outputs, i tak np:

    pcf8574_set_outputs(0x22,0b01111111); na pcf'ku o adresie 0x22 zapali wszystkie wyjścia z wyjątkiem najstarszego.


    Oczywiście pinologię będziesz musiał podmienić na właściwą twojemu hardware'owi.

    Smacznego!
  • #3 6903829
    Mateusz.K
    Poziom 10  
    Dzięki za wstawkę.

    Mam pytanie, mam np. wszystkie wejścia adresowe podłączone do masy to w takim przypadku wywołanie funkcji będzie wyglądało tak:?

    pcf8574_set_outputs(0x22,0b01111111) (na wyjściach pojawią się stany wysokie?)

    Adres dla PCF8574A wygląda tak?: 0111(A0)(A1)(A2)

    Czy jest możliwość zamiast danych wyjściowych podać np jakaś zmienna wartość, która nie będzie przekraczała 8-bitów zamiast (0b01111111)

    takie wywołanie:
    pcf8574_set_outputs(Adres,Wartosc)
  • #4 6903982
    sinuh3
    Poziom 17  
    Mateusz.K napisał:
    Dzięki za wstawkę.

    Mam pytanie, mam np. wszystkie wejścia adresowe podłączone do masy to w takim przypadku wywołanie funkcji będzie wyglądało tak:?

    pcf8574_set_outputs(0x22,0b01111111) (na wyjściach pojawią się stany wysokie?)

    Adres dla PCF8574A wygląda tak?: 0111(A0)(A1)(A2)



    Nie, bo program jest napisany dla PCF8574, a on ma:
    0100(A0)(A1)(A2)

    Więc u Ciebie adres powinien wynosić zdaje się 0x38.

    Mateusz.K napisał:

    Czy jest możliwość zamiast danych wyjściowych podać np jakaś zmienna wartość, która nie będzie przekraczała 8-bitów zamiast (0b01111111)

    takie wywołanie:
    pcf8574_set_outputs(Adres,Wartosc)


    Oczywiście jest to możliwe.
  • #5 6904220
    p_zag
    Poziom 14  
    Witam
    Spójrz na mój artykuł o I2C czyli TWI na procesorze Atmega8 jest tam też sposób wykorzystania - kodowania układu PCF8583 i układu PCF8574AP (układ PCF8574AP to to samo co PCF8574A). Pisałem ten artykuł z myślą o początkujących kolegach zobacz może coś wybierzesz z mojego kodu a jest to zegarek z wyświetlaczami LED(SA10-21GWA) i układem PCF8583 współpracującym z mikroprocesorem Atmega8 oraz układami PCF8574AP na szynie TWI(i2c). Przeczytaj też "avr_twiobsluga.pdf", "atmega16mmr.pdf","C.pdf" - wszystko po polsku!

    A oto procedura zapisu do PCF8574A
    
    void TWI_wswietlacz(unsigned char scalak,
                      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 =liczba;
      TWCR =(1 << TWINT) | (1 << TWEN);
      while(!(TWCR & (1 << TWINT)));
      TWCR =(1 << TWINT) | (1<<TWEN) | (1<<TWSTO);
    } 
    

    Gdzie zmienna "scalak" to adres PCF8574A na szynie TWI(I2C), a zmienna "liczba" to wartość jaką wysyłasz do PCF8574A. Zmień nazwę procedury na taką jaka tobie odpowiada
    Ale najpierw musisz zainicjować szynę TWI(I2c) na procesorze Atmega np.
    
    void TWI_inicjacja(void)
    {
      // Czestotliwosc TWI(i2c) = 100kHz (max 100kHz) -> atmega8 taktowana wewnetrznie 8MHz (RC=8MHz)
      // ------------------------------------------------
      /* TWSR = TWS7 TWS6 TWS5 TWS4 TWS3  -   TWPS1 TWPS0 */
      TWSR =0b00000000;    // Preskaler = 1  ->> TWPS1=0 TWPS0=0
      // ------------------------------------------------------
      /* TWBR = TWBR7 TWBR6 TWBR5 TWBR4 TWBR3 TWBR2 TWBR1 TWBR0 */
      TWBR =0b00100000;
      /* Rejestr odpowiedzialny za wybór współczynnika podziału dla generatora.
         Generator ten odpowiada za czestotliwosc która jest dzielona przez
         sygnał zegarowy SCL w trybie pracy Master.
         ->> TWBR musi byc wieksze od 10 dla stabilnej pracy TWI(i2c)   
     Czyli ((8MHz/100kHz)-16)/2=32  => TWBR=32 lub TWBR=0x20 lub TWBR=0b00100000 */ 
    } 
    

    Tu musisz dobrać częstotliwość taktowania Atmegi umnie jest 8Mhz, a wzór do obliczeń jest taki:
    ((częstotliwość taktowania Atmegi/częstotliwość taktowania TWI(I2C))-16)/2=wynik (rejestr TWBR)


    https://www.elektroda.pl/rtvforum/topic1338039.html

    Przyjemnej lektury.
    Piotr
REKLAMA