Hallo zusammen!

Hatte ja letzte Woche mit dem SPI bus gekämpft und hier auch nicht viel Hilfreiches finden können. Habe mit den Bsp. aus Bascom was brauchbares zusammenbekommen, hoffe das Hilft dem Ein oder Anderen.

Code:
'*******************************************************************************
'Prozessor: Atmel Mega 32
'Programm: SPI BUS MASTER mit RS232
'          RS232 Eingabe über Terminal Senden der Werte an SPI-Slave
'*******************************************************************************
'$sim
$regfile = "M16DEF.DAT"
$crystal = 8000000
$baud = 9600

Config Spi = Hard , Data Order = Msb , Master = Yes , Polarity = Low , Phase = 0 , Clockrate = 128 , Noss = 1

Spiinit

'-----------------------------Variablendeklaration--------------------------------

Const Esc = 27
Dim Cv As Integer
Dim Bytes(2) As Byte At Cv Overlay
Dim I As Byte
Dim A As Integer
Dim X As Byte
Dim Y As Byte


Declare Sub Aus
Declare Sub Senden
Declare Sub Empfangen
'-----------------------------Portkonfiguration-----------------------------------

'Der PortC wird als Ausgang programmiert
Config Pinc.0 = Input
Config Pinc.1 = Output
Config Pinc.2 = Output
Config Pinc.3 = Output
Config Pinc.4 = Output
Config Pinc.5 = Output
Config Pinc.6 = Output
Config Pinc.7 = Output
Config Pina.7 = Output
Config Pina.6 = Output
Config Pina.5 = Output
Config Pina.4 = Output
Config Pina.3 = Output
Config Pina.2 = Output
Config Pina.1 = Output
Config Pina.0 = Output

'Der Port B und D wird als Eingang programmiert
Config Pinb.0 = Output
Config Pinb.1 = Output
Config Pinb.2 = Output                                      ' Interrupt 2
Config Pinb.3 = Output
'Config Pinb.4 = Output
Config Pinb.5 = Output
Config Pinb.6 = Output
Config Pinb.7 = Output
Config Pind.2 = Output                                      ' Interrupt 0
Config Pind.3 = Output                                      'Interrupt 1
Config Pind.4 = Output
Config Pind.5 = Output
Config Pind.6 = Output
Config Pind.7 = Output

'Hier geben wir der Definition einen schoeneren Namen
D7 Alias Porta.0
D9 Alias Porta.1
D10 Alias Porta.2
D11 Alias Porta.3

Y = 0
Cv = 0
Portd.6 = 0                                                 'CS nicht aktiv

Call Aus
'------------------------------Programm-Hauptschleife-----------------------------

Do

Anfang:

Toggle D7
         Waitms 250
Toggle D9
         Waitms 250
Toggle D10
         Waitms 250
Toggle D11
         Waitms 250


If Ischarwaiting() <> 0 Then
   X = Inkey()
   Print
   Print "RS232 Schnittstelle an Hardware UART"
   Print

Anfang1:

   Input "Wert oder zu sendende Zahl:" , Cv
   Print "gewaehlte Zahl=" ; Cv

Ausgabe:

   Print "OK?        RETURN"
   Print "Abbrechen? ESC"
   X = Waitkey()                                            'wait for character

   If X = 27 Then
      Goto Anfang
   End If

   If X = 13 Then
      Call Senden
   End If

End If


Loop

                                                    'end program

'-----------------------------------------------------------------------------------



'----------------------------Funktion Ausschalten---------------------------------

Sub Aus

Porta = &HFF                                                ' alle LEDs aus
Portb = &HFF                                                ' alle LEDs aus
Portc = &HFF                                                ' alle LEDs aus
Portd = &HFF                                                ' alle LEDs aus

End Sub


Sub Senden
   Portd.6 = 0                                              'CS aktiv
   For I = 1 To 2
      Waitms 1
      'Y = Spimove(cv)
      Spiout Bytes(i) , 1
      Print "Byte(" ; I ; ")=" ; Bytes(i)
   Next I
      Print "Sequenz wurde gesendet"
      Portd.6 = 1                                           'CS ausgeschaltet
End Sub


Sub Empfangen
   nop

End Sub


End

Code:
'------------------------------------------------------------------
'                           SPI-SLAVE.BAS
'
' sample shows how to create a SPI SLAVE
' use together with SPI BUS Master.bas
'------------------------------------------------------------------
' Tested on the STK500. The STK200 will NOT work.
' Use the STK500 or another circuit
$regfile = "m32def.dat"
$crystal = 8000000

