Forum: Mikrocontroller und Digitale Elektronik PIC: Schleife für Matrixausgabe mit MAX7219 wird abgebrochen


von Marcel L. (switch)


Lesenswert?

Hallo an alle,

seit einiger Zeit beschäftige ich mich nun mit dem Mikrocontroller 
PIC12F675 und möchte mit dem MAX7219 eine Laufschrift programmieren.

Derzeit habe ich zwei 8x8 Matrix mit je einem MAX7219 an den PIC 
angeschlossen. Einen Standtext anzuzeigen habe ich bereits geschafft. 
Nun soll dieser Text auch von rechts nach links laufen. Dazu habe ich 
als Anfang diesen Code geschrieben. Er soll erst mal nur einen Balken 
von links beginnend nach rechts ziehen (Später dann Buchstaben).
1
/****************** Portbelegung *******************************************************/
2
#define MAX7219DIN              GPIO.F5
3
#define MAX7219LOAD             GPIO.F2
4
#define MAX7219CLK              GPIO.F4
5
6
/****************** Funktionsprototypen ************************************************/
7
// Zwei MAX7219 hintereinander (kaskadiert)
8
void MAX7219_INIT2(char Scanlimit, char ShutdownFormat, char DecodeMode, char Intensity);
9
void MAX7219_KOMMANDO2(char Adr1, char Data1, char Adr2, char Data2);
10
11
// Hilfsunterprogramm
12
void MAX7219_SENDBYTE(char Byte);
13
14
/****************** Controller initialisieren ******************************************/
15
void INIT(void)
16
{
17
    OSCCAL = 0b11111100;
18
19
// Port konfigurieren
20
    TRISIO = 0b00000000;             // Richtungsregister Port (0: Ausgang, 1: Eingang)
21
/*             ++------------------- Bit 7-6 Reserve
22
                 +------------------ Bit 5 Port GP5: hier Ausgang (Takt CLK)
23
                  +----------------- Bit 4 Port GP4: hier Ausgang (Data DIN)
24
                   +---------------- Bit 3 Port GP3: hier unbenutzt
25
                    +--------------- Bit 2 Port GP2: hier Ausgang (LOAD)
26
                     +-------------- Bit 1 Port GP1: hier unbenutzt
27
                      +------------- Bit 0 Port GP0: hier unbenutzt
28
*/
29
}
30
31
//****************** Unterprogramm Daten ********************
32
33
void DATEN(void)
34
{
35
     char D1_W1 = 0;
36
     char D1_W2 = 0;
37
     char D1_W3 = 0;
38
     char D1_W4 = 0;
39
     char D1_W5 = 0;
40
     char D1_W6 = 0;
41
     char D1_W7 = 0;
42
     char D1_W8 = 0;
43
44
     char D2_W1 = 0;
45
     char D2_W2 = 0;
46
     char D2_W3 = 0;
47
     char D2_W4 = 0;
48
     char D2_W5 = 0;
49
     char D2_W6 = 0;
50
     char D2_W7 = 0;
51
     char D2_W8 = 0;
52
53
    char SZ;
54
    for (SZ=17; SZ>0; SZ--)
55
    {
56
57
    // Adressen und Daten an den MAX7219 schicken
58
    MAX7219_KOMMANDO2(0x01, D1_W1, 0x01, D2_W1);
59
    MAX7219_KOMMANDO2(0x02, D1_W2, 0x02, D2_W2);
60
    MAX7219_KOMMANDO2(0x03, D1_W3, 0x03, D2_W3);
61
    MAX7219_KOMMANDO2(0x04, D1_W4, 0x04, D2_W4);
62
    MAX7219_KOMMANDO2(0x05, D1_W5, 0x05, D2_W5);
63
    MAX7219_KOMMANDO2(0x06, D1_W6, 0x06, D2_W6);
64
    MAX7219_KOMMANDO2(0x07, D1_W7, 0x07, D2_W7);
65
    MAX7219_KOMMANDO2(0x08, D1_W8, 0x08, D2_W8);
66
67
    // Kurz warten
68
    Delay_ms(200);
69
70
    // Den Wert 255 eine Spalte weiter nach vorne kopieren.
71
    D2_W1 = D2_W2;
72
    D2_W2 = D2_W3;
73
    D2_W3 = D2_W4;
74
    D2_W4 = D2_W5;
75
    D2_W5 = D2_W6;
76
    D2_W6 = D2_W7;
77
    D2_W7 = D2_W8;
78
    D2_W8 = D1_W1;
79
    D1_W1 = D1_W2;
80
    D1_W2 = D1_W3;
81
    D1_W3 = D1_W4;
82
    D1_W4 = D1_W5;
83
    D1_W5 = D1_W6;
84
    D1_W6 = D1_W7;
85
    D1_W7 = D1_W8;
86
    D1_W8 = 255;
87
    }
88
}
89
90
//***************** Hauptprogramm **************************
91
void main(void)
92
{
93
    INIT();                            // Controller initialisieren
94
95
    MAX7219_INIT2(0x07, 0x01, 0x00, 0x0F); // MAX7219 initialisieren
96
/*                 +------------------------ Scanlimit: 8 Digits
97
             +------------------ Shutdown-Format: Normal Operation
98
             +------------ Decode-Mode: No Decode
99
             +------ Intensity: Volle Helligkeit
100
*/
101
    DATEN();
102
103
    while (1)
104
    {
105
    }
106
}
107
108
/****************** Unterprogramme fuer zwei MAX7219 (Kaskadiert) **********************/
109
110
void MAX7219_INIT2(char Scanlimit, char ShutdownFormat, char DecodeMode, char Intensity)
111
{
112
    // Scanlimit an beide MAX7219 senden
113
    MAX7219_KOMMANDO2(0x0b, Scanlimit, 0x0b, Scanlimit);
114
115
    // Shutdown-Format an beide MAX7219 senden
116
    MAX7219_KOMMANDO2(0x0c, ShutdownFormat, 0x0c, ShutdownFormat);
117
118
      // Decode-Mode an beide MAX7219 senden
119
    MAX7219_KOMMANDO2(0x09, DecodeMode, 0x09, DecodeMode);
120
121
      // Intensity an beide MAX7219 senden
122
    MAX7219_KOMMANDO2(0x0a, Intensity, 0x0a, Intensity);
123
}
124
125
//-------------------------------------------------------------
126
127
void MAX7219_KOMMANDO2(char Adr1, char Data1, char Adr2, char Data2)
128
{
129
    // Schritt 1: Steuerleitung LOAD loeschen
130
       MAX7219LOAD = 0;
131
132
  // Schritt 2: Die Adresse des ersten MAX7219 bitweise senden
133
    MAX7219_SENDBYTE(Adr1);
134
135
    // Schritt 3: Die Daten des ersten MAX7219 bitweise senden
136
    MAX7219_SENDBYTE(Data1);
137
138
    // Schritt 4: Die Adresse des zweiten MAX7219 bitweise senden
139
    MAX7219_SENDBYTE(Adr2);
140
141
    // Schritt 5: Die Daten des zweiten MAX7219 bitweise senden
142
    MAX7219_SENDBYTE(Data2);
143
144
    // Schritt 6: Steuerleitung LOAD setzen und ein positive Taktflanke erzeugen
145
       MAX7219LOAD = 1;
146
       MAX7219CLK = 1;
147
}
148
149
/****************** Hilfsunterprogramm *************************************************/
150
151
void MAX7219_SENDBYTE(char Byte)
152
{
153
    char i;
154
155
156
  for (i=8; i>0; i--)
157
  {
158
    // MSB ausgeben
159
        MAX7219DIN = Byte.F7;
160
161
    // Takt erzeugen
162
    MAX7219CLK = 1;
163
      MAX7219CLK = 0;
164
165
      // Bits verschieben (Bit 6 -> Bit 7, Bit 5 -> Bit 6 usw.)
166
    Byte = Byte << 1;
167
    }
168
}

