PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : SPI Bus Beispiel und Frage dazu



ACsenf
07.02.2006, 10: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

ACsenf
08.02.2006, 07:26
Hat hier niemand Erfahrungen?

Gruß

Sven

Kunki
22.06.2006, 15:09
Hallo,

ich habe eine merkwürdiges Problem. Mein programm schickt mehrere Bytes über den SPI- Bus zu einem Funkmodul. Jedoch sendet Bascom das zweite Byte nie richtig aus. Anstatt der 8 kommt immer nur eine 0. Alle
anderen Bytewerte stimmen (würde auf dem Oszi geprüft).
Der Teil meines Codes:

A(1) = &H66
Spiout A(1) , 1
Waitus 20

A(1) = &H08
Spiout A(1) , 1 ------------ dieses Byte wird nie richtig gesendet
Waitus 20

A(1) = &H00
Spiout A(1) , 1
Waitus 20

Der MCU ist dabei Master und springt nie in den Slavebetrieb. Der Takt
ist zu sehen, nur der Bytewert stimmt nicht überein. Hat jemand eine
Ahnung woran das liegen könnte?
Zudem hört Bascom einfach nach einer Weile mit dem SPI-Bus auf zu
senden. Also eine dauerhaften senden ist auch nicht möglich.

Danke schon mal für die Antwort
mfg
Alex