Config Lcdpin = Pin , Db4 = Porta.4 , Db5 = Porta.5 , Db6 = Porta.6 , Db7 = Porta.7 , E = Portd.7 , Rs = Portd.6

'******************************************************************************
Config Lcd = 16 * 2                                         'configure lcd screen

Dim B As Byte , Rbit As Bit
Dim Bsend As Byte
Dim Index As Byte , X As Byte
Dim Bytes(2) As Byte
Dim Outp As Word At Bytes Overlay
Dim Spg As Word

'Der PortC wird als Ausgang programmiert
Config Pinc.0 = Output
Config Pinc.1 = Output
Config Pinc.2 = Output
Config Pinc.3 = Output
Config Pinc.4 = Output
Config Pinc.5 = Output
Config Pinc.6 = Output
Config Pinc.7 = Output



'First configure the MISO pin
Config Pinb.6 = Output                                      ' MISO

'Then configure the SPI hardware SPCR register
Config Spi = Hard , Interrupt = On , Data Order = Msb , Master = No , Polarity = Low , Phase = 0 , Clockrate = 128

'Then init the SPI pins directly after the CONFIG SPI statement.
Spiinit


'specify the SPI interrupt
On Spi Spi_isr Nosave

'enable global interrupts
Enable Interrupts

Portc = &HFF
Index = 1
X = 0
Bsend = 0
Spg = 0

Cls

'show that we started
Lcd "start SPI SLAVE"
Wait 2
Cursor Off
Spdr = 0                                                    ' start with sending 0 the first time
Do
  Upperline
  Waitms 1
  Lcd "Auswahl: 1000 Uc "
  Lowerline
  Waitms 1
  Lcd "Auswahl: 2000 Test"

  If Rbit = 1 Then

     If Outp = 1000 Then
         Upperline
         Waitms 1
         Lcd "Eingabe Uc        "
         Lowerline
         Waitms 1
         Lcd "Uc= ?             "
         Reset Rbit
         Outp = 0
         Spg = 0
         Spdr = 0

          Do
            If Rbit = 1 Then
               Waitms 10
               Spg = Outp
               Upperline
               Waitms 1
               Lcd " Uc= " ; Spg ; " V     "
               Lowerline
               Waitms 1
               Lcd " Saved          "
               Reset Rbit
               X = 1
            End If
            Toggle Portc.1
            Waitms 30
          Loop Until X = 1

         Wait 5
         X = 0
         Portc.1 = 1

      End If

      If Outp = 2000 Then
         Upperline
         Waitms 1
         Lcd "Eingabe Test        "
         Lowerline
         Waitms 1
         Lcd "1=ON , 2=OFF           "
         Reset Rbit
         Outp = 0
         Spg = 0
         Spdr = 0

          Do
            If Rbit = 1 Then
               Waitms 10
               Spg = Outp
               Upperline
               Waitms 1
               Lcd "Testbetrieb " ; Spg ; "   "
               Lowerline
               Waitms 1
               Lcd " Saved!        "
               Reset Rbit
               X = 1
            End If
            Toggle Portc.1
            Waitms 30
          Loop Until X = 1

         Wait 5
         X = 0
         Portc.1 = 1
      End If
  End If
  ' your code goes here
  Toggle Portc.7
  Waitms 100
Loop



'Interrupt routine
'since we used NOSAVE, we must save and restore the registers ourself
'when this ISR is called it will send the content from SPDR to the master
'the first time this is 0
Spi_isr:
  push r24    ; save used register
  in r24,sreg ; save sreg
  push r24
  B = Spdr
  Set Rbit
  If Index = 1 Then
      Bytes(index) = B
      Incr Index
  Elseif Index = 2 Then
      Bytes(index) = B
      Index = 1
  End If
  pop r24
  !out sreg,r24 ; restore sreg
  pop r24        ; and the used register
Return                                                      ' this will generate a reti

Funktioniert wunderbar! Allerdings kommt es sehr sehr selten vor, aber es kommt vor! Daß manchmal der nach der Auswahl gesendete Wert, der dann mal ins Eeprom soll nicht richtig ankommt, sondern nur das 1. gesendete Byte auf dem Display erscheint.
Hat jemand eine Ahnung woran das liegen kann? Wie gesagt passiert sehr sehr selten, beim erneuten Senden ist dann das Ergebnis korrekt.

Andere Frage, wie bringe ich den Slave dazu mir entsprechend seine Daten zu senden? Also ich will die Werte die im Eeprom eines anderen µC stehen auslesen. Stehe da momentan etwas auf dem Schlauch...
Aber fürs erste reicht die Übertragung alles andere ist Kosmetik.

Gruß

Sven