PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : LPT-Master <=> SPI <=> AVR-Slave



BlueNature
17.04.2006, 15:41
Servus, ich habe hier seit Tagen keine Erfolge mit der SPI-Anbindung eines AVR-Slaves am LPT eines PC's (Master). Die Datenübertragung ist mehr als mieserabel egal weche Frequenz ich auch Betreibe (selbst bei 1 sek. pro Bit und LED als Kontrolle). Der LPT bringt 4,4V bei High und war schlecht in den Flanken, daraufhin habe ich eben für SCK und MOSI je zwei Inverter genommen, Flanken sind jetzt OK und mit dem Oszi sauber.

Der momentane AVR-Slave-Code:




' SPI-Slave-Routine für SPI-Hub
' =============================

$RegFile = "m8def.dat"
$Crystal = 7372000
$Baud = 115200

On SPI SPI_Interrupt NoSave

LEDError Alias PortD.7

Dim TempSpi As Byte
Dim SpiDataRec As Byte

DDRD.7 = 1 ' LED auf Out
PortD.7 = 0 ' LED aus

Init:
DDRB.4 = 1 ' MISO auf Ausgang
PortB.4 = 0 ' MISO auf High
GoSub SPI_Init ' SPI-Initialisierung
Set SREG.7

Main:
Do
LEDError = SpiDataRec.0
Loop

SPI_Init:
SPCR = &B11000000 ' SPI-Slave einstellen
ReSet SPSR.SPI2X ' Double Speed aus
SPIDataRec = 0
Return

SPI_Interrupt:
'TempSpi = SREG
If SPSR.7 = 0 Then GoTo SPI_Interrupt
SpiDataRec = SPDR
SPDR = 0
'LEDError = SPSR.WCOL ' Write-Collision?
'Print SpiDataRec; " ";
'SREG = TempSpi
Return



Der momentane PC-Code:



Private Declare Function Inp Lib "inpout32.dll" Alias "Inp32" ( _
ByVal PortAdress As Integer) As Integer

Public Declare Sub Out Lib "inpout32.dll" Alias "Out32" ( _
ByVal PortAdress As Integer, ByVal Value As Integer)

Private Sub CmdTransmit_Click()
Dim SendByte As Byte
Dim ReciveByte As Byte
Dim TempByte As Byte
Dim i As Byte

TxtTest.Text = ""
' Sendebyte laden
SendByte = Val(TxtSend.Text)
For i = 0 To 7
' Datenbit auf Bus legen
HubMosi = (SendByte And &H80) <> 0
Call SchreibeDatenByte
With TxtTest
If HubMosi Then .Text = .Text & "1" Else .Text = .Text & "0"
End With
' Clock-Puls senden
HubSck = Not HubSck
Call SchreibeDatenByte
HubSck = Not HubSck
Call SchreibeDatenByte
' Byte links schieben
SendByte = (SendByte And &H7F) * 2
Next i
End Sub

Public Sub SchreibeDatenByte()
Dim Ausgabe As Byte

Ausgabe = 0
If HubSck Then Ausgabe = Ausgabe + 1
If HubReset Then Ausgabe = Ausgabe + 2
If HubMosi Then Ausgabe = Ausgabe + 128
Out Basisadresse, CInt(Ausgabe)
Debug.Print Ausgabe
End Sub


Jetzt müßte der LPT ein SPI-Protokoll senden auf Mode 0, laut Oszi ist das auch der Fall in jeder Geschwindigkeit. Das Problem ist es kommt eben immer das Anfangsbyte verschoben an im AVR-Slave. Aus einer 1 wird meinetwegen mal eine 128, dann eine 64, auch mal eine 32 und so weiter, also eben willkürlich verschoben.

Hat jemand eine Idee woran das liegen kann?

Grüße Wolfgang

BlueNature
17.04.2006, 16:31
Nachtrag:

Habe eben noch versucht ein Foto zu machen am Oszi mit Verschlusszeit 1 Sek. damit man das Signal auch sieht das am AVR ankommt vom PC (also nach dem Schmitt-Trigger)

BlueNature
17.04.2006, 20:38
Nochmal Nachtrag:

Problem mit dem SPI-Slave habe ich zuerst nochmal mit dem BASCOM-eigenen Config SPI=Hard und Config SPI=Soft programmiert. Dabei hat es wunderbar funktioniert.

Dann eben noch den Code der Version mit Config SPI=Hard wieder Befehl für Befehl auf Registerzugriffe zurückreduziert. Es gieng auch in jedem Stadium. Zum Schluß blieb im Grunde mein AVR-Slave-Code übrig der seltsamerweise läuft! Der Code ist nun soweit identisch und ich steh echt auf dem Schlauch was da anders sein soll. Die Warteschleife auf SPSR.7 = 0 ist irrelevant, ohne giengs ja auch nicht, das hatte ich nur aus letzten Versuchen noch drin.

Code jetzt:



' SPI-Slave-Routine für SPI-Hub
' =============================

$RegFile = "m8def.dat"
$Crystal = 7372000
$Baud = 115200

On SPI SPI_Interrupt

LEDError Alias PortD.7

Dim TempSpi As Byte
Dim SpiDataRec As Byte
Dim Richtung As Byte

DDRD.7 = 1 ' LED auf Out

Init:
GoSub SPI_Init
Enable Interrupts

Main:
Do
LEDError = SpiDataRec.0
Loop

SPI_Init:
DDRB.3 = 0 ' MOSI input
DDRB.4 = 1 ' MISO output
DDRB.5 = 0 ' SCK input
SPCR = &B11000000 ' SPI-Slave einstellen
ReSet SPSR.SPI2X ' Double Speed aus
SPIDataRec = 0
Return

SPI_Interrupt:
SpiDataRec = SPDR
SPDR = 0
Return


Grüße (sprachloser) Wolfgang

P.S.: Und Strom hat doch ne Duftnote!!!