Moin.

Nachdem ich ja gerade mehr oder weniger erfolgreich versuche, eine Kommunikation zwischen AVRs mittels TWI herzustellen gibts schon wieder das nächste Problem.

Ein ATMega8 soll einen Jog/Shuttle-Regler auslesen, die Position über einen 4511 auf einem 7-Segment-LED-Display ausgeben. Zusätzlich können über 3 Taster (u. 3 Status-LEDS) 3 verschiedene Kanäle gewählt werden. Somit kann die Einheit dann z.B. zum steuern von 3 Lampen oder zum Positionieren des Werkzeugs einer CNC-Maschine verwendet werden.

Sobald ich jedoch nur die Zeile $Inlcude "twicomm.bas" einfüge, steht der
AVR bzw. startet erst garnicht. Es blinkt nichts, das 7-Segment-Display zeigt nicht "0" an (meistens eine "Überblendung" zwischen "3" und "5"). Und beim Drehen passiert garnichts.

Geplant war dann, dass das Teil eine Bewegung über den TWI/I²C ans RNKeyLCD sendet und mir da eben im Display die Daten anzeigt.

Findet da evtl jemand den Fehler?


Hier die Codes

Jog/Shuttle-Software:
Code:
$regfile = "m8def.dat"
$crystal = 8000000
$hwstack = 64                                               ' default use 32 for the hardware stack
$swstack = 10                                               'default use 10 for the SW stack
$framesize = 40
'$include "twicomm.bas"
'$baud = 9600

'Outputs
   Config Pind.6 = Output : Vorzeichen Alias Portd.6
   Config Pinb.6 = Output : Bcdbit1 Alias Portb.6
   Config Pinb.7 = Output : Bcdbit2 Alias Portb.7
   Config Pind.5 = Output : Bcdbit3 Alias Portd.5
   Config Pinc.1 = Output : Ledrot Alias Portc.1
   Config Pinc.2 = Output : Ledblau Alias Portc.2
   Config Pinc.3 = Output : Ledgruen Alias Portc.3


'Inputs (Bezeichnungen = Kabelfarben)
   Config Portb.2 = Input : Rosa Alias Pinb.2
   Config Portb.3 = Input : Schwarz Alias Pinb.3
   Config Portb.4 = Input : Rot Alias Pinb.4
   Config Portb.5 = Input : Grau Alias Pinb.5
   Config Portb.1 = Input : Gelb Alias Pinb.1
   Config Portb.0 = Input : Braun Alias Pinb.0

'ADC
   Config Adc = Single , Prescaler = Auto
   Start Adc

'Variablen
   Dim Vz As Bit
   Dim Adcval0 As Word
   Dim Ch As Byte
   Dim Jsvalue As Byte
   Dim Twislaveadresse As Byte
   Dim Twidaten As Byte

Enable Interrupts
Config Timer1 = Timer , Prescale = 256
On Timer1 Isrtimer1
Timer1 = 34286
Enable Timer1


   Bcdbit1 = 0
   Bcdbit2 = 0
   Bcdbit3 = 0

   Twislaveadresse = &H40
	Twidaten = 50 'Nur Test
	Ledrot = 1
	Ledgruen = 1
	Wait 1

'Call Twi_send_byte(twislaveadresse , Twidaten)

Ledrot = 1 : Ch = 1

Do

Adcval = 0
Adcval0 = Getadc(0)
If Adcval0 > 100 Then
   Waitms 125
   Select Case Adcval0
      Case 250 To 400
         Ledgruen = 1
         Ledblau = 0
         Ledrot = 0
         Ch = 3
      Case 560 To 750
         Ledgruen = 0
         Ledblau = 1
         Ledrot = 0
         Ch = 2
      Case Is > 900
         Ledgruen = 0
         Ledblau = 0
         Ledrot = 1
         Ch = 1
      End Select
   End If

   If Rosa = 0 And Schwarz = 0 And Rot = 0 And Grau = 1 Then
      Bcdbit1 = 1
      Bcdbit2 = 1
      Bcdbit3 = 1
      Jsvalue = 7
      Vz = 0
      End If
'   [weitere If-Blöcke zur Zuweisung der Radstellung enstprechend
'    der Eingänge an den Kabeln]
 
   Loop

   End

   Isrtimer1:
   Timer1 = 34286
   Toggle Ledgruen
   Return
TWI-Modul
Code:
'===============================================================================

'===============================================================================

