Moin,
langsam gehen mir die Ideen aus.
Ich habe hier zwei verschiedene PCBs, eins dient als Entwicklungsboard
für die Software, das andere soll die finale Hardware für unser Produkt
werden.
Auf dem Entwicklungsboard sind Display (EA-DOGM128), RS-232 für
Debugging und Taster integriert.
Das finale PCB enthält nur den Controller mit dem üblichen Hühnerfutter
drum herum und gibt die Signale über einen Pfostenstecker an die Platine
in der Frontplatte mit Display und Co weiter.
Für das EA-DOGM128 nutze ich SPI. Auf dem Entwicklungsboard funktioniert
das prima.
Auf dem finalen PCB wird mit der selben Software allerdings (soweit habe
ich den Fehler eingegrenzt) wohl SPIF nicht gesetzt, sodass sich der
Controller im while festfährt. SS habe ich als Ausgang (für CS vom
Display) gesetzt!
Ich habe schon ausgeschlossen, dass die Leiterbahnen für's SPI
untereinander, gg. 5V oder GND kurzgeschlossen sind.
Mir gehen die Ideen aus, wo das Problem liegen könnte... Habe auch schon
den Controller getauscht.
PD5 nutze ich hier zum debuggen (DDRD wird dafür in main() gesetzt):
1 | #define DOGM_SET_DDR() DISPDDR |= (1<<DISPCS)|(1<<DISPRESET)|(1<<DISPA0)
|
2 | #define DOGM_INIT_SPI() SPCR = (1 << SPE) | (1 << MSTR) | (1 << CPOL) | (1 << CPHA);\
|
3 | SPSR = (1 << SPI2X);
|
4 | #define DOGM_SELECT() DISPPORT &= ~(1<<DISPCS)
|
5 | #define DOGM_UNSELECT() DISPPORT |= (1<<DISPCS)
|
6 | #define DOGM_COMMAND() DISPPORT &= ~(1<<DISPA0)
|
7 | #define DOGM_DATA() DISPPORT |= (1<<DISPA0)
|
8 | #define DOGM_RESET() DISPPORT &= ~(1<<DISPRESET)
|
9 | #define DOGM_RUN() DISPPORT |= (1<<DISPRESET); SPSR |= (1 << SPIF)
|
10 |
|
11 | #define DOGM_SPIDR SPDR
|
12 | #define DOGM_BUSY_WAITING() while(!(SPSR & (1<<SPIF)));
|
13 |
|
14 | void dogm_init(void) {
|
15 | DOGM_SET_DDR();
|
16 | dogm_init_spi();
|
17 |
|
18 | // ...
|
19 | }
|
20 |
|
21 | inline void dogm_send(uint8_t byte) {
|
22 |
|
23 | PORTD |= (1 << PD5);
|
24 |
|
25 | uint8_t SPCRbak, SPSRbak;
|
26 | SPCRbak = SPCR;
|
27 | SPSRbak = SPSR;
|
28 |
|
29 | DOGM_INIT_SPI();
|
30 |
|
31 | DOGM_SELECT();
|
32 | DOGM_SPIDR = byte;
|
33 | DOGM_BUSY_WAITING();
|
34 |
|
35 | PORTD &= ~(1 << PD5);
|
36 |
|
37 | DOGM_UNSELECT();
|
38 |
|
39 | // tidy up
|
40 | SPCR = SPCRbak;
|
41 | SPSR = SPSRbak;
|
42 |
|
43 | }
|
44 |
|
45 | void dogm_init_spi(void) {
|
46 | DISPDDR |= (1 << DISPMOSI) | (1 << DISPSCK);
|
47 | }
|
Auf dem Entwicklungsboard wird PD5 kurz gesetzt und dann wieder
zurückgesetzt.
Auf dem finalen PCB bleibt PD5 gesetzt.
Zweiter Versuch, diesmal Rücksetzen vor dem Wait:
1 | inline void dogm_send(uint8_t byte) {
|
2 |
|
3 | PORTD |= (1 << PD5);
|
4 |
|
5 | uint8_t SPCRbak, SPSRbak;
|
6 | SPCRbak = SPCR;
|
7 | SPSRbak = SPSR;
|
8 |
|
9 | DOGM_INIT_SPI();
|
10 |
|
11 | DOGM_SELECT();
|
12 | DOGM_SPIDR = byte;
|
13 |
|
14 | PORTD &= ~(1 << PD5);
|
15 |
|
16 | DOGM_BUSY_WAITING();
|
17 | DOGM_UNSELECT();
|
18 |
|
19 | // tidy up
|
20 | SPCR = SPCRbak;
|
21 | SPSR = SPSRbak;
|
22 |
|
23 | }
|
So sehe ich komischerweise gar keinen Puls an PD5 mehr.
Bilder der PCB-Layouts habe ich angehängt (MCU ist die, die NICHT
funktioniert).
Auf der MCU-Platine mussten wir den Quarz etwas improvisiert auflöten,
er hat aber Takt und ich kann beobachten, dass er nach dem Anlegen der
Spannung kurz normal arbeitet. Daher denke ich nicht, dass ich ein
Problem mit dem Takt habe?.
Ich hoffe auf eure Hilfe, vielleicht habt ihr ja Ideen, oder ein
ähnliches Problem schon mal gelöst.
Viele Grüße :)