mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik SPI für Kommunikation mit EA DOGM128


Autor: Trillian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich versuche ein EA DOGM128 mit dem ATMega64 zum Laufen zu bringen. 
Bisher tut sich leider nichts. Da dies nicht nur mein erster Kontakt mit 
diesem Display, sondern auch mit der SPI-Schnittstelle ist, möchte ich 
erstmal ausschließen, dass der Fehler in meiner SPI Routine liegt. Habe 
mich beim Takt an das Schaubild zur Datenübertragung im Display 
Datenblatt gehalten (http://www.lcd-module.de/deu/pdf/grafik/dogm128.pdf 
--> Seite 5). Also das hoffe ich jedenfalls. Wäre dankbar, wenn 
vielleicht mal jemand rüberschauen könnte, ob die SPI Routine so 
funktioniert.
; ************ write 8 bit to mosi/si *************
;
WRITE_SPI:
    push  temp1
    push  r2

    ldi    temp1, 8  ; bit counter
    mov    r2, temp1

    mosi_low  

loop_8bit:
    clock_high      
    lsl    spi_data  

    brcs  high_mosi
    mosi_low
    rjmp  bit_sent
high_mosi:
    mosi_high    ; if brcs is false, the number of clocks is 1(lsl)+1(brcs)+5(mosi_low)+2(rjmp) = 9 clocks
    nop        ; if brcs is true, the number is 1(lsl)+2(brcs)+5(mosi_high)+1(nop) = 9 clocks
bit_sent:
    clock_low

    nop
    nop
    nop
    nop
    nop
    nop

    dec    r2
    brne  loop_8bit  ; 6*1(nop)+1(dec)+2(brne) = 9 clocks
        
    pop    r2
    pop    temp1

    ret

Die Makros (mosi_high, mosi_low ...) sehen so aus:
.macro  clock_low
    lds    temp1, PORTF      ; 2 Takte
    andi   temp1, ~(1<<clk)    ; 1 Takt
    sts    PORTF, temp1      ; 2 Takte
.endm

.macro  clock_high
    lds    temp1, PORTF      ; 2 Takte
    ori    temp1, (1<<clk)      ; 1 Takt
    sts    PORTF, temp1      ; 2 Takte
.endm

.macro  mosi_low
    lds    temp1, PORTF
    andi   temp1, ~(1<<mosi)
    sts    PORTF, temp1
.endm

.macro  mosi_high
    lds    temp1, PORTF
    ori    temp1, (1<<mosi)
    sts    PORTF, temp1
.endm

Danke im Voraus für Eure Antworten :)

Autor: Swen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sorry, zzt. nur alter Codeschnipsel verfügbar.

... das hier funktioniert z.B. mit DOGM128 3- Zeilig, läßt sich bequem 
anpassen.

Delays müssen noch ergänzt werden, dort kann man noch viel falsch machen 
;-), die Displays wollen es nicht "zu schnell"...


also zuerst SPI MaterInit und danach lcd_init ausführen,

Zeichen werden z.B. mit

ldi temp1,'*'
out SPDR,Temp1
rcall delay50ms

ausgegeben.


----------------------------------------------------------------------

lcd_init:
    rcall  SPI_MasterInit
    rcall delay5ms

    ldi    temp1,0b00111001    ;Function set 
(8Bit,2Lines,DoubleHight,IS[2:1])
    rcall    SPI_MasterTransmit
    rcall delay5ms

    ldi    temp1,0b00111001    ;Function set 
(8Bit,2Lines,DoubleHight,IS[2:1])
    rcall    SPI_MasterTransmit
    rcall delay5ms

    ldi    temp1,0b00010100    ;Bias Set (1/4Bias,FX)
    rcall    SPI_MasterTransmit
    rcall delay5ms

    ldi    temp1,0b01010101    ;Booster Set (C5,C4)Contrast Set 
(C3,C2,C1,C0)
    rcall    SPI_MasterTransmit
    rcall delay5ms

    ldi    temp1,0b01101101    ;Follower (Follower,Rab2,Rab1,Rab0)
    rcall    SPI_MasterTransmit
    rcall delay5ms

    ldi    temp1,0b01111000    ;Contrast Set
    rcall    SPI_MasterTransmit
    rcall delay5ms

    ldi    temp1,0b00001100    ;Display ON (Entire ON,Cursor 
OFF,Blinking OFF)
    rcall    SPI_MasterTransmit
        rcall delay5ms

    ldi    temp1,0b00000001      ;Clear Display
    rcall    SPI_MasterTransmit
    rcall delay5ms

    ldi    temp1,0b00000110    ;Auto Increment
    rcall    SPI_MasterTransmit
        rcall delay5ms

ret

; -------------------------------------------------------------------

