-
        

Ergebnis 1 bis 3 von 3

Thema: TWI Multimaster Betrieb mit TWI_LCD möglich

  1. #1
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    25.03.2006
    Ort
    Hinsdorf
    Alter
    43
    Beiträge
    379

    TWI Multimaster Betrieb mit TWI_LCD möglich

    Anzeige

    Hallo

    ich nutze die TWI Multimasterumgebung aus RN Wissen. Ich habe nun den TWI Bus und möchte nun gern ein LCD mit integrieren. Dazu habe ich den Artikel AN #118 - I2C LCD and Keboard library bei MCS gefunden.
    Wie gelesen so auch getan, LCD aufgebaut und mit Testcode gefüttert. Siehe da => es funzt! Doch leider, wenn ich versuche diesen in meinen:
    Code:
    $regfile = "m8def.dat"
    $crystal = 16000000
    
    $include "MyTWI.bas"                                                            'dafür wird noch die MyTWI.lib benötigt
    $lib "Lcd_i2c.lib"
    $baud = 19200
    
    $hwstack = 80
    $swstack = 80
    $framesize = 80
    '------------------------------------------------------------------------------- Config TWI-LCD 2x16
    Config Lcd = 16 * 2
    Config Lcdbus = 4
    Initlcd
    Cursor Off
    Cls
    Const Pcf8574_lcd = &H40                                                        'Defines the address of the I/O expander for LCD
    Config Scl = Portc.5                                                            'Configure I2C SCL
    Config Sda = Portc.4                                                            'Configure I2C SDA
    Dim _lcd_e As Byte                                                              'Needed to control 4 line LCD
    _lcd_e = 128                                                                    'Upper half of 4-line display is selected
    Dim A As Byte
    '------------------------------------------------------------------------------- Configuration DS1820
    Config 1wire = Portd.4
    Dim Bd(9) As Byte
    Dim J As Byte , Tmp As Byte ,
    Dim T1 As Integer
    '------------------------------------------------------------------------------- Sendevariablen deklarieren
    
    Dim Temp1 As Single
    Dim Temperaturbyte(6) As Byte At Temp1 Overlay                                  'Temperaturbyte(5), 4 an der Zahl, wird über Temp1 (single=4byte) gelegt, byte(5) enthält Subadresse
                                                                                      'dabei nimmt Temperaturbyte(1) die Speicherstelle des 1.Byte von Temp1 ein
    Dim Licht As Word
    Dim Lichtbyte(6) As Byte At Licht Overlay
    Dim Send_flag As Bit
    '------------------------------------------------------------------------------- Timer1 konfigurieren
    Config Timer1 = Timer , Prescale = 256                                          'Timer mit 1sec Überlauf
    On Timer1 Counter_irq
    Const Timer1vorgabe = 18661
    Enable Timer1
    Dim Timecount As Word
    
    '------------------------------------------------------------------------------- Configuration Licht A/D Wandler an PortC=0 (10bit)
    Config Adc = Single , Prescaler = Auto , Reference = Off
    
    
    'Pc0 = Lichtsensor
    
    '-------------------------------------------------------------------------------  TWI Variablen
    Const Mn1_adr = &H6C                                                            'lokale I2C Adresse   (als Slave)
    'Const Mn2_adr = &H6A                                                            'fremde I2C Adresse   (als Master)
    
    Dim Twi_mst_buff(24) As Byte                                                    'Buffer für Masterfunktionen
    Dim Twi_slv_buff(24) As Byte                                                    'Buffer für Slavefunktionen
    
    Dim Temp As Byte , Komando As Byte
    Dim Slave_adress As Byte , Send_byte As Byte , Speicherpointer As Byte
    Declare Sub Master_transmit(byref Slave_adress As Byte , Byref Send_byte As Byte , Byref Speicherpointer As Byte)       'Declarierung der Sub =>mit byref wird immer nur ein Zeiger auf die Speicherstelle
                                                                                              ' verwiesen und nicht ein Wert übergeben
    Twi_slv_addr = Mn1_adr                                                          'lokale I2C-Adresse
    Twi_sr_data = Varptr(twi_slv_buff(1))                                           'datenbuffer empfang
    Twi_st_data = Varptr(twi_slv_buff(1))                                           'datenbuffer senden
    
      Twar = Twi_slv_addr + 1                                                       'I2C Adress Mega32 + GCA
      Config Twi = 100000                                                           'I2C Speed
      On Twi Twi_mst_slv_isr , Nosave                                               'ISR f. TWI
      Gosub Twi_sense                                                               'Aktivieren Slave-Funktion
      Enable Interrupts                                                             'Generell
    
    '******************************************************************************* Hauptprogramm
    Do
     Disable Interrupts
     Lcd "licht " ; Licht
     Enable Interrupts
    1wwrite &HCC : 1wwrite &H44                                                     'DS1820 Messung starten
    
    '******************************************************************************* TWI Betrieb
    'praktisches Beispiel zu Anzeige der Daten, werden im Prog nicht benötigt bis auf die Flagabfrage
    'Twi_slv_flag =
     '   * 0 Keine Slave Aktion hat stattgefunden
     '   * &H60 Daten wurden empfangen. Sie stehen im Buffer mit der Länge Twi_sr_cntr
     '   * &HA8 Daten wurden gesendet. Sie stehen im Buffer mit der Länge Twi_st_cntr
     '   * &H70 Gca -daten Wurden Empfangen.
    
    If Twi_slv_flag <> 0 Then                                                       'ständige Abfrage ob als Slave Daten anliegen  =>Vorsicht, der Bus ist solange blockiert
    
             Select Case Twi_slv_flag
             Case &H60 :
                     For Temp = 1 To Twi_sr_cntr                                    ' fülle "Temp" für empfangene Bytes
                       'If Twi_mst_addr = &H6A Then                                  ' ist Masteradresse &H6E?
                         Print "SlaveAdress" ; Spc(10) ; Hex(twi_slv_addr)          'schreibe eigene Adresse
                         Print "MasterAdress" ; Spc(10) ; Hex(twi_mst_addr)         'schreibe Adresse von wem etwas empfangen wurde
                         Komando = Twi_slv_buff(temp)                               'fülle "Temp1" mit Daten
                         Print "temp wasser" ; Komando                              'schreibe gesendete DAten
                       'End If
                     Next                                                           'wurden mehrere Bytes geschickt (Twi_mt_cntr = 1...) wird die Schleife durchlaufen
                                                                                ' und dabei "Temp" gefüllt bis "Twi_sr_cntr" leer ist
    '( For Temp = 1 To Twi_sr_cntr
                        Print "TempZähler " ; Spc(10) ; Temp                        ' schreibe Zählerstand (empfangene Bytes)
                       If Twi_mst_addr = &H6C Then                                  ' ist Masteradresse &H6C?
                       Print "SlaveAdress" ; Spc(10) ; Hex(twi_slv_addr)
                       Print "MasterAdress" ; Spc(10) ; Hex(twi_mst_addr)
                       Temp2 = Twi_slv_buff(temp)
                       Print "temp hof" ; Spc(10) ; Temp1
                       Next
                     End If
    ')
    
             End Select
    
             Print
             Twi_slv_flag = 0                                                       'löschen marker
             Twi_slv_stat = 0                                                       'löschen marker
             Gosub Twi_sense                                                        'alles wieder enablen
                                       'und Bus freigeben
          End If
    
    '******************************************************************************* Zeitcounter für Temperatur aus DS1820 und Übertragung über TWI
    
    If Timecount = 8 Or Timecount = 24 Or Timecount = 48 Then                       ' aller 8,24,48sek. wird eine vollständige Temperatur convertierung angestoßen
       Send_flag = 1                                                                'Send_flag verhindert doppeltes senden
       Start Adc
       Licht = Getadc(0)
       Stop Adc
       'Locate 1 , 1
       Lcd "licht " ; Licht
    
          1wreset                                                                   ' reset the bus
          1wwrite &HCC                                                              ' read internal RAM
          1wwrite &HBE                                                              ' read 9 data bytest
          Bd(1) = 1wread(9)                                                         ' read bytes in array
          1wreset                                                                   ' reset the bus
    
          If Tmp = 1 Then Decr Bd(1)
             T1 = Makeint(bd(1) , Bd(2))
             T1 = T1 / 2
             Temp1 = Bd(8) - Bd(7)
             Temp1 = Temp1 / Bd(8)
             Temp1 = T1 + Temp1
             Temp1 = Temp1 - 0.25
          End If
    
        Lowerline
        Lcd "temp " ; Temp1
    
    If Timecount = 10 Or Timecount = 26 Or Timecount = 50 Then                      'sendet aller 10sec den Temperaturwert mit Adresse 6A
       If Send_flag = 1 Then
          Send_flag = 0
          Slave_adress = &H6A                                                       'Sendeadresse
          Send_byte = 6
          Temperaturbyte(5) = &H6C                                                  'Anzahl zu sendene Bytes (ersten 4 sind die Tempwerte, 5 ist Subbyte
          Temperaturbyte(6) = 1                                                     'Subadresse entspricht der Herkunft der Daten: 1=> Temperaturwerte
          Call Master_transmit(slave_adress , Send_byte , Temperaturbyte(1))        'Aufruf der Callprozedur mit der Adresse und der zu übergebenen Adresspointer
          Twi_sr_cntr = 0
    
          Print "sende Temperatur" ; Spc(3) ; Temp1
          Print "Temperaturbyte1" ; Spc(3) ; Hex(temperaturbyte(1))                 'ausgeben der 4 einzelnen Temperaturbyts aus dem Tempbytes vom Hofslave
          Print "Temperaturbyte2" ; Spc(3) ; Hex(temperaturbyte(2))
          Print "Temperaturbyte3" ; Spc(3) ; Hex(temperaturbyte(3))
          Print "Temperaturbyte4" ; Spc(3) ; Hex(temperaturbyte(4))
    
        End If
    End If
    
    
    If Timecount = 14 Or Timecount = 30 Or Timecount = 54 Then                      'Timecounter für Sendeflag
    Send_flag = 1                                                                   ' Sendeflagsetzen um nur immer einmal die Temp/Lichtwerte zu senden
    End If
    
    If Timecount = 15 Or Timecount = 31 Or Timecount = 55 Then                      'sendet aller 10sec den Temperaturwert mit Adresse 6A
       If Send_flag = 1 Then
          Send_flag = 0
       Slave_adress = &H6A                                                          'Sendeadresse
       Send_byte = 6
       Lichtbyte(5) = &H6C                                                          ' zu sendene Bytes
       Lichtbyte(6) = 2                                                             'Subadresse entspricht der Herkunft der Daten: 1=> Lichtwerte
       Call Master_transmit(slave_adress , Send_byte , Lichtbyte(1))                'Aufruf der Callprozedur mit der Adresse und der zu übergebenen Adresspointer
       Twi_sr_cntr = 0
    
         Print "sende Licht" ; Spc(3) ; Licht
         Print "Lichtbyte1" ; Spc(3) ; Hex(lichtbyte(1))                            'ausgeben der 4 einzelnen Temperaturbyts aus dem Tempbytes vom Hofslave
       Print "Lichtbyte2" ; Spc(3) ; Hex(lichtbyte(2))
       Print "Lichtbyte3" ; Spc(3) ; Hex(lichtbyte(3))
       Print "Lichtbyte4" ; Spc(3) ; Hex(lichtbyte(4))
    
       End If
    End If
    
    '******************************************************************************* nach Datenempfang als Slave umschalten auf Master und Daten senden
    
      If Komando = &H1A Then
            'Print "Temp:" ; Fusing(temp1 , "#.##") ; "C"                            'ist Masteranforderung 26 dann schicke Temperatur1
            'print "Lichtwert" ; Spc(3) ; licht
            Slave_adress = &H6A
            Send_byte = 5
            'Sub_adr = 1
       Call Master_transmit(slave_adress , Send_byte , Temperaturbyte(1))
        Komando = 0
        Twi_sr_cntr = 0                                                             'ja
      End If
    
    
    Loop
    End
    
    
    '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ SUBS
    Counter_irq:
    
     Timer1 = Timer1vorgabe
     Incr Timecount
                                                                                     ' increment every sec the counter with 1
     If Timecount => 60 Then                                                        ' 60 here is the 1min
     Timecount = 0
                                                                                    ' wenn nicht dann lade StartWert in Timer1
    End If
    Return
    
    '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Senderoutine TWI
    Run_wait_master:
          Gosub Mst_start                                                           'aufruf
     Select Case Twi_mst_flag                                                       'ergebnis ?
          Case Twi_m_sent:
                   Locate 3 , 1                                                     'gesendet
                   Lcd "<<MASTsent:" ; Hex(twi_mst_addr) ; " ";
                   Print
                   For Temp = 1 To Twi_mt_cntr
                   Locate 3 , 14
                         Lcd Twi_mst_buff(temp);
                   Next
                   Print
                   Twi_mst_flag = 0
    
         Case Twi_m_recv:
                   Locate 4 , 1                                                     'geholt
                    Lcd ">>MASTread:" ; Hex(twi_mst_addr) ; " ";
                   Print
                   For Temp = 1 To Twi_mr_cntr
                   Locate 4 , 14
                    Lcd Twi_mst_buff(temp);                                         'Hex(twi_mst_buff(temp))
                   Next
                   Print
                   Twi_mst_flag = 0
    
                   End Select
    
       Return
    
    '############################################################################### Sendesub
    '   Beispiel 8 byte senden,
    '     dann mit Rep.Start von gleicher adresse 3 Byte empfangen
    'Nur senden
    
       'Twi_mst_addr = Mn2_adr                                   'I2C adresse ZIEL
       'Twi_mt_cntr = 8                                          '  8 Byte senden
       'Twi_mt_data = Varptr(twi_mst_buff(1))                    ' Daten
       'Twi_mr_cntr = 0
    'Nur abholen
    
       'Twi_mst_addr = Mn2_adr + 1                               'I2C adresse ZIEL (+R)
       'Twi_mr_cntr = nn                                         ' wieviele Byte
       'Twi_mr_data = Varptr(twi_mst_buff(1))                    ' empfangsbuffer
    
    
    
    Sub Master_transmit(byref Slave_adress As Byte , Byref Send_byte As Byte , Byref Speicherpointer As Byte)       'Sub in der die Adresse des Empfängers steht und der Zeiger aus der Callprozedur
    
       Twi_mst_addr = Slave_adress                                                  'I2C Adresse Slave
       Twi_mt_cntr = Send_byte                                                      '4 Byte senden
       Twi_mt_data = Varptr(speicherpointer(1))                                     'Daten senden => Varptr(Speicherpointer(1)) Speicherpointer = Zeiger auf eine
                                                                                     ' Speicherstelle, nicht auf den Wert, aus der Callsubroutine (Temperaturbyte(1))
       Twi_mr_cntr = 0
    
       'Twi_mr_cntr = 1                                          ' dann 3 Byte empfangen
       'Twi_mr_data = Varptr(twi_mst_buff(1))                    ' empfangsbuffer
    
       Gosub Run_wait_master                                                        ' auf gehts
    
       End Sub
       Return
    '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ LCD-TWI
    einzufügen geht auf dem TWI Bus gar nichts mehr! Vertragen sich die beiden TWI Funktionen überhaupt und wie und was muss dazu geändert werden?
    Eine Hilfestellung wäre super!

    Danke MAT

  2. #2
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    22.05.2005
    Ort
    12°29´ O, 48°38´ N
    Alter
    48
    Beiträge
    2.731
    Hallo,

    die Lib von Bascom, für das LCD über I2C, verwendet die Bascom-Internen TWI-Befehle, und wenn die TWI-lib nicht ins Programm aufgenommen wurde, macht es das per Software-I2C !
    Aber Grundsätzlich verträgt sich das nicht mit der Version vom Wiki, da Bascom sich nicht um Multimaster kümmert, was der Grund für den Wiki-Artikel war.

  3. #3
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    18.05.2007
    Beiträge
    329
    Hallo Matsche,

    vor einigen Wochen hab ich mit Hilfe von PicNick eine Lib für LCD an I2C erstellt. Diese ist aber sicherlich auch nicht Multimastertauglich. Jedoch ist sie quelloffen und kann/soll/darf erweitert und geändert werden. Für Detailfragen in den ASM-Tiefen bin ich aber der Falsche, da wäre PicNick mit Sicherheit der richtige Mann

    http://www.gerold-online.de/cms/index.php?id=146

    Günter

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •