DOGM128 SPI Ansteuerung

Gast #2345079
Lesenswert?

Moin!

Ich habe mir schon sehr viele und auch hilfreiche Beiträge zum Thema 
DOGM SPI Ansteuerung durchgelesen, blicke aber trotzdem nicht durch. Ich 
verwende die vom Hersteller empfohlene Ansteuerung mit jeweils 1 ms 
zwischen den Befehlen.

Wenn ich das aus anderen Beiträgen richtig erfasst habe, dann muss der 
SPI Ruhepol High sein (CPOL setzen). Muss ich da auch CPHA setzen?

Ich habe einmal im Wiki einen Beitrag über den Wellenwiderstand gelesen. 
Kann es vielleicht daran liegen, dass ich ein 20 cm langes Datenkabel 
(10pol. Wannenstecker) verwende und die Daten nicht richtig ankommen?

Ich betreibe das Display an 3,3V. Boosterkondensatoren habe ich 
angeschlossen. Theoretisch müsste ich nach der Initialisierung ca. 12V 
an Pin 32 abtasten können. Ich kann aber nur 2,7 Volt messen. Also 
stimmt was mit der Übertragung nicht. Ich verwende einen ATmega644 @10 
Mhz

Die Hardware-SPI-Ansteuerung habe ich aus dem Datenblatt des ATMEGA64.

Meine Verbindungen:
Mosi -> Si
SCK -> SCL
PA0 (auf LOW gesetzt) -> CS
PA1 (auf HIGH getzt) -> RESET
PA2 (vorerst auf LOW gesetzt) -> A0

Display-Routine(n):
1
#include "SPI.h"
2
#include <util/delay.h>
3

4
#ifndef _Display
5
#define _Display
6

7
void DisplayInit(void)
8
{
9
  SPI_MasterTransmit(0x40);  //Display start line 0
10
  _delay_ms(1);
11
  SPI_MasterTransmit(0xA1);  //ADC Reverse
12
  _delay_ms(1);
13
  SPI_MasterTransmit(0xC0);  //Normal COM0~COM63
14
  _delay_ms(1);
15
  SPI_MasterTransmit(0xA2);  //Set Bias 1/9
16
  _delay_ms(1);
17
  SPI_MasterTransmit(0x2F);  //Booster, Regulator and Follower on
18
  _delay_ms(1);
19
  SPI_MasterTransmit(0xF8);  //Booster 4x
20
  _delay_ms(1);
21
  SPI_MasterTransmit(0x00);  //Booster 4x
22
  _delay_ms(1);
23
  SPI_MasterTransmit(0x27);  //Contrast set
24
  _delay_ms(1);
25
  SPI_MasterTransmit(0x81);  //Contrast set
26
  _delay_ms(1);
27
  SPI_MasterTransmit(0x16);  //Contrast set
28
  _delay_ms(1);
29
  SPI_MasterTransmit(0xAC);  //No Indicator
30
  _delay_ms(1);
31
  SPI_MasterTransmit(0x00);  //No Indicator
32
  _delay_ms(1);
33
  SPI_MasterTransmit(0xAF);  //Display on
34
  _delay_ms(1);
35
}
36

37
#endif

SPI-Routine (Aus dem 644-Datenblatt):
1
#ifndef _SPI
2
#define _SPI
3

4
void SPI_MasterInit(void)
5
{
6
  DDRB = (1<<PB5) | (1<<PB7);
7
  SPCR = (1<<SPE) | (1<<MSTR);
8
  SPCR = (1<<SPR0);  //F_CPU / 16
9
  SPCR |= (1<<CPOL);  //set CPOL
10
}
11

12
void SPI_MasterTransmit(char Data)
13
{
14
  SPDR = Data;
15
  while( ! (SPSR & (1<<SPIF)));
16
}
17

18
#endif
Gast #2345128
Lesenswert?

Hi

Bei mir funktioniert das mit folgenden Initialisierungswerten:

init_sequ: .db $40,$A1,$C0,$A6,$A2,$2F,$F8,$00,$27,$81,$16,$AC,$00,$AF
                            |
                            |_Display normal/reverse (Display normal)

Bei dir fehlt der gekennzeichnete Befehl.
Was für Kondensatoren benutzt du?

MfG Spess
Gast #2345144
Lesenswert?

Ach, A6 hab ich vor lauter hex-zahlen wohl übersehen. Geht aber noch 
immer nicht (immer noch 2,7V). Ich verwende Chip-Kondensatoren (0603) 
1µF direkt ans Board angelötet. Ich habe schon auf eventuelle Brücken 
überprüft. 1µF deshalb, weil es ja auch im Datenblatt steht. Oder soll 
man besser nicht nach dem Rezept kochen?
Gast #2345160
Lesenswert?

Hi