Den Code habe ich dem Programm MicroC geschrieben, deswegen fehlt hier 
auch die __config-Einstellungen, da die direkt im Programm eingestellt 
werden. Ich verwende den internen 4 MHz Oszillator.

Zum Programm:
Nachdem die Einstellungen für den PIC und die MAX7219 (Unterprogramme 
INIT und MAX7219_INIT2) übertragen sind (Zusammen mit den 
Unterprogrammen MAX7219_KOMMANDO2 und MAX7219_SENDBYTE), soll mit dem 
Unterprogramm DATEN der Balken angezeigt werden.
Dazu werden erst alle Variablen auf 0 gesetzt und gesendet. Anschließend 
werden alle Werte um eine Spalte auf der Matrix nach links verschoben. 
Dann wird auch die Variable D1_W8 mit dem Wert 255 (alle 8 LEDs der 
Spalten an) geladen und erneut gesendet. Das soll durch die Schleife 
17mal gehen, bis alle LEDs der beiden Matrix leuchten (Der Wert 255 wird 
immer kopiert.).

Problem ist jetzt, sobald ich als Zeitverzögerung den Wert 300 oder mehr 
eingebe, beginnt der Balken zu laufen und bricht nach der 10. Spalte 
oder schon früher ab und beginnt von vorne. Gebe ich den Wert 200 ein, 
läuft der Balken bis zur letzten Spalte, wird aber dann auch wieder 
gelöscht und beginnt von vorne. Eigentlich sollte er nach den 17mal doch 
die Schleife verlassen und im Hauptprogramm in der Dauerschleife 
bleiben,also alle LEDs eingeschaltet lassen, oder?

Ich hoffe, ihr könnt mir dieses komische Verhalten erklären.
Danke im Vorraus!
switch

von Dieter W. (dds5)


Lesenswert?

Das klingt irgendwie nach Reset durch den Watchdog.

von X4U (Gast)


Lesenswert?

Marcel L. schrieb:
> Problem ist jetzt, sobald ich als Zeitverzögerung den Wert 300 oder mehr
> eingebe, beginnt der Balken zu laufen und bricht nach der 10. Spalte
> oder schon früher ab und beginnt von vorne.

Das riecht nach overflow. MikroC hat einen sehr guten Simulator. Lass es 
doch erst mal damit laufen und schau die deine chars damit an.

Schlage auch vor aus char SZ unsigned short zu machen da als Zähler 
genutzt.

Den Takt (clock) würde ich dann noch eine Verzögerung spendieren oder 
die LAT Register nehmen (wenn vorhanden). Evtl greift das Read_Modify 
Write Problem (s. Hilfe von MikroC).

von Marcel L. (switch)


Lesenswert?

Danke für die schnellen Antworten.

Bei mir war in der config der Watchdogtimer aktiviert und er hat mein 
Programm dauernd unterbrochen. Mit deaktivierten WDT läuft das Programm 
jetzt ohne Probleme durch.

Danke nochmal für diesen guten Hinweis!!!!

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.