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.
1
; ************ write 8 bit to mosi/si *************
2
;
3
WRITE_SPI:
4
push temp1
5
push r2
6
7
ldi temp1, 8 ; bit counter
8
mov r2, temp1
9
10
mosi_low
11
12
loop_8bit:
13
clock_high
14
lsl spi_data
15
16
brcs high_mosi
17
mosi_low
18
rjmp bit_sent
19
high_mosi:
20
mosi_high ; if brcs is false, the number of clocks is 1(lsl)+1(brcs)+5(mosi_low)+2(rjmp) = 9 clocks
21
nop ; if brcs is true, the number is 1(lsl)+2(brcs)+5(mosi_high)+1(nop) = 9 clocks
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
; -------------------------------------------------------------------
Ä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).
@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ß
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?
... 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...
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?
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...
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!
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
... 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 (?)
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
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.