Hallo, ich möchte mit einem Atmega als SPI Slave Daten von einem anderen
IC empfangen, der als Master läuft. Den Atmega habe ich wie folgt
konfiguriert:
Allerdings bin ich beim Empfang nicht sicher, wie das richtig gemacht
wird.
1
SETREG_DATA// grün
2
SETRXTX// blau
3
4
SPDR=0x00;
5
byte2=spi_slave_receive();
6
if(byte2==0x13)uart_puts_P("byte2");// Inhalt soll testweise per UART ausgegeben werden (code von Peter Fleury)
7
elseuart_puts_P("xxx");
8
9
_delay_ms(20);
10
CLRREG_DATA
11
CLRRXTX
Auf dem Bild im Anhang ist zu sehen, wie der Master-IC bei Aktivierung
der beiden Ports (grün & blau) kurz den Clock inaktiv setzt und dann 24
Bit sendet. Ein SS vom Master aus gibt es nicht, deshalb habe ich den
Atmega SS dauerhaft auf GND gelegt.
spi schrieb:> SPCR = (1<<SPE) | (1<<SPIE) | (0<<DORD) | (0<<MSTR) | (0<<CPOL) | (0<<CPHA);
Wenn Du den SPI-Interrupt nicht nutzt, brauchst Du auch nicht SPIE
setzen.
> dummy=SPDR;> /* Return Data Register */> return SPDR;
Warum dieser doppelt hintereinander ausgeführte Zugriff auf SPDR?
> Allerdings bin ich beim Empfang nicht sicher, wie das richtig gemacht> wird.
Falls Dein Code nicht funktioniert, gib doch bitte eine richtige
Fehlerbeschreibung.
> if(byte2==0x13) uart_puts_P("byte2"); // Inhalt soll testweise per UART >ausgegeben werden
Hier wird nicht der Inhalt ausgegeben, sondern der Text "byte2".
J.-u. G. schrieb:> spi schrieb:>> SPCR = (1<<SPE) | (1<<SPIE) | (0<<DORD) | (0<<MSTR) | (0<<CPOL) | (0<<CPHA);> Wenn Du den SPI-Interrupt nicht nutzt, brauchst Du auch nicht SPIE> setzen.>
OK, das hatte ich mal testweise auch versucht.
>> dummy=SPDR;>> /* Return Data Register */>> return SPDR;> Warum dieser doppelt hintereinander ausgeführte Zugriff auf SPDR?>
Hatte irgendwo gelesen, dass man das vorher nochmal auslesen müsse.
>> Allerdings bin ich beim Empfang nicht sicher, wie das richtig gemacht>> wird.> Falls Dein Code nicht funktioniert, gib doch bitte eine richtige> Fehlerbeschreibung.>
Naja, wenn ich spi_slave_receive() aufrufe bleibt er halt in der while
hängen und es passiert nichts mehr.
>> if(byte2==0x13) uart_puts_P("byte2"); // Inhalt soll testweise per UART>>ausgegeben werden> Hier wird nicht der Inhalt ausgegeben, sondern der Text "byte2".
Ja zumindest sollte der Inhalt geprüft werden.
Wenn ich im Debugmodus in das SPDR was schreibe, müsste ich das doch in
der Registeranzeige rechts sehen oder? Wenn ich z.B. SPDR=0x01;
schreibe, tut sich da allerdings gar nichts.
spi schrieb:> Naja, wenn ich spi_slave_receive() aufrufe bleibt er halt in der while> hängen und es passiert nichts mehr.
Woran erkennst Du, dass er genau da hängen bleibt?
Zeig doch mal mehr von Deiner main()-Funktion.
Ist das Power Reduction Register richtig gesetzt?
// Enable SPI (disable it in Power Reduction Register)
PRR &= ~(1u << PRSPI);
Bin mir aber nicht sicher, ob das nicht schon standardmäßig gesetzt ist.
> Wenn ich im Debugmodus in das SPDR was schreibe, müsste ich das doch in> der Registeranzeige rechts sehen oder? Wenn ich z.B. SPDR=0x01;> schreibe, tut sich da allerdings gar nichts.
SPDR besteht aus zwei Registern, eins zum Lesen, eins zum Schreiben.
Hier hatte ich auch schon das Problem, dass nicht das (für mich)
richtige angezeigt wurde.
J.-u. G. schrieb:> spi schrieb:>> Naja, wenn ich spi_slave_receive() aufrufe bleibt er halt in der while>> hängen und es passiert nichts mehr.> Woran erkennst Du, dass er genau da hängen bleibt?>> Zeig doch mal mehr von Deiner main()-Funktion.
Zumindest kommt er aus der Funktion nicht mehr haeraus, da darauf
folgende Aufrufe nicht mehr ausgeführt werden.
schwarz schrieb:> Ist das Power Reduction Register richtig gesetzt?> // Enable SPI (disable it in Power Reduction Register)> PRR &= ~(1u << PRSPI);> Bin mir aber nicht sicher, ob das nicht schon standardmäßig gesetzt ist.>
Da habe ich gar nix mit gemacht, das ist wohl standardmäßig auch nicht
von Bedeutung.
spi schrieb:> #define CLRSSLINE SSPORT &= (0<<SSPIN); //!< Set ~SS line low.
...
> #define CLRCSLINE SSPORT &= (0<<CSPIN); //!< Set ~CS line low.
...
> DDRA |= (0<<RSTO);> DDRB |= (1<<RXTX) | (1<<REG_DATA) | (0<<BUTHERM) | (0<<CD_PD);
Nein, nein, nein! Bitte noch mal hier:
http://www.mikrocontroller.net/articles/Bitmanipulation
nachlesen, wie man Bits löscht.
Du scheinst ja einiges an Peripherie angeschlossen zu haben. Fehlerhaft
beschriebene Konfigurationsregister können natürlich dann zu Hängern
führen.
J.-u. G. schrieb:> spi schrieb:>> #define CLRSSLINE SSPORT &= (0<<SSPIN); //!< Set ~SS line low.> ...>> #define CLRCSLINE SSPORT &= (0<<CSPIN); //!< Set ~CS line low.> ...>>> DDRA |= (0<<RSTO);>> DDRB |= (1<<RXTX) | (1<<REG_DATA) | (0<<BUTHERM) | (0<<CD_PD);>> Nein, nein, nein! Bitte noch mal hier:> http://www.mikrocontroller.net/articles/Bitmanipulation> nachlesen, wie man Bits löscht.>> Du scheinst ja einiges an Peripherie angeschlossen zu haben. Fehlerhaft> beschriebene Konfigurationsregister können natürlich dann zu Hängern> führen.
Wäre das so richtig?
spi schrieb:> Wäre das so richtig?> DDRA |= (0<<RSTO);
Nein. Diese Anweisung bewirkt nichts.
> DDRB |= (1<<RXTX) | (1<<REG_DATA);> DDRB &= ~((1<<BUTHERM) | (1<<CD_PD));
Ja. So ist es richtig.
Hallo!
Offenbar handelt es sich hier um den Code für ein Powerline Modem.
Bin selbger grade am Basteln, möchte so etwas basierend auf dem Arduino
machen.
Bin leider Anfänger, in diesem Bereich und man findet nicht sehr viel
Code rund um den ST7540.
Würdest du den Code mit mir teilen, damit könnte ich mal starten? Auf
welcher Schaltung basiert dein Modem?