Forum: Mikrocontroller und Digitale Elektronik Nach 8 kommt 19 und danach 10 - 7 Seg Uhr mit MAX7219


von BeastyK (Gast)


Lesenswert?

Moin Leute,

ich hab hier ein Problem mit PIC18F4455, MAX7219 mit 8Digit 
7Segment-Modul.
Mir scheint das die Zählroutine etwas buggy ist, er zählt von 0 bis 8 
ganz normal und anstatt 9 zeigt er mir 19 an und danach kommt die 10.
Das funktioniert nicht nur bei den Sekunden sondern auch bei den Minuten 
so.
Ich häng mal die Main mit ran:
1
/*
2
 * File:   main7219.c
3
 * Author: BeastyK
4
 *
5
 * Created on 9. Oktober 2016, 17:54
6
 */
7
8
9
#include <xc.h>
10
#include <delays.h>
11
#include <spi.h>
12
#include <timers.h>
13
#include <stdio.h>
14
#include <stdlib.h>
15
#include "m7219.h"
16
17
#define _XTAL_FREQ 20000000
18
19
void Timer1Init();
20
void interrupt_isr(void);
21
//void max7219_time_write(unsigned int std, unsigned int min, unsigned int sek);
22
23
/*****************************************************************************/  
24
/** C O N F I G U R A T I O N ************************************************/
25
/*****************************************************************************/
26
27
28
// PIC18F4455 Configuration Bit Settings
29
30
// 'C' source line config statements
31
32
// CONFIG1L
33
#pragma config PLLDIV = 5       // PLL Prescaler Selection bits (Divide by 5 (20 MHz oscillator input))
34
#pragma config CPUDIV = OSC1_PLL2// System Clock Postscaler Selection bits ([Primary Oscillator Src: /1][96 MHz PLL Src: /2])
35
#pragma config USBDIV = 2       // USB Clock Selection bit (used in Full-Speed USB mode only; UCFG:FSEN = 1) (USB clock source comes from the 96 MHz PLL divided by 2)
36
37
// CONFIG1H
38
#pragma config FOSC = HSPLL_HS  // Oscillator Selection bits (HS oscillator, PLL enabled (HSPLL))
39
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor disabled)
40
#pragma config IESO = OFF       // Internal/External Oscillator Switchover bit (Oscillator Switchover mode disabled)
41
42
// CONFIG2L
43
#pragma config PWRT = OFF       // Power-up Timer Enable bit (PWRT disabled)
44
#pragma config BOR = ON         // Brown-out Reset Enable bits (Brown-out Reset enabled in hardware only (SBOREN is disabled))
45
#pragma config BORV = 3         // Brown-out Reset Voltage bits (Minimum setting 2.05V)
46
#pragma config VREGEN = ON      // USB Voltage Regulator Enable bit (USB voltage regulator enabled)
47
48
// CONFIG2H
49
#pragma config WDT = OFF        // Watchdog Timer Enable bit (WDT disabled (control is placed on the SWDTEN bit))
50
#pragma config WDTPS = 32768    // Watchdog Timer Postscale Select bits (1:32768)
51
52
// CONFIG3H
53
#pragma config CCP2MX = ON      // CCP2 MUX bit (CCP2 input/output is multiplexed with RC1)
54
#pragma config PBADEN = OFF     // PORTB A/D Enable bit (PORTB<4:0> pins are configured as digital I/O on Reset)
55
#pragma config LPT1OSC = OFF    // Low-Power Timer 1 Oscillator Enable bit (Timer1 configured for higher power operation)
56
#pragma config MCLRE = ON       // MCLR Pin Enable bit (MCLR pin enabled; RE3 input pin disabled)
57
58
// CONFIG4L
59
#pragma config STVREN = ON      // Stack Full/Underflow Reset Enable bit (Stack full/underflow will cause Reset)
60
#pragma config LVP = OFF        // Single-Supply ICSP Enable bit (Single-Supply ICSP disabled)
61
#pragma config ICPRT = OFF      // Dedicated In-Circuit Debug/Programming Port (ICPORT) Enable bit (ICPORT disabled)
62
#pragma config XINST = OFF      // Extended Instruction Set Enable bit (Instruction set extension and Indexed Addressing mode disabled (Legacy mode))
63
64
// CONFIG5L
65
#pragma config CP0 = OFF        // Code Protection bit (Block 0 (000800-001FFFh) is not code-protected)
66
#pragma config CP1 = OFF        // Code Protection bit (Block 1 (002000-003FFFh) is not code-protected)
67
#pragma config CP2 = OFF        // Code Protection bit (Block 2 (004000-005FFFh) is not code-protected)
68
69
// CONFIG5H
70
#pragma config CPB = OFF        // Boot Block Code Protection bit (Boot block (000000-0007FFh) is not code-protected)
71
#pragma config CPD = OFF        // Data EEPROM Code Protection bit (Data EEPROM is not code-protected)
72
73
// CONFIG6L
74
#pragma config WRT0 = OFF       // Write Protection bit (Block 0 (000800-001FFFh) is not write-protected)
75
#pragma config WRT1 = OFF       // Write Protection bit (Block 1 (002000-003FFFh) is not write-protected)
76
#pragma config WRT2 = OFF       // Write Protection bit (Block 2 (004000-005FFFh) is not write-protected)
77
78
// CONFIG6H
79
#pragma config WRTC = OFF       // Configuration Register Write Protection bit (Configuration registers (300000-3000FFh) are not write-protected)
80
#pragma config WRTB = OFF       // Boot Block Write Protection bit (Boot block (000000-0007FFh) is not write-protected)
81
#pragma config WRTD = OFF       // Data EEPROM Write Protection bit (Data EEPROM is not write-protected)
82
83
// CONFIG7L
84
#pragma config EBTR0 = OFF      // Table Read Protection bit (Block 0 (000800-001FFFh) is not protected from table reads executed in other blocks)
85
#pragma config EBTR1 = OFF      // Table Read Protection bit (Block 1 (002000-003FFFh) is not protected from table reads executed in other blocks)
86
#pragma config EBTR2 = OFF      // Table Read Protection bit (Block 2 (004000-005FFFh) is not protected from table reads executed in other blocks)
87
88
// CONFIG7H
89
#pragma config EBTRB = OFF      // Boot Block Table Read Protection bit (Boot block (000000-0007FFh) is not protected from table reads executed in other blocks)
90
91
// #pragma config statements should precede project file includes.
92
// Use project enums instead of #define for ON and OFF.
93
94
/*****************************************************************************/
95
/**** M A I N  P R O G R A M  ************************************************/
96
/*****************************************************************************/
97
98
unsigned char i;
99
unsigned int second = 0, minute = 0, hour = 0;
100
101
void Timer1Init() {
102
103
    //Timer1 ist ein 16bit Timer (FFFFh oder 65535) mit jeweils 8bit Timer High 
104
    //und 8bit Timer Low mit externen Uhrenquarz von 32768Hz wird der Interrupt nach
105
    //2 Sekunden gesetzt, daher wird TMR1H auf 80h gesetzt (8000h ist der gesamte 
106
    //Timer1 aus TMR1H und TMR1L und entspricht 32768)
107
TMR1H = 0x80;                //setzt Msb des oberen 8bit des Timer1 auf 1     
108
TMR1L = 0;                //setzt die unteren 8bit des Timers1 auf Null
109
  TRISCbits.TRISC0 = 1;       //setzt TRISC0 auf Eingang (warum aber nicht TRISC1?)
110
  LATBbits.LATB6 = 1;        //setzt den PM-Zeit bit
111
  T1CON = 0b00001111;           // 2x8bit, externer Takt, Osc enabled, asynch, start!
112
    PIE1bits.TMR1IE = 1;
113
    INTCONbits.PEIE = 1;
114
    //RCONbits.IPEN=0x01;
115
    //IPR1bits.TMR1IP=0x01;            // TMR1 high priority ,TMR1 Overflow Interrupt Priority bit
116
    INTCONbits.GIE = 1;
117
    PIR1bits.TMR1IF = 0;        //setzt den Timerinterrupt von Timer1 auf Null
118
}
119
120
void interrupt  isr(void)
121
{
122
//TMR1H |= 0x80;
123
  if (PIR1bits.TMR1IF) 
124
  {
125
    unsigned int d = 0, e = 0, f = 0, std = 0, min = 0, sek = 0;
126
        second++;
127
  //  max7219new++;
128
    TMR1H = 0x70;    
129
    //PIR1bits.TMR1IF = 0;    //TMR1IF überlauf muß per software zurückgesetzt werden (Datenblatt Seite 102)
130
    
131
   
132
    if (second >= 60)     //ist second gleich oder größer 60 dann
133
      {
134
        minute++;      //Variable minute um 1 erhöhen (60 Sekunden sind eine Minute)
135
          second = 0;      //die Variable second beim Timerinterrupt wieder von 0 anfangen lassen zu zählen
136
      }
137
138
  if (minute >= 60)    //ist minute gleich oder größer 60 dann
139
      {
140
        hour++;        //Variable hour um 1 erhöhen (60 Minuten sind eine Stunde)
141
          minute = 0;      //die Variable minute wieder auf 0 setzen damit eine neue Minute gezählt wird
142
      }
143
  if (hour >= 24)
144
      {
145
        hour = 0;
146
      }
147
  
148
    //if (max7219new >= 1)
149
  //    {
150
  //      max7219_time_write(hour, minute, second);
151
  //      max7219new = 0;
152
  //    }
153
  //d = hour / 10;
154
  //std = hour - (d * 10);
155
  //max7219_digitwrite(3, d);
156
  //max7219_digitwrite(4, std);
157
  //e = minute / 10;
158
  //min = minute - (e * 10);
159
  //max7219_digitwrite(5, e);
160
  //max7219_digitwrite(6, min);
161
  f = second / 10;
162
  sek = second - (f * 10);
163
  max7219_digitwrite(7, f);
164
  max7219_digitwrite(8, sek);
165
    
166
    PIR1bits.TMR1IF = 0;    //TMR1IF überlauf muß per software zurückgesetzt werden (Datenblatt Seite 102)
167
  }
168
}
169
170
/*void max7219_time_write(unsigned int std, unsigned int min, unsigned int sek)
171
{
172
  unsigned int d = 0, e = 0, f = 0;
173
  
174
  d = std / 10;
175
  std = std - (d * 10);
176
  max7219_digitwrite(3, d);
177
  max7219_digitwrite(4, std);
178
  e = min / 10;
179
  min = min - (e * 10);
180
  max7219_digitwrite(5, e);
181
  max7219_digitwrite(6, min);
182
  f = sek / 10;
183
  sek = sek - (f * 10);
184
  max7219_digitwrite(7, f);
185
  max7219_digitwrite(8, sek);
186
    
187
  
188
}
189
*/
190
void main(void)
191
{
192
  __delay_ms(25);  //Delay of 100ms
193
  __delay_ms(25);
194
  __delay_ms(25);  
195
  __delay_ms(25);
196
  OpenSPI(SPI_FOSC_16, MODE_00, SMPMID);  // MODE besteht aus CKP/CKE, ist CKP gleich 1, SCK sendet nicht bei hohen Pegel oder CKP ist 0, SCK
197
                      //sendet nicht bei niedrigen Pegel.           
198
  __delay_ms(25);  //Delay of 100ms
199
  __delay_ms(25);
200
  __delay_ms(25);  //Delay of 100ms
201
  __delay_ms(25);
202
                       
203
  TRISC &= 0xFB;    // 1111 1011
204
  TRISD = 0xF0;      // 1111 0000  
205
  LATDbits.LATD0 = 1; //Set D0 high  
206
  __delay_ms(25);  //Delay of 100ms
207
  __delay_ms(25);
208
  __delay_ms(25);  //Delay of 100ms
209
  __delay_ms(25);
210
  max7219_init();
211
  __delay_ms(25);  //Delay of 100ms
212
  __delay_ms(25);
213
  __delay_ms(25);  //Delay of 100ms
214
  __delay_ms(25);
215
  Timer1Init();
216
  __delay_ms(25);  //Delay of 100ms
217
  __delay_ms(25);
218
  __delay_ms(25);  //Delay of 100ms
219
  __delay_ms(25);
220
  
221
while(1)
222
  {
223
224
  } 
225
}

