Forum: Mikrocontroller und Digitale Elektronik DOGM132 + SPI an Mega16


von Alex (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,
Ich habe mir vor Kurzem ein DOGM132 Grafik-Display geholt und scheitere 
an der Ansteuerung.
Ich habe schon ein paar Texte hier über das Display gelesen, aber keiner 
hat wirklich etwas gebracht.
Die Kondensatoren in der Schaltung sind 1µF, wie im Datenblatt.
Der ATmega32 arbeitet mit 5V, daher die Spannungsteiler.
CS,MOSI,SCK sind an den SPI-Pins und LCD_reset & RAMSEL sind an PORTD.

Anbei ist der C-Code & ein Bild der Beschaltung (die Jumper sind 
natürlich übergelötet, JTAG ist aus).
Momentan kann ich die nicht genauer nachprüfen. Die Hardware habe ich 
schonmal flüchtig geprüft (auf lötfehler) und die schien i.O. zu sein.
Ich rufe dann im Code einfach nur dogm_init(); auf und erwarte, dass 
alles Kurz an & wieder aus geht - es passiert aber nichts! (Der 
Prozessor macht noch anderes, woran ich merke dass der Prozessor 
funktioniert und die Funktion auch aufgerufen wird...)
Eigentlich habe ich mit Programmieren, Elektronik u.s.w. schon etwas 
Erfahrung, aber momentan komme ich mit dem Display einfach nicht weiter 
und hoffe hier auf Hilfe...
1
HEADER: DOGM.H
2
3
4
5
#ifndef DOGM_H
6
#define DOGM_H
7
8
#include <avr\io.h>
9
#include <util\delay.h>
10
11
#define DOGM_RESET_PORT PORTD 
12
#define DOGM_RESET_DIR DDRD 
13
#define DOGM_RESET_BIT 3 
14
15
#define DOGM_RAMSEL_PORT PORTD 
16
#define DOGM_RAMSEL_DIR DDRD 
17
#define DOGM_RAMSEL_BIT 4 
18
19
#define DOGM_INIT_BYTES 14
20
21
void dogm_init(void);
22
23
void dogm_adress(uint8_t ptr);
24
25
void dogm_writedata(uint8_t data);
26
27
void dogm_page(uint8_t page);
28
29
void dogm_all(uint8_t onoff);
30
31
#endif
32
33
34
35
36
SOURCE: DOGM.C
37
38
39
40
41
#include "dogm.h"
42
43
const uint8_t dogm_init_data[DOGM_INIT_BYTES] = {0x40,0xA1,0xC0,0xA6,0xA2,0x2F,0xF8,0x00,0x23,0x81,0x1F,0xAC,0x00,0xAF};
44
45
inline void dogm_reset_lo(void) {
46
  DOGM_RESET_PORT &= ~(1 << DOGM_RESET_BIT);
47
}
48
49
inline void dogm_reset_hi(void) {
50
  DOGM_RESET_PORT |= (1 << DOGM_RESET_BIT);
51
}
52
53
inline void dogm_ramsel_lo(void) {
54
  DOGM_RAMSEL_PORT &= ~(1 << DOGM_RAMSEL_BIT);
55
}
56
57
inline void dogm_ramsel_hi(void) {
58
  DOGM_RAMSEL_PORT |= (1 << DOGM_RAMSEL_BIT);
59
}
60
61
inline void dogm_cs_hi(void) {
62
  PORTB |= (1 << 4);
63
}
64
65
inline void dogm_cs_lo(void) {
66
  PORTB &= ~(1 << 4);
67
}
68
69
void dogm_spi_init(void) {
70
  DDRB |= (1<<PB4) | (1<<PB5) | (1<<PB7);
71
72
  dogm_cs_hi();
73
74
  SPCR = (1<<SPE) | (1<<MSTR) | (1<<SPR0);
75
76
    uint8_t dummy = (SPSR); // clear status, nie verkehrt...
77
  dummy=dummy;
78
79
}
80
81
void dogm_spi_transmit(uint8_t cData) {
82
  /* Start transmission */
83
  dogm_cs_lo();
84
85
  SPDR = cData;
86
  /* Wait for transmission complete */
87
  while(!(SPSR & (1<<SPIF)));
88
89
  dogm_cs_hi();
90
}
91
92
void dogm_all(uint8_t onoff) {
93
  dogm_ramsel_lo();
94
95
  dogm_spi_transmit(0b10100100 | onoff);
96
}
97
98
void dogm_init(void) {
99
  DOGM_RESET_DIR |= (1 << DOGM_RESET_BIT);
100
  DOGM_RAMSEL_DIR |= (1 << DOGM_RAMSEL_BIT);
101
102
  dogm_spi_init();
103
104
  dogm_reset_lo();
105
106
    dogm_ramsel_lo();
107
108
    _delay_ms(50);
109
    dogm_cs_lo();
110
111
  dogm_reset_hi();
112
113
  _delay_us(1000);
114
115
  uint8_t i;
116
  for (i=0; i < DOGM_INIT_BYTES; ++i) {
117
    dogm_spi_transmit(dogm_init_data[i]);
118
  }
119
  _delay_us(1000);
120
121
  dogm_all(1);
122
123
  _delay_ms(500);
124
125
  dogm_all(0);
126
127
  _delay_ms(500);
128
/*
129
  dogm_page(0);
130
  dogm_adress(0);
131
  for(i=0;i<132;++i) {
132
    dogm_writedata(170);
133
  }
134
*/
135
}
136
137
138
139
void dogm_adress(uint8_t ptr) {
140
  dogm_ramsel_lo();
141
142
  dogm_spi_transmit(0b0001 | ((ptr >> 4) & 0b00001111));
143
  dogm_spi_transmit(0b0000 | (ptr & 0b00001111));
144
}
145
146
void dogm_page(uint8_t page) {
147
  dogm_ramsel_lo();
148
149
  dogm_spi_transmit(0b1011 | (page & 0b00001111));
150
}
151
152
void dogm_writedata(uint8_t data) {
153
  dogm_ramsel_hi();
154
155
  dogm_spi_transmit(data);
156
}

MfG Alex

von Alex (Gast)


Lesenswert?

Ich habe gerade gesehen, dass einer der Spannungsteiler-Widerstände 
nicht richtig gelötet war. Kann das Display davon schaden genommen 
haben?
Das Display hat vom Mega16 die 5V vom Pin über 10kOhm auf Reset oder A0 
bekommen :-/.

MfG Alex

von Alex (Gast)


Lesenswert?

Das Problem habe ich jetzt gelöst. Die Buchse in die ich das Display 
gesteckt  hatte, hielt nicht richtig und hat nicht alle Kontakte korrekt 
hergestellt.
Jetzt scheint das Display zu laufen :-).
MfG Alex