'===============================================================================
'Deklarationsteil
'===============================================================================
'===============================================================================
'I2C/TWI-Bus Pins
'===============================================================================
   Config Sda = Portc.4
   Config Scl = Portc.5

'===============================================================================
'I2C/TWI-Bus Slave Adresse
'===============================================================================
   Const MySlaveAdd = &H44

'===============================================================================
'Functions deklarieren
'===============================================================================
   Declare Function TWI_Read_Byte(byval Slave as Byte) as Byte

'===============================================================================
'Subs deklarieren
'===============================================================================
   Declare Sub TWI_Init_Slave
   Declare Sub TWI_Send_Byte(byval Slave as Byte , TWIZeichen as Byte)
   Declare Sub TWI_Start_Transceiver()

'===============================================================================
'Variablen
'===============================================================================
   DIM TWI_Control as Byte       'Kontrollregister, Lokale Kopie
   DIM TWI_Status as Byte
   DIM TWI_Data as Byte
   DIM TWI_Error as Byte       'Fehlermerker
   DIM TWI_Errorstate as Byte       'Eigener Fehlerstatus
   DIM TWI_MessageBuffer(4) as Byte       'Array für Datenübertragung
   DIM TWI_AnzahlBuffer as Byte       'Anzahl zu sendender Zeichen
   DIM TWI_Count as Byte       'Zähler
   DIM TWI_RW as Bit       'Read/Write-Flag
   DIM TWI_NewByte as byte       'Byte-Merker


'===============================================================================
'TWI Initialisieren
'===============================================================================
   TWCR = &B00000100       'TWI aktivieren
   TWSR = 0       'Status/Prescaler-Register
   TWBR = 72       'Bitratenregister


       'Aufruf TWI-Daten senden: CALL TWI_Send_Byte(Slave-Adresse, Byte)
       'Aufruf Byte vom Slave holen: Daten = TWI_Read_Byte(Slave-Adresse)


'===============================================================================
'Functions
'===============================================================================
Function TWI_Read_Byte(Slave As Byte) As Byte
   'MASTER: Holt Byte vom Slave, schliesst Übertragung ab
   TWI_Error = 0       'Fehler Reset
   TWI_Read_Byte = 0       'Wert "leeren"
   TWCR = &B10100100       'TWINT, Startbedingung
   Gosub TWI_Wait_INT       'Warten bis TWINT gesetzt
   'Wenn Zugriff auf Bus erlaubt, Slaveadresse senden:
   If TWI_Status = &H08 OR TWI_Status = &H10 Then
      TWDR = Slave OR &H01       ' Slave Adresse + Read
      TWCR = &B10000100       'TWINT löschen, Byte senden
      Gosub TWI_Wait_INT       'Warten bis TWINT gesetzt
      'Antwort von Slave:
      If TWI_Status = &H40 Then
         TWCR = &B10000100       'TWINT löschen, Byte senden
            'KEIN ACK, DA NUR 1 BYTE GELESEN WIRD!
         Gosub TWI_Wait_INT       'Warten bis TWINT gesetzt
         'Byte empfangen:
         If TWI_STatus = &H58 OR TWI_Status = &H50 Then
            TWI_Read_Byte = TWDR       'Daten auslesen
            TWI_Error = 0
         Else
            TWI_Error = TWI_Status
         EndIF
      Else       'Kein Slave
         TWI_Error = TWI_Status
      EndIF
      'Stop-Bedingung
      TWCR = &B10010100       'TWINT löschen, STOP senden
   Else       'Bus belegt;freigeben
      TWCR = &B10000100       'TWINT löschen, Bus freigeben
      TWI_Error = TWI_Status
   EndIf
End Function

'===============================================================================
'Subs
'===============================================================================
Sub TWI_INIT_SLAVE
   TWSR = 0       'Status + Prescaler auf 0
   TWDR = &HFF       'Default
   TWAR = MySlaveAdd       'Slaveadresse setzen
   TWCR = &B01000100       'TWI aktivieren, ACK einschalten
End Sub