Vieles ist auskommentiert und dann in die ISR gerutscht, zuletzt hab ich 
mich nur noch auf die Sekunden konzentriert.
Die MAX7219 sieht dabei so aus:
1
//MAX 7219 chip_util Library
2
#include <p18f4455.h>
3
#include <spi.h>
4
5
#define SELMAX      PORTCbits.RC2 = 1;
6
#define DESELMAX    PORTCbits.RC2 = 0;
7
8
void max7219_init() {
9
10
  SELMAX;           // SELECT MAX
11
  WriteSPI(0x09);         // BCD mode for digit decoding
12
  WriteSPI(0xFF);
13
  DESELMAX;              // DESELECT MAX
14
15
  SELMAX;           // SELECT MAX
16
  WriteSPI(0x0A);
17
  WriteSPI(0x0F);         // Segment luminosity intensity
18
  DESELMAX;              // DESELECT MAX
19
20
  SELMAX;           // SELECT MAX
21
  WriteSPI(0x0B);
22
  WriteSPI(0x07);
23
 // WriteSPI(x-1);         // Set how many digits mit max7219_init(int x)
24
  DESELMAX;              // DESELECT MAX
25
26
  SELMAX;           // SELECT MAX
27
  WriteSPI(0x0C);
28
  WriteSPI(0x01);         // Turn on the display
29
  DESELMAX;              // DESELECT MAX
30
31
  SELMAX;           // SELECT MAX
32
  WriteSPI(0x00);
33
  WriteSPI(0xFF);         // No test
34
  DESELMAX;              // DESELECT MAX
35
}
36
37
void max7219_clear(int x) {
38
39
unsigned char ii;
40
41
  for (ii = 1; ii<=x; ii++)
42
  {
43
    SELMAX;          // select max7219
44
    WriteSPI(ii);           // send i to max7219 (digit place)
45
    WriteSPI(0);         // send i to max7219 (digit)
46
    DESELMAX;             // deselect max7219
47
  }
48
}
49
50
void max7219_digitwrite(int x, int y) {
51
52
    SELMAX;          // select max7219
53
    WriteSPI(x);           // send i to max7219 (digit place)
54
    WriteSPI(y);         // send i to max7219 (digit)
55
    DESELMAX;             // deselect 
56
    return;
57
}
58
59
void max7219_write(unsigned int value) {
60
61
unsigned int d;
62
63
    d = value / 10000;
64
    value=value-(d*10000);
65
    max7219_digitwrite(5,d);
66
    d = value / 1000;
67
    value=value-(d*1000);
68
    max7219_digitwrite(4,128+d);
69
    d = value / 100;
70
    value=value-(d*100);
71
    max7219_digitwrite(3,d);
72
    d = value / 10;
73
    value=value-(d*10);
74
    max7219_digitwrite(2,d);
75
    max7219_digitwrite(1,value);
76
77
}