SPI_MasterInit: ; für SPI- Display TExt 3x16
    sbi    PortB,RS
    sbi    PortB,CSB
    ldi   Temp2,(1<<SPE)|(1<<MSTR)|(1<<SPR0)
    ; Enable SPI, Master, set clock rate fck/16
    out   SPCR,Temp2
ret

; -------------------------------------------------------------------

SPI_MasterTransmit: ; für SPI- Display Text 3x16
    cbi    PortB,RS
    cbi    PortB,CSB
    out   SPDR,temp1          ; Start transmission of data (Temp1)
  Wait_Transmit:              ; Wait for transmission complete
    sbis   SPSR,SPIF
    rjmp   Wait_Transmit
    sbi    PortB,RS
    sbi    PortB,CSB
ret

; -------------------------------------------------------------------

Autor: Swen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Äh, sorry, wer lesen kann ist immer noch klar im Vorteil. Die Routine 
für diese _Grafik_- Displays habe ich leider nur in C. Der SPI- Teil ist 
aber prinzipiell der gleiche, die einzelnen Steps der Initialisierung 
liefert das Datenblatt. Sonst: auf das Timing achten (Delays).

Autor: Matthias Lipinsky (lippy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mal so ne Frage:

Warum nimmst du nicht die Hardware-SPI Schnittstelle?

Autor: Marja K. (trillian)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Swen: Oh das is ja mehr als erwartet ;) Danke für Deine Bemühungen aber 
das Problem ist, dass ich nicht die Hardware SPI vom AVR benutze sondern 
versuche, die SPI in Software zu realisieren. Zur Initialisierung: Ich 
vermute Deine Sequenz ist für den ST7036 Controller - in dem 128er 
DOG-Display ist aber der ST7565 drin. Bei dem muss die 
Initialisierungssequenz innerhalb von max 5ms abgeschlossen sein. Ich 
vermute also dass ich keine zusätzlichen Pausen benötige.

@Matthias Lipinsky: Ja das würd ich auch gerne, aber das war vom 
Platinenlayout leider nicht möglich. Ich habe nur 4 Pins des F Ports zur 
Verfügung um mit dem Display zu kommunizieren.

Mein aktueller Fortschritt: Null. Da sich an meinem Display aber auch 
wirklich garnichts tut, befürchte ich, dass es an der Kommunikation 
hapert. Habe da noch einige Fragen zur SPI:

1. Eine Periode meines SPI Clocks dauert 18 AVR-Takte (9 Takte low, 9 
Takte high). Das entspricht bei mir ca 1MHz. Meiner Meinung nach ist es 
vollkommen egal, welche Frequenz der SPI Master an die Slaves sendet - 
solange die max Frequenz des Slaves nicht überschritten wird. Ist das 
richtig?

2. Der Slave/Chip-Select Pin meines Displays ist mit der Masse 
verbunden, bekommt also ein Dauer-Low bzw. "lauscht" ständig am SPI Bus. 
Geht das so überhaupt?

Gruß

Autor: Bensch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
1. Im Prinzip ja...

2. Nein, lies das Datenblatt des Display-Controllers.

Autor: Marja K. (trillian)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Bensch

ja das hab ich getan, habe aber daraus geschlossen, dass der CS ruhig 
auf Masse liegen kann, da ich ja eh nur diesen einen Slave habe und wenn 
Daten über den SPI Bus kommen, dann sind die immer und auf jeden Fall 
für diesen Slave (Display). Oder was erfüllt der CS noch für eine 
Funktion?

Autor: Swen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
... vielleicht helfen Dir die Codeschnipsel aus meiner funktionierenden 
C- Routine weiter:





#define DDR_SPI DDRB
#define DD_MOSI PORTB3
#define DD_SCK PORTB5

#define LCD_A0 PORTB1
#define LCD_CSB PORTB2

-.-


  // set directions for A0 and CSB
  DDRB |= (1<<LCD_A0) | (1<<LCD_CSB);
  PORTB |= (1<<LCD_A0) | (1<<LCD_CSB);

  SPI_MasterInit();

#if LCD_TYPE == DOGM128
  lcd_cmd(ST7565R_Set_Start_Line);
  lcd_cmd(ST7565R_Select_ADC_Reverse);
  lcd_cmd(ST7565R_Set_COM_Normal);
  lcd_cmd(ST7565R_Display_Normal);
  lcd_cmd(ST7565R_Set_Bias_1to8);      // Set bias 1/9 (Duty 1/65)
  lcd_cmd(ST7565R_Set_Power_Controller | (1<<ST7565R_Voltage_regulator) 
| (1<<ST7565R_Voltage_follower));
  lcd_cmd(ST7565R_Set_Resistor_Ratio | 7);
  lcd_cmd(ST7565R_Go_To_Volume_Set_Mode);  // Contrast set (2 byte 
command)
  lcd_cmd(0x16);              // data byte for contrast
  lcd_cmd(ST7565R_Static_Indicator_Off);  // no indicator
  lcd_cmd(ST7565R_Display_On);      // Display on

