PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : TWI stoppt ATMega8



Jaecko
23.03.2007, 07:02
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:


$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


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

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

'================================================= ==============================
'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

linux_80
23.03.2007, 18:24
Hallo,

wenn Du die Datei am Anfang includest, kommt der Text der eingefügten Datei auch dort hin beim Compilieren, und das geht nicht gut, mach das Include mal ans Ende, dann sollte es besser laufen.