Wenn jemand hier weiter weiß, bin da ganz offen :)

MfG
BeastyK

von A. S. (Gast)


Lesenswert?

Nur zum Verständnis:

Es läuft von [00] bis [59] richtig,
mit Ausnahme [09] was als [19] ausgeben wird?
Und nach [59] gehts mit [00] weiter?

Und es zählt im Sekundentakt (kein Verschlucken/Verzögern)?

Die SPI-Routinen laufen in der ISR, also ohne eigene Interrupts?

Und bei der Inbetriebnahme konntest Du erfolgreich 09 direkt im Main 
ausgeben (ohne Interrupts, ohne weitere Anzeigen)?

von Klaus (Gast)


Lesenswert?

Schon mal mit dem Debugger versucht? Da sollte man doch leicht 
rausfinden, was da abgeht.

MfG Klaus

von int (Gast)


Lesenswert?

>unsigned int d = 0, e = 0, f = 0,

Die Definition paßt ja nicht so ganz zu der Berechnung:

>f = second / 10;

Das solltes Du nochmals überdenken. Oder Copy und Paste besser benutzen.

von Peter D. (peda)



Lesenswert?

BeastyK schrieb:
> Ich häng mal die Main mit ran:

Lesen kannst Du aber schon?
Siehe Anhang!

