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
voidTimer1Init();
20
voidinterrupt_isr(void);
21
//void max7219_time_write(unsigned int std, unsigned int min, unsigned int sek);
#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)
#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.
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)?
>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.
@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
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?
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
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);
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
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
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!
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:
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.
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€.
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
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
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
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:
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
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
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.
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