Sub TWI_Send_Byte(byval Slave as Byte , TWIZeichen as Byte)
   'MASTER: Sendet Byte an Slave und schliesst Übertragung ab
   TWI_Error = 0       'Fehler Reset
   TWCR = &B10100100       'TWINT, Startbedingung
   Gosub TWI_Wait_INT       'Warten bis TWINT gesetzt
   'Wenn Zugriff auf Bus erlaubt, Slaveadresse senden:
   If TWI_Status = &H08 OR TWI_Status = &H10 Then
      TWDR = Slave AND &HFE       ' Slave Adresse + Write
      TWCR = &B10000100       'TWINT löschen, Byte senden
      Gosub TWI_Wait_INT       'Warten bis TWINT gesetzt
      'Antwort von Slave:
      If TWI_Status = &H18 OR TWI_Status = &H20 Then
         TWDR = TWIZeichen       'Nutzdaten
         TWCR = &B10000100       'TWINT löschen, Byte senden
         Gosub TWI_Wait_INT       'Warten bis TWINT gesetzt
         'Zeichen gesendet:
         If TWI_Status = &H28 OR TWI_Status = &H30 Then
            TWI_Error = 0
         Else
            TWI_Error = TWI_Status
         EndIF
      Else       'Kein Slave
         TWI_Error = TWI_Status
      EndIf
      'Stop-Bedingung
      TWCR = &B10010100       'TWINT löschen, STOP senden
   Else       'Bus belegt; freigeben
      TWCR = &B10000100       'TWINT löschen, Bus freigeben
      TWI_Error = TWI_Status
   EndIf
End Sub

Sub TWI_Start_Transceiver()
   TWI_Errorstate = 0
   TWCR = &B10100100       'TWINT, Startbedingung
   Gosub TWI_Wait_INT       'Warten bis TWINT gesetzt
   'Wenn Zugriff auf Bus erlaubt, Slaveadresse senden:
   If TWI_Status = &H08 OR TWI_Status = &H10 Then
      TWI_RW = TWI_MessageBuffer(1).0       'RW-Flag für Abfrage holen
         For TWI_Count = 1 TO TWI_AnzahlBuffer
            'Slave-Adresse immer WRITE, ansonten RW prüfen
            If TWI_Count = 1 OR TWI_RW = 0 Then
               'Slave-Adresse ausgeben
               TWDR = TWI_Messagebuffer(TWI_Count)
               TWCR = &B10000100       'TWINT löschen, Byte senden
               Gosub TWI_Wait_INT       'Warten bis TWINT gesetzt
               'Beim ersten Byte anderer Status erwartet
               If TWI_Count = 1 Then
                  'Slave hat sich gemeldet
                  If TWI_Status = &H18 OR TWI_Status = &H40 Then
                     TWI_Errorstate = 0
                  Else       'Kein Slave
                     TWI_Errorstate = TWI_Status
                     Exit For
                  EndIf
               Else
                  'Zeichen wurde gesendet
                  If TWI_Status = &H28 Then
                     TWI_Errorstate = 0
                  Else
                     TWI_Errorstate = TWI_Status
                  EndIf
               EndIf
            Else       'Byte lesen; Wenn letztes Byte gesendet: NACK senden für Ende
               If TWI_Count = TWI_Anzahlbuffer Then
                  'NACK laden für Ende der Übertragung
                  TWCR = &B10000100       'TWINT löschen,Byte senden
               Else
                  'ACK Den, TEWA = 1
                  TWCR = &B11000100       'TWINT löschen, Byte senden
               EndIf
               Gosub TWI_Wait_INT       'Warten bis TWINT gesetzt

               'Byte wurde empfangen:
               TWI_Messagebuffer(TWI_Count) = TWDR       'Daten auslesen

               'Byte Empfangen und mit ACK quittieren, sonst Ende
               If TWI_Status = &H50 Then
                  TWI_Errorstate = 0
               Else
                  'beim letzten Byte auch NACK
                  If TWI_Count = TWI_Anzahlbuffer AND TWI_Status = &H58 Then
                     TWI_Errorstate = 0
                  Else
                     TWI_Errorstate = TWI_Status
                     Exit For
                  EndIf
               EndIf
            EndIf
      Next TWI_Count
   Else
      'Bus belegt; freigeben
      TWCR = &B10000100       'TWINT löschen, Bus freigeben
      TWI_Errorstate = TWI_Status
   EndIf
End Sub



'===============================================================================
'Unterprogramme (Gosub)
'===============================================================================

TWI_Stop:
   'Stopsequenz
   TWCR = &B10010100       'TWINT löschen, Stop senden
   'warten bis Stop-Flag gelöscht wird, danach Stop abgeschlossen.
   DO
      TWI_Control = TWCR AND &H10
   LOOP Until TWI_Control = 0
   TWI_STatus = TWSR
   TWI_Status = TWI_Status AND &HF8
   Return

TWI_Wait_INT:
   Do
      TWI_Control = TWCR AND &H80
   Loop until TWI_Control = &H80
   TWI_Status = TWSR AND &HF8
   Return