von KingJulian (Gast)


Lesenswert?

1
  f = second / 10;
2
  sek = second - (f * 10);

Weiss nicht ob gewollt oder nicht, aber
1
sek
 ist hier immer 0

von JensM (Gast)


Lesenswert?

@KingJulian

Schnell aber falsch.

Datentypen von second, f und sek ist unsigned int

second = 52;

f = second / 10;
-> f = 5

 sek = second - (f * 10);

-> sek = 52 - (5 * 10)
-> sek = 52 - 50
-> sek = 2

das war wohl so gedacht

Gruß JensM

von Norbert (Gast)


Lesenswert?

KingJulian schrieb:
>
1
  f = second / 10;
2
>   sek = second - (f * 10);
>
> Weiss nicht ob gewollt oder nicht, aber
1
sek
 > ist hier immer 0

Wie kommst du denn darauf?
'f' ist ein integer!

von MaWin (Gast)


Lesenswert?

KingJulian schrieb:
> Weiss nicht ob gewollt oder nicht,
> aber sek ist hier immer 0

Warum sollte es? Kann es sein, dass dir die Grundlagenkenntnisse im 
Programmieren fehlen?

von BeastyK (Gast)


Lesenswert?

Moin Leute,

ich fang mal mit beantworten an, entschuldigt für das späte 
aufstehen...ich hatte ne unangenehme Nacht.
Ich fang mal mit dem Chef an!

