- Akku Tests und Balkonkraftwerk Speicher         
Seite 5 von 5 ErsteErste ... 345
Ergebnis 41 bis 49 von 49

Thema: TWI-slave ohne lib

  1. #41
    Benutzer Stammmitglied
    Registriert seit
    15.09.2004
    Beiträge
    30
    Anzeige

    Powerstation Test
    Hallo,
    das mit dem Hardware TWI unter Bascom geht ja mit diesem Programm
    so gut das ich mich frage warum ich die I2C_TWI.LBX bestellt habe ....

    Aber ich wollte das abholden der Daten mit Interrupts machen ,
    das müsste ja gehen (mega, da in der m8def.dat
    TWI angelegt ist, aber bei mir funktioniert es leider nicht
    eine Idee ?
    Was mache ich falsch ?
    oder ist der TWI Interrupt doch gesperrt das man die TWI slave library kaufen muss ?
    Danke für eine Hilfe

    so versuche ich es (wir auch so von Bascom angenommen und ohne Fehlermeldung kompiliert):


    On Twi Twi_isr
    Enable Twi
    Enable Interrupts
    .
    Program:
    .
    .
    Goto Program



    Twi_isr:
    .
    Wird leider nie aufgerufen
    .
    .
    Return

  2. #42
    Benutzer Stammmitglied
    Registriert seit
    15.09.2004
    Beiträge
    30
    Hallo,
    mein Problem ist gelöst, ich habe meinen Fehler gefunden .
    Habe übersehen das an anderer stelle im Prog das TWIE im TWCR
    zurückgesetzt wird .
    Hab’s korrigiert und jetzt läuft der Aufruf per Interrupt so wie er soll .

  3. #43
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    15.01.2006
    Ort
    Biberach
    Alter
    35
    Beiträge
    485
    Hi,
    tut mir Leid, dass ich noch in diesen alten Thread etwas poste, aber ich hab ne Frage. Wenn ich das ganze über Interrupt laufen lassen will, so wie HansHans, muss ich dann in der ISR einfach das TWDR Register auslesen oder muss da noch etwas anderes passieren (TWSR zurücksetzen oder so)? Ich habe ein Programm geschrieben, das in der ISR einfach das TWDR Register ausliest. Allerdings erhalte ich dadurch nicht die gesendeten Werte, sondern jedes mal den Wert "64".

    Hoffe mir kann jemand helfen.

    MfG

  4. #44
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    22.05.2005
    Ort
    12°29´ O, 48°38´ N
    Beiträge
    2.731
    Normalerweise TWSR auslesen und anhand des Status drauf reagieren,
    so ähnlich wie in den Beispielen im Wiki,
    wenn ein Byte gekommen ist, dieses erst auslesen aus TWDR,
    zum Schluss, und damit es auch weitergeht, muss man zB. noch ein ACK oder NACK ausgeben, in dem man das entsprechende Flag in TWCR setzt, oder eben nicht,
    incl. das Flag TWINT, denn erst wenn TWINT gesetzt wird gehts wirklich weiter, auf dem I2C-Bus.

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

    da die Beispiele im Wiki wohl nicht immer so ganz optimal für Einsteiger zu überschauen sind, bzw. für den weiteren Ausbau etwas zu einfach gehalten sind, hab ich ein Beispiel zusammengebaut, in dem das RN-Mega8 I2C-Slave ist, und das RN-Control Mega32 der Master.
    Der Master ist per UART mit dem PC verbunden, über den man Daten eingeben kann, die dann zum I2C-Slave gesendet werden.
    Am RN-Mega8 habe ich 2 Servos hängen, die entsprechend den Werten die man am PC eingibt positioniert werden.

    I2C-Slave:
    Code:
    $regfile = "M8def.dat"                                 ' the used chip
    $crystal = 16000000                                    ' frequency used
    '$baud = 9600    ' brauchen wir nicht
    
    Waitms 100
    
    ' TWI init
    Gosub Twi_init_slave
    
    Config Servos = 2 , Servo1 = Portb.1 , Servo2 = Portb.2 , Reload = 8
    
    ' Ports für Servo auf Ausgang
    Config Portb.1 = Output
    Config Portb.2 = Output
    Config Portd = Output
    
    ' Musik, wegen Stimmung usw. :-)
    Sound Portb.0 , 300 , 450                              ' BEEP
    
    Servo(1) = 100
    Servo(2) = 100
    
    Const Maxanzahlbyte = 10                               ' Wenn mehr Zeichen kommen werden diese verworfen !
    Dim Messagebuf(maxanzahlbyte) As Byte
    Dim Anzahlbuf As Byte                                 ' Anzahl Zeichen die gesendet wurden
    
    Dim Neuemsg As Byte                                    ' zeigt an wenn eine neue Message gültig ist
    
    Dim Twi_control As Byte                                ' Controlregister lokale kopie
    Dim Twi_status As Byte
    Dim Twi_data As Byte
    
    Const Eigene_slave_adr = &H40                          ' Adresse evtl. Anpassen
    
    ' wegen der Servos, TWI braucht das hier nicht
    Enable Interrupts
    
    Twi_data = 0
    Neuemsg = 0                                            ' Paket ungültig
    Anzahlbuf = 0                                          ' Anzahl empfangener Bytes
    
    Portd = &HFF                                           ' alle LEDs aus
    
    'Print "M8 servo test"
    Do
    
        ' schauen ob TWINT gesetzt ist
        Twi_control = Twcr And &H80                        ' Bit7 von Controlregister
    
        If Twi_control = &H80 Then
            Twi_status = Twsr And &HF8                     ' Status
    
            Portd = Not Twi_status                         ' test auf die LEDs
    
            Select Case Twi_status
    
                ' Slave Adress received, wir sind gemeint !
                Case &H60 :
                    Twcr = &B11000100                      ' TWINT löschen, erzeugt ACK
                    Anzahlbuf = 0
                    Neuemsg = 0                            ' Flag für Message ungültig
    
                ' Byte mit ACK
                Case &H80 :
                    If Anzahlbuf < Maxanzahlbyte Then
                        Incr Anzahlbuf                     ' zähler +1
                        Messagebuf(anzahlbuf) = Twdr
                    End If
                    Twcr = &B11000100                      ' TWINT löschen, erzeugt ACK
    
                ' Stop oder restart empfangen
                Case &HA0 :
                    Twcr = &B11000100                      ' TWINT löschen, erzeugt ACK
                    ' es müssen 3 Byte sein, damit das Paket OK ist
                    If Anzahlbuf = 3 Then
                        Neuemsg = 1                        ' Flag für Message gültig
                    Else
                        Neuemsg = 0                        ' Flag für Message ungültig
                    End If
    
                ' letztes Byte mit NACK, brauchen wir nicht
                Case &H88 :
                Case &HF8 :
                ' Fehler, dann reset TWI
                Case &H00 :
                    Twcr = &B11010100                      ' TWINT löschen, reset TWI
    
                ' was anderes empfangen, sollte nicht vorkommen
                Case Else :
                    Twcr = &B11000100                      ' TWINT löschen, erzeugt ACK
    
            End Select
    
        End If
    
        ' ein gültiges Paket angekommen
        If Neuemsg = 1 Then
            Neuemsg = 0                                    ' Flag wieder löschen
            ' nur wenn das erste Zeichen ein "S" ist tun wir was damit !
            If Messagebuf(1) = "S" Then
                Servo(messagebuf(2)) = Messagebuf(3)
                Sound Portb.0 , 300 , 450                  ' Roger-BEEP
            End If
        End If
    
        Waitms 10
    
    Loop
    
    End
    
    ' TWI als slave aktivieren
    Twi_init_slave:
        Twsr = 0                                                ' status und Prescaler auf 0
        Twdr = &HFF                                             ' default
        Twar = Eigene_slave_adr                                 ' Slaveadresse setzen
        Twcr = &B01000100                                       ' TWI aktivieren, ACK einschalten
    Return
    Angepasst werden kann die Slaveadresse mit Eigene_slave_adr,
    und die max. Grösse des Paketes bei Maxanzahlbyte.

    I2C-Master:
    Code:
    $regfile = "M32def.dat"                                ' the used chip
    $crystal = 16000000                                    ' frequency used
    $baud = 9600
    
    $lib "i2c_twi.lbx"                                     ' Für Hardware TWI
    
    Waitms 100
    
    Config Twi = 400000                                   ' setzt die TWI-Register
    ' Twsr = 0                                               ' Status reset
    ' Twbr = 12                                              ' Bus Geschwindigkeit 400kHz @ 16MHz
    TWCR = &B00000100                                      ' TWI Modul aktivieren, nur TWEN
    
    Dim Nr As Byte                                         ' Servo-Nr
    Dim Position As Byte                                   ' Position
    
    Const Servom8w = &H40                                  ' Slaveadresse
    Const Servom8r = &H41
    
    Sound Portd.7 , 300 , 450                              ' BEEP
    
    ' Startausgabe
    Print
    Print "TWI Master Servo einstellen"
    
    Print "Nr. und Wert fuer Servo eingeben :"
    
    Do
    
        Print "Nr : " ;
        Input Nr
        Print "Position : " ;
        Input Position
    
        ' Es gibt nur 2 Servos mit Nr 1 und 2
        If Nr > 0 And Nr < 3 Then
    
            I2cstart
            I2cwbyte Servom8w
            I2cwbyte &H53                                  ' "S" Kennzeichen für Servo ansteuern
            I2cwbyte Nr
            I2cwbyte Position
            I2cstop
    
            ' Fehler-Flag ausgeben, sollte immer 0 sein, dann war kein Fehler
            Print "Err " ; Err
        End If
    
    Loop
    
    End
    Angepasst werden muss nur die Slaveadresse bei Servom8w.
    Da vom Slave nichts gelesen werden kann braucht man die Lese-Adresse eigentlich nicht.
    Evtl. kann man die Busgeschwindigkeit bei TWBR ändern, falls andere Quarz- oder Busfrequenzen gewünscht sind. Verwendet man Config TWI = .. rechnet das Bascom für einen aus, Anhand der Angabe bei $crystal.

    Das Telegramm-Paket, dass der Master zum Slave sendet ist so aufgebaut:
    1. Zeichen: ein "S" (grosses S) als Kennzeichen das ein Servo angesteuert werden soll, alle anderen werden verworfen,
    2. Zeichen: die Servo-Nr
    3. Zeichen: die Position des Servos, theoretisch von 0 bis 255, aber je nach Servo meistens im Bereich von 50 bis 200 !

    Die Funktion des Slave nochmal als Text:
    In der Do..Loop-Schleife wird immer das Flag TWINT geprüft, das anzeigt, dass Daten über TWI angekommen sind, anschließend wir der Status aus TWSR ausgelesen, und per Select..Case entsprechend verzweigt, da wir hier nur einen Slave-Receiver haben, braucht man nur die hier angegebenen Statuscodes verwenden.
    Wird nach einer Start-Sequenz die eigene Slaveadresse angesprochen wird der Zähler für die Anzahl der empfangenen Zeichen auf 0 zurückgesetzt.
    Es wird grundsätzlich jedes Byte mit ACK quittiert egal ob der Puffer schon voll ist oder nicht, ist der Puffer voll werden die nachfolgenden Bytes verworfen !
    Wird ein STOP oder RESTART empfangen, wird ein weiteres Flag gesetzt (Neuemsg) falls die Paketgrösse passt, ansonsten ist das Pakte ungültig und wird verworfen. Will man unterschiedliche Paketgrössen empfangen, muss man diese Abfrage natürlich hier rausnehmen, und kann sich zB. nur an das 1. Zeichen im Paket halten was zu tun ist.
    Ist das Flag Neuemsg auf 1, wird in der nächsten If-Abfrage die Auswertung des empfangenen Pakets gestartet, und das Flag wieder zurückgesetzt.
    Beginnt das Paket mit einem "S" ist es für uns interessant, und wir stellen den entsprechenden Servo (aus Byte 2) auf den neuen Wert (aus Byte 3).
    Jetzt ist die Schleife beendet, und es beginnt alles wieder von vorne, solange das Flag TWINT nicht gesetzt ist, muss sich der AVR nur um die PWM-Ausgabe für die Servos kümmern, das geschieht per ISR, und deshalb können wir hier die Do..Loop-Schleife endlos laufen lassen.

  6. #46
    Neuer Benutzer
    Registriert seit
    28.02.2010
    Ort
    Tokyo
    Beiträge
    3
    Hallo Leute!

    Erstmal muss ich sagen, dass ich hier viel über die TWI und auch allgemein über µC gelernt habe. Danke
    Auch tut es mir Leid, dass ich ein 3 Jahre altes Thema wieder hervor nehme und eine Frage darüber stelle.

    Schon seit 2 Tagen versuche ich es fertig zu bringen, dass mein atmega88 als Slave 2 oder mehrere Byte an meinem atmega32 Master über TWI zu versenden. Ein Byte konnte ich bisher erfolgreich, dank rn-wissen.de und dieses Thema, machen.

    Ich bin wirklich verzweifelt, da wirklich viel darüber gelesen habe aber leider nichts darüber gefunden habe und ich nicht weiss ich das realisieren kann. (bin noch ein Anfänger)

    Ich hoffe, dass ihr mir hier kurz einen Tipp, oder eine Anleitung dazu geben könnt, wie ich den Slave, evtl auch den Master programmieren muss, damit mehrere Bytes vom Slave versendet, bzw vom Master empfangen werden können.

    Für eure Unterstützung bedanke ich mich bei euch.

    Gruss
    shurikn

  7. #47
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    09.05.2007
    Beiträge
    202
    Hallo,

    ich verwende auch das Grundprogramm aus den RN-Wissen.
    Im Slave mache ich das so:

    Code:
                'Master will Byte haben
                Case &HA8:
                     Twdr = Vers
                     Twcr = &B11000100
                     I = 0
                'Master will weiteres Byte haben
                Case &HB8:
                     Select Case I
                         Case 0
                            Twdr = Portstate
                         Case 1
                            Twdr = Proz
                     End Select
                     Incr I
                     Twcr = &B11000100
    Im Master:
    Code:
    Dim Buf(3) As Byte
    buf(1) = 0
    
    I2creceive Slaveadr , Buf(1) , 1 , 3
    Im Array Buf stehen danach meine Werte von Vers, Portstate und Proz aus dem Slave. Das "Select Case I" kannst du natürlich noch erweitern, je nach dem, wieviel Bytes du übertragen willst. Das Array buf müsste dann von der Länge her noch entsprechend angepasst werden und auch der letzte Parameter bei I2Creceive (Anzahl der zu empfangenden Bytes).
    Gruß, Stefan

  8. #48
    Neuer Benutzer
    Registriert seit
    28.02.2010
    Ort
    Tokyo
    Beiträge
    3
    Hallo StevieL

    Danke für deinen Tipp! Ich werde morgen mal versuchen, dein Code zu verstehen und abzukupfern.

    So, dann gehe ich mal ins Bett

    Freundliche Grüsse aus Japan
    Shurikn

  9. #49
    Neuer Benutzer
    Registriert seit
    28.02.2010
    Ort
    Tokyo
    Beiträge
    3
    Hallo StevieL!

    Das hat wunderbar geklappt, danke. Was bei mir jedoch nicht funktionierte ist, dass wenn ich Twcr = &B11000100 im Case habe (so wie bei deinem Code). Als ich den Twcr=&B11000100 heraus nahm und nach dem end select gesetzt habe funktioniert alles bestens.

    Nochmals danke viel mals für deinen wertvollen Tipp.

    Gruss
    Shurikn

Seite 5 von 5 ErsteErste ... 345

Berechtigungen

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

12V Akku bauen