-.-

Und - ja, einmal warten reicht beim Grafikdisplay. Ich kann mich 
erinnern am Anfang einen Bug mit der ClockPhase gemacht zu haben. Das 
Datenblatt war da wohl ein wenig "komisch" zu interpretieren...

Autor: Marja K. (trillian)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Swen,

die Initialisierungsequenz werde ich so übernehmen (natürlich in asm), 
da sie ja von Dir getestet ist ;) Vielen Dank.

Aber bis jetzt krieg ich überhaupt keine Daten zum Display gesendet - 
und es liegt laut Bensch am Chip-Select Pin. Habe nochmal im Controller 
Datenblatt nachgeschaut und doch noch was gefunden:

When the chip select is inactive, D0 to D7 enter a high
impedance state, and the A0, /RD, and /WR inputs are
inactive. When the 4-line SPI interface is selected, the shift
register and the counter are reset.

Also eine weitere Funktion des CS ist das Resetten des Schieberegisters 
und irgendeines counters. Ist das nötig damit das Display die 
empfangenen Daten auswertet?

Autor: Swen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Noch'n kleiner Tipp:

Vergiss den CS ;-) - er kann(!) benutzt werden wenn andere SPI- Geräte 
mit angeschlossen werden sollen.

Aber die Leitung A0 entscheidet zwischen Daten und Befehl. Das ist 
vielleicht zu beachten...

Autor: Bensch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dieses IC scheint eine grosse Ausnahme zu sein und braucht keinen CS. 
Das beinhaltet aber die Gefahr, dass irgendwelcher Sch..., der 
irgendwann auf der CLK passiert z.B. beim Initialisieren den Controller 
durcheinander bringen kann. Und bei einer Software-SPI ist das m.E. sehr 
wahrscheinlich.
Daher die DRINGENDE Empfehlung: benutz den CS!

Autor: Marja K. (trillian)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Puuh ok dann werd ich mich jetzt wieder ransetzen. Vielen Dank erstmal 
für Eure Hilfe - ich melde mich später nochmal um zu berichten ;)

LG und einen schönen Tag noch

Autor: Swen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
... sollte nicht heißen das der CS nicht benutzt werden soll wenn ein 
Portpin da ist um ihn anzusteuern ... ;-) andererseits sollte es den 
Display- Controller wenig kümmern wenn z.B. die Clock- Leitung während 
der Initialisierung irgendwo rumbaumelt - das kann auch dem CS- Pin zu 
diesem Zeitpunkt passieren und der Chip sollte irgendwie sowieso nach 
einer gewissen Zeit ohne Takt einen Interface- Reset durchführen (?)

Autor: Marja K. (trillian)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Freude Freude :D Es lebt!! Habe es geschafft, dass Display zu 
initialisieren und mir "all display points ON" anzeigen zu lassen.

Wie vermutet, lag der Fehler in meiner SPI - genauer gesagt an deren 
Initialisierung. Diese besteht im Grunde nur darin, den Clock auf high 
zu setzen/halten, solange keine Kommunikation stattfinden soll. 
Höchstwahrscheinlich hat das Display tatsächlich irgendwo am Anfang 
meines Hauptprogrammes ein low auf dem SPI Clock erhalten und irgendein 
Bit vom Mosi ausgelesen, als es das noch garnicht sollte :s

Also zusammenfassend kann ich sagen, dass das Display (in meinem Fall) 
auch ohne Benutzung des CS-Pins funktioniert (dieser ist mit Masse 
verbunden). Funktioniert natürlich nur dann, wenn man mit dem 
Master-Controller auch tatsächlich nur einen SPI-Slave ansprechen will.

Auch die SPI Clock-Frequenz von 1MHz macht komischerweise keine 
Probleme. Auf meinem Testboard wird nämlich die 5V AVR Spannung über 
Widerstände (Spannungsteiler) auf die 3,3V Display Spannung 
runtergesetzt. Das führt dazu, dass die SPI Frequenz die ich vom AVR ans 
Display schiebe nicht grad rechteckig ist, sondern fast dreieckförmig!! 
Trotzdem scheint das dem Display auszureichen :)

Liebe Grüße und vielen Dank nochmal,
Trillian

Autor: Bensch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Genau meine Vermutung, mit CS wär das nicht passiert ...

> fast dreieckförmig...

Solange Gnd und 3,3V so gerade erreicht werden, ist das ok. Ich hab hier 
470R  und 470pF in den Signalleitungen bei 600kHz und 5V-Pegel, das 
reicht für 1m Leitung zum Display. Aber selbst ein Signal mit Pegeln 
<1,5V und >3,5V spielt einwandfrei- wenn auch mit geringerer 
Störsicherheit.

Autor: Marja K. (trillian)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bensch wrote:
> Genau meine Vermutung, mit CS wär das nicht passiert ...

Ja das stimmt. Hätte mir einiges erspart...

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.