Peter D. schrieb:
> Lesen kannst Du aber schon?

Moin Peter, ich halte mich natürlich an die Boardregeln, in dem Fall 
dachte ich mir das der Code nicht wirklich lang ist und ich ihn noch so 
posten kann.
Wahrscheinlich habe ich "lang" falsch definiert, sorry!

So, weiter:

Achim S. schrieb:
> Es läuft von [00] bis [59] richtig,
> mit Ausnahme [09] was als [19] ausgeben wird?
> Und nach [59] gehts mit [00] weiter?

Hallo Achim, die Frage ist gut, das hab ich nicht gut genug erklärt:
Er hat das immer wenn er hinten eine 9 hat, also bei 09 zeigt er 19, bei 
19 zeigt er 29 usw. bis er bei 59 die Minute und dann dahinter 09 
anzeigt. Nach 109 geht es dann mit 100 weiter.

Achim S. schrieb:
> Und es zählt im Sekundentakt (kein Verschlucken/Verzögern)?

Naja, ich bin der Meinung er steht etwas länger bei der 0 am Anfang, er 
sollte im Sekundentakt zählen. Manchmal kommt es mir auch vor als würde 
er etwas haken, nachgemessen hab ich das noch nicht.
Den TMR1H hab ich zum testen auch mal mit 0xC0 gefüttert, dann läuft er 
schneller über.
Interessant ist aber das ich wegen der Verzögerung am Anfang dachte das 
vielleicht second schon weiter ist und die Ausgabe auf dem 7Segment 
Display noch hängt und hab deshalb einfach mal folgendes geändert:
1
f = second / 10;
wurde zu
1
f = (second - 1) / 10;

Eine Verzweiflungstat, die aber dazu führte das er von 01 bis 09 zählte 
und dann bei der 10 einfach 1- ausgegeben hat.
Dito bei den anderen Zahlen mit 9 am Ende!

Achim S. schrieb:
> Die SPI-Routinen laufen in der ISR, also ohne eigene Interrupts?

Die SPI.h Headerdatei ist mit eingebunden, da hab ich dann nicht so 
genau draufgeschaut.

Klaus schrieb:
> Schon mal mit dem Debugger versucht? Da sollte man doch leicht
> rausfinden, was da abgeht.

Hab ich schon probiert, mit dem debuggen bei MPLABX hab ich etwas 
Probleme, ich weiß nicht wie ich die Variablen in die Watchliste 
bekomme. Bei Proteus läuft das besser, was ich gesehen hab ist das er 
bei second = 09 noch minute = 0 hat. Leider läßt sich das Display beim 
steppen nicht beobachten wegen dem multiplexen.