> 1µF deshalb, weil es ja auch im Datenblatt steht. Oder soll
>man besser nicht nach dem Rezept kochen?

Das passt schon so.

Versuche mal: RESET anschließen und vor deiner Initialisierung die 
Leitung kurz (µs) auf L ziehen. Dann noch ein paar µs warten. Kann auch 
länger sein.

Möglicherweise überfährst du das Display, bevor es bereit ist.

MfG Spess
Gast #2345174
Lesenswert?

Ich habe das Ganze mal etwas in die Länge gezogen (10ms). Oder ist das 
wiederum schlecht, wenn es zu lange ist?
1
#include "SPI.h"
2
#include <util/delay.h>
3

4
#ifndef _Display
5
#define _Display
6

7
void DisplayInit(void)
8
{
9
  PORTA &= ~(1<<Reset_DSP);
10
  _delay_ms(10);
11
  PORTA |= (1<<Reset_DSP);
12
  _delay_ms(10);
13
  SPI_MasterTransmit(0x40);  //Display start line 0
14
  _delay_ms(1);
15
  SPI_MasterTransmit(0xA1);  //ADC Reverse
16
  _delay_ms(1);
17
  SPI_MasterTransmit(0xC0);  //Normal COM0~COM63
18
  _delay_ms(1);
19
  SPI_MasterTransmit(0xA6);  //Display Normal
20
  _delay_ms(1);
21
  SPI_MasterTransmit(0xA2);  //Set Bias 1/9
22
  _delay_ms(1);
23
  SPI_MasterTransmit(0x2F);  //Booster, Regulator and Follower on
24
  _delay_ms(1);
25
  SPI_MasterTransmit(0xF8);  //Booster 4x
26
  _delay_ms(1);
27
  SPI_MasterTransmit(0x00);  //Booster 4x
28
  _delay_ms(1);
29
  SPI_MasterTransmit(0x27);  //Contrast set
30
  _delay_ms(1);
31
  SPI_MasterTransmit(0x81);  //Contrast set
32
  _delay_ms(1);
33
  SPI_MasterTransmit(0x16);  //Contrast set
34
  _delay_ms(1);
35
  SPI_MasterTransmit(0xAC);  //No Indicator
36
  _delay_ms(1);
37
  SPI_MasterTransmit(0x00);  //No Indicator
38
  _delay_ms(1);
39
  SPI_MasterTransmit(0xAF);  //Display on
40
  _delay_ms(1);
41
}
42

43
#endif
Gast #2345203
Lesenswert?

Nein tut nix. Ich poste mal zur Sicherheit den Hauptcode. Vielleicht 
versteckt sich ja da was.
1
#include <avr/io.h>
2
#include <util/delay.h>
3
#include <avr/interrupt.h>
4
#include "SPI.h"
5
#include "Interrupts.h"
6
#include "PinDefinitions.h"
7
#include "Display.h"
8

9
int main(void)
10
{
11
    DDRD |= (1<<PD5);              //Ausgangspin setzten (Für LED mit PWM)
12
  DDRD &= ~(1<<PD4);              //Eingangspin setzten (Für LED mit PWM)
13
  DDRA = (1<<PA0) | (1<<PA1) | (1<<PA2);
14
  
15
  PORTA |= (1<<Reset_DSP);
16
  PORTA &= ~(1<<ChipSelect);
17
  PORTA &= ~(1<<A0);
18
  
19
  SPI_MasterInit();
20
  
21
  PCMSK3 |= (1<<PCINT28);            //Für LED mit PWM
22
  PCICR |= (1<<PCIE3);            //Für LED mit PWM
23
  
24
  TCCR1A = (1<<WGM10) | (1<<COM1A1);      //Fast PWM 8 Bit (Für LED mit PWM)
25
  TCCR1B = (1<<WGM12) | (1<<CS10);      // Prescaler 1 = Enable counter (Für LED mit PWM)
26
  OCR1A = 255;                //Volle Ansteuerung (127 = halbe Ansteuerung) (Für LED mit PWM)
27
  
28
  sei();
29
  
30
  DisplayInit();
31
  _delay_ms(10);
32
  SPI_MasterTransmit(0xA5);
33
    
34
    while(1)
35
    {    
36
    }
37
}
Gast #2345256
Lesenswert?

Hi

>Nein tut nix. Ich poste mal zur Sicherheit den Hauptcode. Vielleicht
>versteckt sich ja da was.

Also, auf den ersten Blick (als notorischer Assemblerprogrammierer) kann 
ich nichts auffäliges erkennen.
Vielleicht solltest du doch noch mal die Hardware überprüfen.

>Gehören vielleicht PullUp/PullDown Widerstände bei der Datenleitung
>rein?

Nein.

MfG Spess
Gast #2345362
Lesenswert?

