www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik SPI-Problem mit AVR


Autor: Martin (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo

Das Problem ist, dass ich den SPI einfach nicht zum ordnungsgemässen 
Funktionieren bringe. Der AVR ist ein Mega328p, und ich will über den 
SPI ein Grafikdisplay ansteuern.

Dazu verwende ich den Hardware-SPI, jedoch nicht das SS-Signal des SPI 
sondern ein separates chip select Signal, weil später einmal mehrere 
Slaves damit angesteuert werden sollen. Der SS-Pin ist als Out 
konfiguriert und unbenutzt.

Beiliegend ein KO-Bild, oben Clock und unten MOSI, mir scheints die 
Datenpulse sind nicht ganz sauber, sehe ich das recht? Die dürfen ja 
wohl nicht so verschiedene Breiten haben, oder?

Wenn dem so ist, was könnte das Problem sein? Ich habe den Takt so weit 
runter geschraubt wie möglich, bei einem 8MHz-Quarz habe ich die 
CLKDIV8-Fuse gesetzt und den SPI-Taktteiler nochmal auf 128 eingestellt. 
Wahrscheinlich übersehe ich irgendwas, da ich auch kein geübter 
SPI-Benutzer bin...

Grüsse
Martin

Autor: Michael M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
source?

Autor: Bensch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Passen CPOL und CPGHA zum Empfänger?

Senden und empfangen auf der gleichen CLK-Flanke geht im allgemeinen 
schief.

Autor: Klaus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Irgendwie schon kurios. Sogar das Clocksignal ist nicht regelmässig...

Autor: Benedikt K. (benedikt) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Da ist garnichts kurios:
SPI sendet 8bits am Stück, dazwischen ist halt eine mehr oder weniger 
große Pause in der Clock länger ist, und MOSI auf high liegt. Also 
vollkommen normal.
Der Fehler liegt also wo anders.

Autor: Martin (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Danke für eure Antworten.

@Bensch: Ich versuche gar nicht zu empfangen, weil der Slave nicht 
gelesen werden kann. Es handelt sich um ein BL12896A-Display.

@Michael M: Beiliegend die Display-Treiber .c und .h (abgeändert von 
Luminary Micro).

main sieht so aus:
int main(void) {

DDRB =  0b00101110;
PORTB = 0b00000001;
                      
DDRC =  0b0111111;
PORTC = 0b0000000;

DDRD =  0b00000011;
PORTD = 0b11111100;

// SPI CONFIG
SPCR = 0;
SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR1)|(1<<SPR0);
SPSR = (0<<SPI2X);

// Init OLED display
SSD1329_Init();

// Write Hello World
SSD1329_StringDraw("Hello World!", 30, 24, 15);

   //main loop
   while(1) {

   }
}

Hilft das was?

Grüsse

Martin

Autor: Soeren A. (abraxa)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie sieht denn die Beschaltung aus? Ohne die sagen uns deine 
Port-Konfigurationen leider nichts.

Es ist desweiteren moeglich, dass du reset falsch angeschlossen, chip 
select invertiert und/oder D0/D1 vertauscht hast. Das sehen wir im Code 
nicht :)

Autor: Bensch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> @Bensch: Ich versuche gar nicht zu empfangen, weil der Slave nicht
gelesen werden kann. Es handelt sich um ein BL12896A-Display

Also wenn das Display nichts empfangen soll, warum dann das Ganze?
Nochmal gaaaaanz langsam: Sender=AVR, Empfänger=Display.
Wenn also das Display auf der negativen Flanke sampled, geht schief.

Autor: Soeren A. (abraxa)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn Seite 12 von 
http://www.apc-plc.co.uk/documents/Bolymin%20BL128... 
stimmt (das Diagramm hat einige Fehler), dann wird auf der positiven 
Flanke gesampled.

Autor: Martin (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Ok klar, hatte ich ganz vergessen. Die Beschaltung ist wie folgt:

SS = B2 (wie erwähnt unbenutzt)
MOSI = B3
MISO = B4
SCK = B5
Display D/C = C0
Display RES = C1
Display CS = C2

@Bensch: Doch das Display soll empfangen, aber kann nichts senden. 
Beiliegend noch das Timing-Diagramm aus dem Datenblatt, meiner Meinung 
nach siehts schon so aus als ob bei steigender Flanke gelesen wird.

Autor: Soeren A. (abraxa)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
// The SPI must already be configured before using this driver and
// the following pins must already be defined:
//
// SCK            SPI Clock
// MOSI           SPI Data
// CS_DISP        Oled chip select, active low
// RES_DISP       Oled reset, active low
// DC_DISP        Data/command selection, low = command, high = data
// OLED_CMD_PORT  Port where the CS_DISP, RES_DISP and DC_DISP lines are connected

Hast du die in hardware.h definiert?

Bitte zeigen :)

Autor: Martin (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
voilà

Autor: Soeren A. (abraxa)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das Display wird nie resettet (RES_DISP ist unbenutzt). Da du VCC nicht 
ueber den uC steuerst, wirst du die specs nicht einhalten koennen (VDD 
an, Reset, VCC an). Vermutlich nicht tragisch, aber erwaehnenswert.

Schau also bitte mal, ob es schon funktioniert, wenn du vor dem SPI-Init 
das Display resettest (C1 low fuer >3uS, ab dann konstant high).

Autor: Martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Geile Sache, vielen Dank für den Hinweis! Ich habe also

OLED_CMD_PORT &= ~(1<<RES_DISP);
_delay_us(10);
OLED_CMD_PORT |= (1<<RES_DISP);

vorne in die SSD1329_Init() geschrieben und siehe da, endlich eine 
Anzeige auf dem Display!

Danke dir und allen anderen für die Hilfe, falls ich später weitere 
Fragen habe melde ich mich natürlich gerne wieder!

Grüsse
Martin

Autor: Soeren A. (abraxa)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Freut mich, dass es funktioniert.

Kleiner Hinweis am Rande: meine Aussage, dass der Controller nie 
resettet wird, war falsch - er wird vielmehr staendig resettet, da 
reset invertiert ist und nie auf high gesetzt wird.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.