int schrieb:
>>unsigned int d = 0, e = 0, f = 0,
>
> Die Definition paßt ja nicht so ganz zu der Berechnung:
>
>>f = second / 10;
>
> Das solltes Du nochmals überdenken.

Ich hatte wirklich schon in betracht gezogen das er 9/10 einfach 
aufrundet.
Dann hab ich das aber schnell wieder als unsinnig abgetan.

JensM schrieb:
> Datentypen von second, f und sek ist unsigned int
>
> second = 52;
>
> f = second / 10;
> -> f = 5
>
>  sek = second - (f * 10);
>
> -> sek = 52 - (5 * 10)
> -> sek = 52 - 50
> -> sek = 2
>
> das war wohl so gedacht

Exakt so ist das gedacht!

Bin aber froh das ihr euch an dem Post so gut beteiligt, ich weiß da im 
Moment einfach nicht mehr weiter!

MfG
Beast

von Wegstaben V. (wegstabenverbuchsler)


Lesenswert?

MaWin schrieb:
> dass dir die Grundlagenkenntnisse im
> Programmieren fehlen?

manchmal ist es hilfreich, Variablen aussagefähig zu benennen. Schon 
liest sich das viel geschmeidiger.


zum Beispiel anstelle von
f = second / 10;
sek = second - (f * 10);

-->

ZehnerSekunde = second / 10;
EinerSekunde  = second - (ZehnerSekunde * 10);

von Klaus (Gast)


Lesenswert?

BeastyK schrieb:
> Bin aber froh das ihr euch an dem Post so gut beteiligt, ich weiß da im
> Moment einfach nicht mehr weiter!

Vielleicht doch mal den Debugger bemühen? Breakpoint setzen, 
durchsteppen und sehen was passiert. Macht viel weniger Arbeit als 
dauernd zu posten.

MfG Klaus

von BeastyK (Gast)


Lesenswert?

Wegstaben V. schrieb:
> manchmal ist es hilfreich, Variablen aussagefähig zu benennen. Schon
> liest sich das viel geschmeidiger.

Moin Wegstaben Verbuchsler,

für den Informatikunterricht an Schulen geb ich dir da total recht.

Die Zerlegung einer Zahl findet sich so aber auch in der max7219.h Datei 
wieder, dort wurde das für eine 5 stellige Zahl durchgenommen, siehe

void max7219_write(unsigned int value)

MaWin hat das in seinem Post nur auf seine Art gesagt, übrigens: Moin 
MaWin!

Gruss
Beast

von BeastyK (Gast)


Lesenswert?

Klaus schrieb:
> Vielleicht doch mal den Debugger bemühen? Breakpoint setzen,
> durchsteppen und sehen was passiert. Macht viel weniger Arbeit als
> dauernd zu posten.

Ich les mich noch etwas ins debuggen ein und werds mal 
probieren...darfst nir aber gern weiterhelfen!

von Eric B. (beric)


Lesenswert?

BeastyK schrieb:
> unsigned int second = 0, minute = 0, hour = 0;

Die werden im Interruptroutine geändert --> volatile!

BeastyK schrieb:
> f = second / 10;
>   sek = second - (f * 10);
>   max7219_digitwrite(7, f);
>   max7219_digitwrite(8, sek);

Der Abschnitt an sich ist schon ok. Der Fehler muss woanders sitzen.
Wobei ich persönlich das anders aufsetzen würde und einfach jedes 
Zeichen eine eigene Zähler verpassen würde. Und die Ausgabe in die 
main-loop.

