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

AtMega8 [Bascom] + PCF8574 - odczyt wejść

maximus22_kr 03 Paź 2011 01:31 4479 6
REKLAMA
  • #1 9987665
    maximus22_kr
    Poziom 18  
    Witam
    Próbuję zaznajomić się z obsługą wejść i wyjść w PCF8574.
    Na razie wejścia - mam odczyt 255 lub 11111111. Czy możliwy jest odczyt tak, aby dało się "wydzielić" poszczególne wejścia ?

    Teraz robię to tak, ale może da się prościej i pojedyncze wejścia:
    
    $regfile = "m8def.dat"                                      'definicja procesora
    $crystal = 4000000                                          'taktowanie procesora
    $hwstack = 32                                               ' rozmiar stosu sprzętowego
    $swstack = 10                                               ' rozmiar stosu
    $framesize = 40                                             ' rozmiar ramki
    
    Config Debounce = 30
    
    '********************* Konfiguracja wyświetlacza
    Config Lcdbus = 4
    Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 , Db7 = Portd.7 , E = Portc.3 , Rs = Portc.1
    Config Lcd = 24 * 2
    
    '********************* Konfiguracja znaku specjalnego LCD
    Deflcdchar 0 , 2 , 4 , 14 , 17 , 17 , 17 , 17 , 14          'znak "ó"
    Deflcdchar 1 , 32 , 8 , 8 , 12 , 24 , 8 , 6 , 32            ' znak"ł"
    
    '********************* Konfiguracja magistrali I2C
    
    Config I2cdelay = 10                                        ' domyślnie tryb Slow
    Config Sda = Portc.4
    Config Scl = Portc.5
    
    '********************* Konfiguracja podświetlania
    
    Config Portb.0 = Output                                     'Podswietlanie Niebieskie
    Reset Portb.0
    
    Config Portb.1 = Output                                     'Podswietlanie Czerwone
    Reset Portb.1
    
    Config Portb.2 = Output                                     'Podswietlanie Zielone
    Reset Portb.2
    
    
    Dim A As Bit
    Dim B As Bit
    Dim C As Bit
    Dim D As Bit
    Dim E As Bit
    Dim G As Bit
    
    Dim Pcf8574port As Byte
    
    Const Pcf8574write = 66
    Const Pcf8574read = 67
    
    Niebieski Alias Portb.0
    Czerwony Alias Portb.1
    Zielony Alias Portb.2
    
    Niebieski = 1
    
    Cursor Off
    
    Cls
    
    '******** Ustawienie pinów PCF8574 ( 1 - wejście, 0 - wyjście )
    'I2cstart
    'I2cwbyte Pcf8574write
    'I2cwbyte 00011111
    I2csend Pcf8574write , 255
    
    'I2cstop
    
    
    
    Do
    
    Locate 2 , 1
     Lcd Bin(pcf8574port)
    
    
    I2creceive Pcf8574read , Pcf8574port
    
    
    If Pcf8574port = 253 Then
      A = 1
      Else
      A = 0
      End If
    
    If Pcf8574port = 254 Then
      B = 1
      Else
      B = 0
    
      End If
    
      If Pcf8574port = 251 Then
      C = 1
      Else
      C = 0
      End If
    
      If Pcf8574port = 239 Then
      D = 1
      Else
      D = 0
      End If
    
      If Pcf8574port = 247 Then
      E = 1
      Else
      E = 0
      End If
    
    If Pcf8574port = 255 Then
      Locate 1 , 1
      Lcd "     "
      End If
    
    
    If A = 1 Then
      Locate 1 , 1
      Lcd "G" ; Chr(0) ; "ra "
    End If
    
    If B = 1 Then
     Locate 1 , 1
     Lcd "Lewo "
    
    End If
    
    If C = 1 Then
      Locate 1 , 1
      Lcd "Enter"
    
    End If
    
    If D = 1 Then
      Locate 1 , 1
      Lcd "Prawo"
    
    End If
    
    If E = 1 Then
      Locate 1 , 1
      Lcd "D" ; Chr(0) ; Chr(1)
    
    End If
    
    
    Loop
    
    End
    
  • REKLAMA
  • #2 9987993
    piotrva
    VIP Zasłużony dla elektroda
    Da się dużo prościej:
    
    Pcf8574port.0 'stan wejścia P0
    Pcf8574port.1 'stan wejścia P1
    Pcf8574port.n 'stan wejścia Pn
    

    Dokładnie tak samo jak obsługa poszczególnych pinów procesora. W języku BASCOM BASIC operator kropki to operator wyłuskania bitowego - pozwala na dostęp do poszczególnych bitow dowlonej zmiennej, nie koniecznie tylko rejestrów PORTx i PINx.
  • REKLAMA
  • #3 9989884
    maximus22_kr
    Poziom 18  
    Dziękuję Koledze za odpowiedź. Znalazłem gdzieś przykład, gdzie było
    PCF8574port.switchbit.0
    ale coś to nie działało jak trzeba

    Czy jest jakieś przeciwwskazanie, żeby takiej "klawiatury" używać do ustawiania zegara na PCF8563 ?
    Mam coś takiego - fragmenty kodu

    
    I2creceive Pcf8574read , Pcf8574port
    
    
    If Pcf8574port.0 = 0 Then                                   'lewo
      A = 1
      Else
      A = 0
    End If
    
    If Pcf8574port.1 = 0 Then                                   'góra
      B = 1
      Else
      B = 0
    End If
    
    If Pcf8574port.2 = 0 Then                                   'Enter
      C = 1
      Else
      C = 0
    End If
    
    If Pcf8574port.3 = 0 Then                                   'dół
      D = 1
      Else
      D = 0
    End If
    
    If Pcf8574port.4 = 0 Then                                   'prawo
      E = 1
      Else
      E = 0
    End If
    
    If A = 1 And C = 1 Then
     Gosub Menu
     End If
    
    Sub Menu:
    Start_menu = 0
    Czerwony = 1
    Niebieski = 0
    
    Do
    
    If A = 1 And C = 1 Then
       Waitms 25
          If E = 1 Then
             Incr Start_menu
             If Start_menu >= 8 Then
                Start_menu = 0
             End If
          End If
           If A = 1 Then
             Decr Start_menu
             If Start_menu >= 0 Then
                Start_menu = 8
             End If
          End If
    End If
    
    Select Case Start_menu
       Case 0 :
       Case 1 :
          Locate 1 , 1
          Lcd "Minuta"
          Waitms 500 : Cls : Gosub Ustaw_min
       Case 2 :
          Locate 1 , 1
          Lcd "Godzina"
          Waitms 500 : Cls : Gosub Ustaw_godz
       Case 3 :
          Locate 1 , 1
          Lcd "Dzien"
          Waitms 500 : Cls : Gosub Ustaw_dzien
       Case 4:
          Locate 1 , 1
          Lcd "Miesiac"
          Waitms 500 : Cls : Gosub Ustaw_mc
       Case 5 :
          Locate 1 , 1
          Lcd "Dzien tyg."
          Waitms 500 : Cls : Gosub Ustaw_dz_t
       Case 6:
          Locate 1 , 1
          Lcd "Rok"
          Waitms 500 : Cls : Gosub Ustaw_rok
       Case 7 :
          Locate 1 , 1
          Lcd "Zapisz"
          Waitms 500 : Cls : Gosub Settime
       End Select
    
    If A = 1 And C = 1 Then                                     ' przycisk, który powoduje wyjście z menu
       Niebieski = 1
       Czerwony = 0
       Exit Do
    
    End If
    
     Loop
    End Sub
    
    
    Ustaw_min:
    Locate 1 , 13
     Lcd M
     If B = 1 Then
      M = M + 1
       If M > 59 Then
       M = 0
      End If
     End If
    If C = 1 Then
     Gosub Settime
    End If
    
    Return
    
    
    Ustaw_godz:
    Locate 1 , 13
      Lcd H
       If B = 1 Then
        H = H + 1
        If H > 23 Then
       H = 0
      End If
    End If
    
    If C = 1 Then
     Gosub Settime
    End If
    
    Return
    
    Ustaw_dzien:
    Locate 1 , 13
     Lcd Day
      If B = 1 Then
       Day = Day + 1
       If Day > 31 Then
      Day = 1
     End If
    End If
    
    If C = 1 Then
     Gosub Settime
    End If
    
    Return
    
    
    Ustaw_mc:
    Locate 1 , 13
     Lcd Month
      If B = 1 Then
       Month = Month + 1
       If Month > 12 Then
       Month = 1
      End If
    End If
    
    If C = 1 Then
     Gosub Settime
    End If
    
    Return
    
    Ustaw_dz_t:
    Locate 1 , 13
     Lcd Wk
      If B = 1 Then
       Wk = Wk + 1
       If Wk > 6 Then
      Wk = 0
     End If
    End If
    
    If C = 1 Then
     Gosub Settime
    End If
    
    Return
    
    
    Ustaw_rok:
    Locate 1 , 13
     Lcd Year
      If B = 1 Then
       Year = Year + 1
       If Year > 25 Then
       Year = 10
      End If
    End If
    
    If C = 1 Then
     Gosub Settime
     Locate 1 , 13
     Lcd "            "
    End If
    
    Return
    
    


    Jedyny efekt przy naciśnięciu kombinacji dwóch klawiszy w celu wejścia do menu to migotanie podświetlania ( LCD ma podświetlanie RGB i przy wejściu w menu ma zmienić kolor ), przy wykorzystaniu pinów procesora działa znakomicie. Może to wina tego, że są dwa układy na I2C ?
  • REKLAMA
  • #4 9989913
    piotrva
    VIP Zasłużony dla elektroda
    Raczej nie jeśli nie ma konfliktu adresu. Nie mam teraz czasu na analizowanie kodu, ale wróć do wersji z przyciskami podpiętymi pod piny procesora. A potem podmień ją na odczyt z PCF'a...
  • #5 9990482
    maximus22_kr
    Poziom 18  
    Wrzuciłem na LCD wyświetlanie stanu jednego z wejść. Przed wejściem do menu działa bez problemu, tzn. wyświetla stan wejścia, po wejściu w menu nie odczytuje stanu - cały czas jet 0.

    Próbuję użyć przerwań z PCF8574. Przy naciśnięciu klawisza na wyjściu INT pojawia się napięcie około 5V ( właściwie impuls, mierzone względem GND ), więc układ wygląda na sprawny. Poniższy kod powinien na czas przyciśnięcia przycisku zmienić podświetlanie na czerwone, niestety nie robi tego. INT PCF8574 podłączam do Portd.3 - INT1 Atmega8.

    
    '********************* Konfiguracja magistrali I2C
    
    Config I2cdelay = 10                                        ' domyślnie tryb Slow
    Config Sda = Portc.4
    Config Scl = Portc.5
    
    '********************* Konfiguracja podświetlania
    
    Config Portb.0 = Output                                     'Podswietlanie Niebieskie
    Reset Portb.0
    
    Config Portb.1 = Output                                     'Podswietlanie Czerwone
    Reset Portb.1
    
    Config Portb.2 = Output                                     'Podswietlanie Zielone
    Reset Portb.2
    
    Config Portd.3 = Input
    
    '********************* Konfiguracja przerwania Int1
    
    Config Int1 = Falling
    
    On Int1 Pcf_int1
    
    Enable Interrupts
    
    Enable Int1
    
    Dim Pcf8574port As Byte
    
    Const Pcf8574write = 66
    Const Pcf8574read = 67
    
    Niebieski Alias Portb.0
    Czerwony Alias Portb.1
    Zielony Alias Portb.2
    Niebieski = 1
    
    Cursor Off
    
    Cls
    
    '******** Ustawienie pinów PCF8574 ( 1 - wejście, 0 - wyjście )
    I2cstart
    I2cwbyte Pcf8574write
    I2cwbyte 255
    'I2csend Pcf8574write , 255
    I2cstop
    
    Do
    
     Locate 1 , 13
     Lcd Bin(pcf8574port)
    
    '******** odczyt poszczególnych wejść układu
    Loop
    
    Pcf_int1:
    '******** odczyt  układu PCF8574
      Waitms 10
      I2cstart
      I2cwbyte Pcf8574read
      I2crbyte Pcf8574port , Nack
      I2cstop
      If Pcf8574port.0 = 0 Then
      Czerwony = 1
      Else
      Czerwony = 0
      End If
    
    Return
    End
    
    
  • REKLAMA
  • #6 9998042
    maximus22_kr
    Poziom 18  
    Mam pytanie odnośnie długości przewodu z sygnałem INT.
    Atmega8 z dodatkami mam na jednej płytce, a wyświetlacz z PCF8574 z przyciskami na drugiej. Wszystkie sygnały, VCC, GND, LCD, SDA, SCL idą w taśmie, ale INT o którym zapomniałem, idzie osobnym luźnym przewodem ( 15-20 cm ), jeśli chwycę ten przewód ręką to działa, jeśli puszcze, to przestaje reagować na klawisze.
  • #7 10007441
    maximus22_kr
    Poziom 18  
    Czy zapisywać w ten sposób również można ?
    Poniższy przykład zapisuje do portu P5 i działa

    
    '******** Zapis do portu układu PCF8574
     If A = 1 Then
     Pcf_out = &B11111111                                       ' stan wysoki wyjścia P5  (dec = 255 )
     Call Pcf_zapis
    End If
    
     If B = 1 Then
     Pcf_out = &B11011111                                       ' stan niski wyjścia P5 ( dec = 223 )
     Call Pcf_zapis
    End If
    
    '******** podprogram obslugi zapisu do ukladu PCF8574
    
    Sub Pcf_zapis
          I2cstart
          I2cwbyte Pcf8574write                                 ' adres zapisu
          I2cwbyte Pcf_out                                      'wartość zmiennej do zapisania
          I2cstop
    Return
    End Sub
    


    Jednak wygodniej byłoby zapisywać bezpośrednio do portu
    coś takiego - działa tylko raz, czyli mogę dać 1 i następnie 0, później już wariuje

    
    '******** Zapis do portu układu PCF8574
    
     If A = 1 Then
     Pcf_out = 1                                                ' stan wysoki wyjścia P5  (dec = 255 )
     Call Pcf_zapis
    End If
    
     If B = 1 Then
     Pcf_out = 0                                                ' stan niski wyjścia P5 ( dec = 223 )
     Call Pcf_zapis
    End If
    
    '******** podprogram obslugi ukladu PCF8574
    
    Sub Pcf_zapis
          I2cstart
          I2cwbyte Pcf8574write                                 ' adres zapisu
            'I2cwbyte Pcf8574port.5
          I2cwbyte Pcf_out                                      'wartość zmiennej do zapisania
          I2cstop
    Return
    End Sub
    
REKLAMA