Ich kann den Code drehen und wenden wie ich will, es funzt einfach 
nicht. Hardwaremäßig alles in Ordnung. Das Display bekommt ca. 3,2 Volt 
und bei den Datenleitungen kann ich nach dem Einschalten kurz eine 
Frequenz messen (habe leider nur ein Multimeter und keien Oszi oder 
Logikanalyzer). Ich mach mal ne Pause. Vielleicht kommt dann eine 
Erleuchtung :-)
Vorschläge werden gerne entgegengenommen.
Gast #2345564
Lesenswert?

Ich weiß jetzt muss ich schon wieder nerven :-)

Ich habe nun das LCD aus dem Sockel entfernt, eine LED an dem SI-pol mit 
zu GND eingesetzt und den Code jetzt kurz umgeschrieben. Wenn ich 
programmiere leuchtet die LED wie erwartet auch auf.

1
#include <avr/io.h>
2
#include <util/delay.h>
3
#include <avr/interrupt.h>
4
#include "SPI.h"
5
#include "Interrupts.h"
6
#include "PinDefinitions.h"
7
#include "Display.h"
8

9
int main(void)
10
{
11
    DDRD |= (1<<PD5);              //Ausgangspin setzten (Für LED mit PWM)
12
  DDRD &= ~(1<<PD4);              //Eingangspin setzten (Für LED mit PWM)
13
  DDRA = (1<<PA0) | (1<<PA1) | (1<<PA2);
14
  
15
  PORTA &= ~(1<<Reset_DSP);
16
  PORTA &= ~(1<<ChipSelect);
17
  PORTA &= ~(1<<A0);
18
  
19
  SPI_MasterInit();
20
  
21
  PCMSK3 |= (1<<PCINT28);            //Für LED mit PWM
22
  PCICR |= (1<<PCIE3);            //Für LED mit PWM
23
  
24
  TCCR1A = (1<<WGM10) | (1<<COM1A1);      //Fast PWM 8 Bit (Für LED mit PWM)
25
  TCCR1B = (1<<WGM12) | (1<<CS10);      // Prescaler 1 = Enable counter (Für LED mit PWM)
26
  OCR1A = 255;                //Volle Ansteuerung (127 = halbe Ansteuerung) (Für LED mit PWM)
27
  
28
  sei();
29
  
30
  //DisplayInit();
31
  //_delay_ms(10);
32
  //SPI_MasterTransmit(0xA5);
33
    
34
    while(1)
35
    {
36
    SPI_MasterTransmit(0xFF);
37
    _delay_ms(1);
38
    }
39
}


Durch die while-schleife müsste das SPI ja dauernd Daten übertragen 
(111111...). Die oben genannte LED leuchtet aber kein einziges Mal auf. 
Ist dies so richtig? Meiner meinung nach müsste sie zumindest flackern.
Gast #2345598
Lesenswert?

Hi

> Meiner meinung nach müsste sie zumindest flackern.

Nicht unbedingt. Wenn der Ruhepegel H ist und du gibst 8x H aus, wird 
nichts flackern. Mach das gleiche mal mit 0x00. Oder du setzt den 
SPI-Clock möglichst weit herunter und gibst 0x55 oder 0xAA aus.

MfG Spess
Gast #2345617
Lesenswert?

Problem gelöst!

Datenblatt sagt:

1
When the SPI is configured as a Master (MSTR in SPCR is set), the user can
2
determine the direction of the SS pin.
3
If SS is configured as an output, the pin is a general output pin which
4
does not affect the SPI system. Typically, the pin will be driving the SS
5
pin of the SPI Slave.
6
If SS is configured as an input, it must be held high to ensure Master SPI
7
operation.


Laut dem muss ich beim SPI auch SS als Ausgang definieren oder auf High 
schalten. Da ich weder noch gemacht habe, kann es garnicht 
funktionieren!

Mfg
Gast #2345774
Lesenswert?

Noch eine letzte Frage:

Wenn ich das LCD initalisiere, dann zeigt er immer irgendein wirres Zeug 
an. Auch wenn ich "All points on -> All points off" in der Reihenfolge 
mache, bleiben die Punkte. Wenn ich etwas ausgebe, werden die zufälligen 
Punkte überschrieben. Wie bringe ich die Punkte beim Start komplett weg? 
Muss ich jedes Bit mit 0 beschreiben? Die Initialisierung ist exakt nach 
dem Hersteller.
Gast #2345781
Lesenswert?

Hi

>Auch wenn ich "All points on -> All points off" in der Reihenfolge
>mache, bleiben die Punkte.

Diese Befehle beeinflussen den Displayram nicht.

>Wie bringe ich die Punkte beim Start komplett weg?
>Muss ich jedes Bit mit 0 beschreiben? Die Initialisierung ist exakt nach
>dem Hersteller.

Ja. Aber nicht bitweise. Einfach die Bytes jeder Page mit 0x00 
beschreiben.

MfG Spess

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren