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][Bascom] - jeszcze raz sprzętowe TWI Slave

mirekk36 08 Lip 2008 21:24 4022 5
REKLAMA
  • #1 5324843
    mirekk36
    Poziom 42  
    Witam,

    Panowie na poważnie wziąłem się za TWI Slawe ale za pomocą własnej obsługi w Bascomie. Na podstawie szukajki na elektrodzie i kilku postów kolegów zdaje się szymtro i robiw udało mi się w końcu zrobić to aby AVR zaopatrzony w sprzętowe TWI grzecznie odbierał przesyłane do niego bajty. Zrobiłem to tak:

    Twar = &B10000000                                           'Adres=128, jeśli chcesz general call to bit.0=1
    Twbr = &B00000000       'częstotliwość TWI=0 bo pracujemy jedynie jako Slave
    Twcr = &B01000101       'odpalamy TWI, zezwalamy na przerwania od TWI, ustawiamy aby potwierdzał sygnałem ACK
    
    
    Dim Status As Byte       ' Status operacji na magistrali odczytywany w przerwaniu
    Dim Run As Bit       'Flaga żądania wysłania danych do LCD - ustawiana w przerwaniu
    Dim Wskaznik As Byte
    Dim Dane(16) As Byte
    Dim I As Byte
    
    
    On Twi I2c_check
    Enable Interrupts
    
    
    Do
    
       If Run = 1 Then
          Led = Not Led
          Wskaznik = 0
          Reset Run
       End If
    
    Loop
    
    
    
    'Przerwanie od TWI
    I2c_check:
    
     'Odczytujemy status operacji maskując 3 ostatnie - nieważne dla nas bity
     Status = Twsr And &B11111000
    
     If Status = &H80 Then
       'Wcześniej zaadresowany Slave odebrał daną i potwierdził ACK - zapełniamy tablicę danych
       Incr Wskaznik
       Dane(wskaznik) = Twdr
      'End If
    
      Elseif Status = &HA0 Then
       'Odebrano STOP lub ponowny START
       Set Run
    
       Elseif Status = &HA8 Then
          Twdr = Command
       End If
    
     Set Twcr.twint                                             
    Return


    wprawdzie w tym prościutkim teście nic nie robię z odebranymi danymi tylko migam diodą LED gdy są one odebrane, ale

    .... tu się rodzi moje pytanie: jak zrobić żeby teraz Slave coś tam wysłał do Mastera ???

    jest tam już widać taki

       Elseif Status = &HA8 then
          Twdr = Command
       End If


    ale to chyba nie spowoduje wysłania zmiennej Command do Mastera??? coś trzeba zapewne jeszcze zrobić a po drugie jeśli już to jak po stronie mastera to wysyłać???

    narazie to wysyłanie do Slave (które mi działa wyśmienicie) robię w masterze tak:

             I2cstart
             I2cwbyte 128
             I2cwbyte 22        'jakaś tam dana do Slave
             I2cstop


    a gdybym miał odebrać coś ze Slabe???? może ktoś już się z tym męczył i może mnie chociaż naprowadzić choć krok dalej???? (please)

    (wiem wiem oczywiście , że w PDF'ie wszystko jest opisane ale jakoś nie mogę sam tego na Bascom że się tak wyrażę "przetranskodować")

    pozdrawiam i czekam na info
  • REKLAMA
  • #2 5325747
    szymtro
    Poziom 30  
    Popatrz jeszcze raz na mój kod. Tam ewidentnie slave nadaje do mastera kilka bajtów danych (po kolei). To tamto to był zdalny wyświetlacz lcd (c2051 master) który sobie czytał dane z centralki (M8 slave) i pokazywał je na lcd.
  • REKLAMA
  • #3 5326021
    mirekk36
    Poziom 42  
    szymtro -> dziękuję za zainteresowanie moim tematem ale wiesz? użyłem dokładniuśko twojego kodu:

    Twi_przerwanie:
       Twi_status = Twsr And &B11111000
       If Twi_status = &H60 Then                                'SLA+W, ACK sended
       Elseif Twi_status = &H80 Then                            'SLA+W data received, ACK sended
       Elseif Twi_status = &HA0 Then                            'STOP or repeated START
          Set Twcr.twea
       Elseif Twi_status = &HA8 Then                            'SLA+R, ACK sended
          'Twdr = Twi_tx_bufor(1)
          'Twi_licznik = 2
          Twdr = Command
          Set Run
       Elseif Twi_status = &HB8 Then                            'SLA+R, ACK received
          'Twdr = Twi_tx_bufor(twi_licznik)
          'If Twi_licznik < Twi_licznik_ograniczenie Then Incr Twi_licznik
          Twdr = Address
    
       Elseif Twi_status = &HC0 Then                            'SLA+R,NACK received
       Elseif Twi_status = &H00 Then                            'bus ERROR
          Set Twcr.twsto
       End If
       Twcr.twint = 1
    Return


    gdzie nawet już nie używam bufora tylko chcę wysłać Command i Address z RC5 przykładowo. Ostatni jaki odebrał Slave.

    i podpowiedz mi co źle robię w masterze, że nie chce on za chiny jakby odebrać tych 2 bajtów a robię to w mastrze tak:

             I2cstart
             I2cwbyte &B10000001
             I2crbyte Command Ack
             I2crbyte Address Nack
             I2cstop


    adres slave układu u mnie to 128 (&B10000000) ale gdy robię odczyt to daję 129 (&B10000001) , i kicha po tych 2 poleceniach i2crbyte , nawet tylko jednym - zmienne command i address w ogóle się nie zmieniają bo dalej w pętli wyświetlane są wartości te, którymi były zainicjalizowane przed wejściem do pętli głównej. A master w pętli co ok sekundę próbuje to odczytać ze Slave

    Dodano po 1 [godziny] 20 [minuty]:

    okazuje się, że u mnie nigdy nie dochodzi do Twi_status = &HB8 (bo wstawiłem tam sobie jeszcze zapalenie diody LED)

    dioda LED zapala się tylko gdy Twi_status = &HA8

    o co tutaj może chodzić??? kurczę Slave już mi jakby ładnie odbiera - tylko z tym odesłaniem przez niego bajtów jest mega kicha :(

    Dodano po 4 [godziny] 3 [minuty]:

    kurczę udało się w KOŃCU coś odebrać od Slave ale za pomocą takiej kombinacji rozkazów:

    dim Aa(2) as byte
    
    I2creceive &B10000001 , Aa(1) , 1 , 2


    ale czy może ktoś mi łaskawie wyjaśnić czym to się różni od zapisu odczytu pokazanego powyżej za pomocą i2crbyte ??? bo już się nie mogę połapać w tym wszytskim
  • REKLAMA
  • #4 5330730
    mirekk36
    Poziom 42  
    hmmm jeszcze raz zapytam, i poproszę fachowców od Bascoma o podpowiedź:

    czym różni się taka sekwencja poleceń:

    i2cstart
    i2cwbyte Slave_adr_W
    i2cwbyte 33
    i2cstart
    i2cwbyte Slave_adr_R
    i2crbyte zmienna1, ACK
    i2crbyte zmienna2, NACK
    i2cstop



    od takiej sekwencji poleceń:

    Dim Zmienne(2) as Byte
    
    Zmienne(1) = 33
    i2creceive Slave_adr_W, Zmienne(1), 1, 2


    (oczywiście nie chodzi mi to u różnicę, że w jednym przypadku wczytuję dane do pojedyńczych zmiennych a w drugim do tablicy) - chodzi o to, że jedno polecenie działa a drugie nie(dokładnie nie działa ta pierwsza sekwencja). A skoro nie znam pczyczyny to muszę tych poleceń jak narazie po "omacku" używać :(
  • REKLAMA
  • #5 5382036
    ZbeeGin
    Poziom 39  
    A jak kolega określił adresy Slave_adr_W i Slave_adr_R? Slave_adr_W ma być mniejszy o 1 od Slave_adr_R.
  • #6 5382162
    mirekk36
    Poziom 42  
    Slave_adr_W = 128
    Slave_adr_R = 129

    wyczytałem, że jak robię sobie i2creceive Slave_adr_W to poleenie to samo dodaje właśnie 1 do adresu aby przekształcić go w adres do odczytu

    tylko ciekawi mnie dlaczego te dwie sekwencje działają różnie. Tzn ta z i2creceive działa:

    
    Dim Zmienne(2) as Byte 
    
    Zmienne(1) = 33 
    i2creceive Slave_adr_W, Zmienne(1), 1, 2
    

    a ta rozbita na poszczególne rozkazy nie:

    
    i2cstart 
    i2cwbyte Slave_adr_W 
    i2cwbyte 33 
    i2cstart 
    i2cwbyte Slave_adr_R 
    i2crbyte zmienna1, ACK 
    i2crbyte zmienna2, NACK 
    i2cstop
REKLAMA