Forum: Mikrocontroller und Digitale Elektronik DOGM128 SPI Ansteuerung


von Marcus (Gast)


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

von spess53 (Gast)


Lesenswert?

Hi

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

Nein. Es reicht in SPCR die Bits SPE und MSTR zu setzen.

MfG Spess

von Marcus (Gast)


Lesenswert?

Geht leider trotzdem nicht (Habe schon nahezu alles ausprobiert. Sogar 
schon das Datenkabel überprüft)

von spess53 (Gast)


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

von Marcus (Gast)


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?

von Marcus (Gast)


Lesenswert?

Ach, fällt mir gerade ein: Ich habe nebenbei am TIMER1 eine 8bit-PWM 
laufen (für LED zum dimmen). Kann dies der Störfaktor sein?

von spess53 (Gast)


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

von Marcus (Gast)


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

von spess53 (Gast)


Lesenswert?

Hi

>Oder ist das wiederum schlecht, wenn es zu lange ist?

Nein. Und siehst du jetzt etwas?

MfG Spess

von Marcus (Gast)


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
}

von Marcus (Gast)


Lesenswert?

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

von spess53 (Gast)


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

von Marcus (Gast)


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.

von Marcus (Gast)


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.

von spess53 (Gast)


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

von Marcus (Gast)


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

von Marcus (Gast)


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.

von spess53 (Gast)


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

von Marcus (Gast)


Lesenswert?

Danke für deine Hilfe :-)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.