von Rudolph R. (rudolph)


Angehängte Dateien:

Lesenswert?

Ich spiele gerade mit einem DOGM128 herum.
Das müsste ähnlich genug sein.
Das Display habe ich auf einer Adapter-Platine sitzen die auf meinem 
Controller-Board steckt.

Spannungsteiler an Reset und Select sind nicht so geschickt weil die ja 
low-aktiv sind und somit aktiviert werden, wenn der Controller durch den 
Reset läuft, etwa beim Programmieren.
Das habe ich mit einem digital-Transistor und einem Pullup-Widerstand 
gelöst, dann ist zwar die Polarität für die Software anders herum, macht 
aber nichts.

Ein Teiler 10k/10k macht auch etwas knappe Pegel.
Ich benutze 4k7/6k8, betreibe das Display aber auch "nur" mit 3,0V.

In meinem Aufbau dauert ein Flankenwechsel mit diesen Spannungs-Teilern 
etwa 15 ns mit einem FET als Level-Shifter kam ich nur auf 12 ns runter.

Die wichtigste Erkenntnis bisher war aber, dass der SPI-Takt während der 
Initialisierung maximal 500 kHz betragen darf.
Bei 16 MHz Takt meines AT90CAN32 setze ich vor dem Display-Init SPR1 und 
kann nach dem Init das wieder löschen und somit den SPI mit 4 MHz laufen 
lassen.

Ausserdem setze ich in SPCR noch CPHA und CPOL.

von Thilo M. (Gast)


Lesenswert?

Hi, ich habe hier
Beitrag "Dog-M / ST7036 Routine für 1-Zeiliges Display SPI-Mode"
für die Alphanumerischen Teile einen kleinen Treiber gepostet.
Vielleicht helfen dir die Teile weiter.

von Alex (Gast)


Lesenswert?