Etwa so:
1
volatile uint8_t hour10, hout1, min10, min1, sec10, sec1;
2
volatile bool_t tick = FALSE;
3
4
void interrupt isr(void)
5
{
6
  sec1 ++;
7
8
  if (sec1  == 10) { sec1  = 0; sec10  ++; }
9
  if (sec10 ==  6) { sec10 = 0; min1   ++; }
10
  if (min1  == 10) { min1  = 0; min10  ++; }
11
  if (min10 ==  6) { min10 = 0; hour1  ++; }
12
  if (hour1 == 10) { hour1 = 0; hour10 ++; }
13
14
  if ((hour10 == 2) && (hour1 == 4)) { hour10 = 0; hour1 = 0; }
15
16
  tick = TRUE; // notify main loop
17
}
18
19
void main()
20
{
21
  // init stuff here 
22
23
  for(;;)
24
  {
25
    if (tick) // notification from ISR
26
    {
27
       tick = FALSE;
28
       
29
       max7219_digitwrite(1,hour10);
30
       max7219_digitwrite(2,hour1);
31
       max7219_digitwrite(3,min10);
32
       max7219_digitwrite(4,min1);
33
       max7219_digitwrite(5,sec10);
34
       max7219_digitwrite(6,sec1);
35
    }
36
  }
37
}

von Programmierer (Gast)


Lesenswert?

BeastyK schrieb:
> für den Informatikunterricht an Schulen geb ich dir da total recht

Für den normalen Programmieralltag gilt das auch.
Ein langer Variablenname kosten zwar im Quellcode einige Bytes, macht 
das fertige Programm aber nicht länger.

von Harald (Gast)


Lesenswert?

Ich verweise mal wider auf die geniale Software "Sigrok", da kann man 
den Output zum 7219 dekodiert anschauen und so meist sehr schnell den 
Fehler lokalisieren. Die Hardware kostet in Form eines "Saleae Clone" 
weniger als 10€.

von Harald (Gast)


Lesenswert?

wider = wieder

von Klaus (Gast)


Lesenswert?

BeastyK schrieb:
> Ich les mich noch etwas ins debuggen ein und werds mal
> probieren...darfst nir aber gern weiterhelfen!

Und solange läßt du andere deinen Code für dich debuggen. Prima Sache, 
braucht man selbst nicht soviel lesen und nutzt die eigenen Augen nicht 
so ab.

MfG Klaus

von BeastyK (Gast)


Lesenswert?

Klaus schrieb:
> Und solange läßt du andere deinen Code für dich debuggen. Prima Sache,
> braucht man selbst nicht soviel lesen und nutzt die eigenen Augen nicht
> so ab.

Du hast mich durchschaut, Klaus!
Gerade bei dir hab ich darauf gewartet.
Nun bin ich enttäuscht.
Kennst du eine Seite bei der das mit der Watchliste und den nicht 
globalisierten Variablen in einem Tutorial gezeigt wird?

Gruss
Beast

von Klaus (Gast)


Lesenswert?

BeastyK schrieb:
> Nun bin ich enttäuscht.

Das bringt mein Karma wieder ins Reine. Bin heut nämlich schon gelobt 
worden.

Aber BTT, mal die Maus über eine Variable bewegen, wenn der Pic 
angehalten ist. Locale Variable werden IMHO aber auch automatisch im 
Variablenfenster angezeigt.

Ich kenne keine Tutorials, ich lese Texte, zur Not ganze Bücher. Machmal 
steht auch was in der Onlinehilfe.

MfG Klaus

von A. S. (Gast)


Lesenswert?

Halte mich für blöd, aber drehe die Zeilen mal um. Also statt

>max7219_digitwrite(7, f);
>max7219_digitwrite(8, sek);

nun
1
max7219_digitwrite(8, sek);
2
max7219_digitwrite(7, f);

Wenn es sich dann noch immer genauso verhält, fresse ich einen Besen.

sonst sehe ich (ohne debugger) Erkenntnis nur noch darin, die 
original-Zeilen mal mit festen Zahlen laufen zu lassen, egal ob in der 
Interrupt-Routine oder stattdessen (also nur einmal in main). Also:
1
max7219_digitwrite(7, 9);
2
max7219_digitwrite(8, 0);

von BeastyK (Gast)


Lesenswert?

Klaus schrieb:
> Aber BTT, mal die Maus über eine Variable bewegen, wenn der Pic
> angehalten ist. Locale Variable werden IMHO aber auch automatisch im
> Variablenfenster angezeigt.

