ACsenf
07.02.2006, 11:26
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.
'************************************************* ******************************
'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
'------------------------------------------------------------------
' 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
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.
'************************************************* ******************************
'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 "RS232 Schnittstelle an Hardware UART"
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
'------------------------------------------------------------------
' 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