@Rudolph R.
Ich erkenne den Nachteil der Spannungsteiler nicht so richtig...
Sobald das Display benutzt wird, Resete ich es ja und beim Schreiben 
nutzte ich CS. Vorher kann an den Pins also passieren was will...
Die Spannungsteiler teilen das Signal auf ca. 2,3V runter... 
funktionieren tut es. Wenn ich mehrere von den Dingern baue, dann nehme 
ich wirklich andere Spannungsteiler, aber für meinen Erstversuch reicht 
es mir ersteinmal.
Mein Prozessor hat einen 16 Mhz Quarz. Zum Testen habe ich SPI mal auf 8 
Mhz gestellt und es funktioniert (auch beim Init).
Wie kommst du darauf, dass man nur 500kHz nutzen sollte?
Das ist mein erstes Projekt wo ich SPI nutze und beim Durchlesen dachte 
ich mir auch ich müsste CPOL & CPHA nutzen, da es hier aber alle ohne 
machen, dachte ich es wäre ohne richtig... Ich habs jetzt wieder rein 
getan :-).

MfG Alex

von Rudolph R. (rudolph)


Lesenswert?

Alex wrote:
> @Rudolph R.
> Ich erkenne den Nachteil der Spannungsteiler nicht so richtig...

Wie gesagt, das trifft nur Select und Reset und ist eher theoretisch.
Zumal die Daten ja nur in Richtung Display gehen.

> Die Spannungsteiler teilen das Signal auf ca. 2,3V runter...

Dann ist Deine Versorgung nicht stabil auf 5V?
Und das meinte ich damit, dass die Pegel etwas schlapp wären.

> funktionieren tut es.

Das habe ich auch nicht bestritten.
Gerade die Kombination mit Reset ist eigentlich wieder gut.

Man kann auf diese Art ja auch andere Komponenten wie SD-Karten 
anschliessen.
Mit einem Spannungs-Teiler auf dem Select sollte man dann aber besser 
keine Karte im Sockel haben, wenn man den Controller programmieren 
möchte.

> Mein Prozessor hat einen 16 Mhz Quarz. Zum Testen habe ich SPI mal auf 8
> Mhz gestellt und es funktioniert (auch beim Init).
> Wie kommst du darauf, dass man nur 500kHz nutzen sollte?

Weil das eben genau die Erfahrung ist die wir mit dem DOGM128S-6 gemacht 
haben.
Hmm, ich habe die Takt-Reduzierung während der Initialisierung gerade 
mal aus meinem Code rausgenommen - läuft doch.
Gleiche Plattform wie vorher allerdings anderer Code, da werde ich dem 
Arbeitskollegen der das zuerst in Betrieb genommen hat wohl mal eine 
EMail schicken müssen, dass er doch nochmal sein Programm prüfen sollte. 
:-)

> Das ist mein erstes Projekt wo ich SPI nutze und beim Durchlesen dachte
> ich mir auch ich müsste CPOL & CPHA nutzen, da es hier aber alle ohne
> machen, dachte ich es wäre ohne richtig... Ich habs jetzt wieder rein
> getan :-).

Mir kommt dieses Setup vor allem entgegen weil der 8-Kanal DAC den ich 
auf dem Board noch drauf habe das auch braucht. :-)

von nixversteh (Gast)


Lesenswert?

> Mir kommt dieses Setup vor allem entgegen weil der 8-Kanal DAC den ich
> auf dem Board noch drauf habe das auch braucht. :-)
Mein PGA2311 und die Schieberegister 74595 auch. :-)

von Rudolph R. (rudolph)


Lesenswert?

Okay, ob das Initialisieren bei 4 MHz klappte oder nicht,
war jetzt in meinem Code von der Optimierungs-Stufe abhängig.

Die Zeit zwischen Reset-loslassen und dem Übertragen der Daten war wohl 
zu knapp, ich verwende im ganzen Code kein einziges delay().
Die Zeile für den Reset habe ich jetzt einfach aus der display_init() 
genommen und in main() vor can_init() gesetzt, das gibt dem Display auch 
ohne delay() genug Zeit aus dem Reset zu kommen.

von Alex (Gast)


Angehängte Dateien:

Lesenswert?

Im Datenblatt steht, dass es ein bisschen Zeit braucht bis man schreiben 
kan (<1ms stand da Wimre). Ich hab jetzt ein 1000µs Delay nach dem Reset 
drinnen. Alle anderen Delays habe ich raus genommen und es läuft noch 
mit 8 Mhz. :)
CS nutze ich weiterhin.


MfG Alex

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.