Guck an, das mit dem Mauszeiger wußte ich nicht, danke!
Mhhh, sollte mal "Mieses Karma" lesen...türlich auch mehr von den 
Microchip Notes :b

Achim, das mit dem tauschen, Naja, versuch ich auch mal...feste Zahlen 
nehmen hatte ich auch schon vor, dann könnte man feststellen ob die 
Ausgabe an den Max7219 so richtig ist, spi zb.

MfG
Beast

von BeastyK (Gast)


Lesenswert?

Achim S. schrieb:
> Wenn es sich dann noch immer genauso verhält, fresse ich einen Besen.

Du bekommst doch meinen einzigen Besen nicht als Mahlzeit, gib her 
...so!

Danke Achim, du hast mich in die richtige Richtung geschubst mit dem 
drehen der beiden Zeilen!
Ich weiß gerade nicht mehr ob es dann ganz und gar funktionierte, es hat 
mich aber auf die Idee gebracht in der MAX7219 Headerdatei mit dem CS 
Pin zu spielen. Ich fügte hinten in der void (max7219_digitwrite) 
nochmals selmax und deselmax ein und es funktionierte.
Heute morgen hab ich das MAX7219 Datenblatt konsultiert, ich zitiere 
mal...

Aus MAX7219 Datenblatt:
"For the MAX7221, CS must be low to clock data
in or out. The data is then latched into either the digit or
control registers on the rising edge of LOAD/CS.
LOAD/CS must go high concurrently with or after the
16th rising clock edge, but before the next rising clock
edge or data will be lost."

Soso, CS muß also low (0) sein wenn ich ihm über SPI die 2x 8bit Daten 
rüberschiebe, dann wieder high (1). Das deckt sich ja mal garnicht so 
mit dem was ich da fabriziert hab:

BeastyK schrieb:
> #define SELMAX      PORTCbits.RC2 = 1;
> #define DESELMAX    PORTCbits.RC2 = 0;

das drehen wir schnell mal um in
1
#define SELMAX      PORTCbits.RC2 = 0;
2
#define DESELMAX    PORTCbits.RC2 = 1;

und setzen in der main.c noch ein
1
LATCbits.LATC2 = 1;
 zwischen den Zeilen

BeastyK schrieb:
> TRISC &= 0xFB;    // 1111 1011
>   TRISD = 0xF0;      // 1111 0000

und nun läuft die Anzeige und zählt korrekt.
Mhhhh, leider hab ich noch eine Arbeitnehmer freundliche Variante meiner 
Uhr, sie schafft es das die Minute um die 10 Sekunden schneller um ist.

MfG
Beast

von Peter D. (peda)


Lesenswert?

BeastyK schrieb:
> das drehen wir schnell mal um in
> #define SELMAX      PORTCbits.RC2 = 0;
> #define DESELMAX    PORTCbits.RC2 = 1;

Und wenn Du den Code angehangen hättest, wär das garantiert schon viel 
früher aufgefallen.
So wurde es durch das ständige hin und her scrollen einfach überlesen.

Kleine 20-Zeiler kann man einfügen, alles größere schaut sich erheblich 
besser in einem Editor an.

von A. S. (Gast)


Lesenswert?

BeastyK schrieb:
> Du bekommst doch meinen einzigen Besen nicht

Uups ... Halloween steht vor der tür

von BeastyK (Gast)


Lesenswert?

Peter D. schrieb:
> Und wenn Du den Code angehangen hättest, wär das garantiert schon viel
> früher aufgefallen.
> So wurde es durch das ständige hin und her scrollen einfach überlesen.
>
> Kleine 20-Zeiler kann man einfügen, alles größere schaut sich erheblich
> besser in einem Editor an.

Moin Peter,
ich zieh mal aus dem Post den Schluss das alles über 20 Zeilen als lang 
gilt.
Das werde ich mir für andere Beiträge merken und beherzigen!

Achim S. schrieb:
> Uups ... Halloween steht vor der tür

Oha, jaaa, dann wird der Besen noch viel unverzichtbarer ;)
Wie bist du eigentlich auf die Idee mit dem Zeilentausch gekommen?

Gruss
Beast

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.