Hallo wollte Fragen was mein Fehler ist, da meine "Uhr" etwas zu langsam
zählt und ich einfach nicht darauf komme.
Das Projekt soll eine Uhr sein welche auf einem Display ausgegeben wird.
Es muss mit dem PIC18F25K22 programmiert werden und ich benötige dies
für eine Arbeit in der Schule.
Danke schon im Vorhinein für eure Vorschläge und Anregungen
MFG
PROGRAMMCODE:
1
#include"main.h"
2
#include"lcd.h"
3
4
intsec1,sec2,min1,min2,hour1,hour2;
5
6
7
voidmain(void)
8
{
9
//Initialisierungen
10
ANSELA=0;
11
ANSELC=0;
12
TRISA=0;
13
TRISC=0;
14
15
//Startwert bestimmen
16
sec1=0;
17
sec2=0;
18
min1=0;
19
min2=0;
20
hour1=0;
21
hour2=0;
22
23
LCD_init();
24
25
//Timer initialisieren für das Zählen von 1 sekunde
Interne Clock wird verwendet.
es sind ca 250 ms welcher er zu langsam zählt,weiß nicht ob Fehler im
Programm liegt, oder ob es rein die "Verarbeitungszeiten" sind.
MFG
D. R. schrieb:> Hallo wollte Fragen was mein Fehler ist, da meine "Uhr" etwas zu langsam> zählt und ich einfach nicht darauf komme.
Du solltest einen anderen Timer (1/3/5) mit einem dem CCP- Modul
verwenden.
Dann hast du die von Peter angesprochene Möglichkeit.
Wenn es eine Bedingungen der Aufgabe ist, den Timer0 zu verwenden, dann
musst du den Timer vorstellen, indem du was zum aktuellen Timerwert dazu
addierst und nicht den Timer neu lädst.
Schau mal da:
http://www.hs-ulm.de/nocache/wir/Personal/PersonalSaSchr/vschilli/Mikrocontroller/uCQ/
Der oberste Download auf der rechten Seite.
5.1 Timer_0 Interrupt
5.2 Interrupt mit Special-Event-Trigger (CCP + Timer)
Uhr gibt es auch...
D. R. schrieb:> es sind ca 250 ms
Pro Sekunde? Pro Tag?
Häufigste Fehler:
A: interne clock hat Abweichungen: kalibrieren oder Quarz verwenden.
Timer-Teiler zu ungenau: entsprechende Schalttakte einfügen.
Off by one Fehler beim Teiler: nachrechnen, Beispiele verstehen, Pin
togglen lassen und messen, mit Oszi oder Frequenzzähler
Interrupt verschluckt:
Interrupts nicht sperren, Zählerstand am Anfang und Ende auf
Plausibilität prüfen, Fehlerzähler einbauen und auch anzeigen
D. R. schrieb:> TMR0H = 00001011;
Ist das dein originaler Code?
Dann hast du vielleicht auch noch ein ganz anderes Problem.
1011 != 0b1011
<EDIT>
1011 = 0b100_00000011
<edit2>
D. R. schrieb:> //Timer starten> T0CON = 10000001;
Hier kommt zufällig das gewollte raus ;-)
(0b1001100010010110_10000001)
0b010 ist zwei und eine Erweiterung um binäre zahlen
10 ist zehn
010 ist acht. Zumindest in C, da oktal
Es wäre aber möglich, dass dein Compiler jede separate Folge von 8
Nullen und Einsen als binär nimmt
D. R. schrieb:> Es muss mit dem PIC18F25K22 programmiert werden
Dein PIC hat einen "Dedicated Secondary 32 kHz oscillator circuit"
Warum nicht einen Uhrenquarz verwenden?
Anbei eine pdf-Zusammenstellung wie man eine Real Time Clock
programmiert und was zu beachten ist,wenn man Timer1 updated.
Achim S. schrieb:> Es wäre aber möglich, dass dein Compiler jede separate Folge von 8> Nullen und Einsen als binär nimmt
ich glaube so ist es ja ^^
dankeschön Leute ich hab heute keine Zeit mehr ich schau morgen weiter
und berichte von meinen "Ergebnisen" (falls euch interessiert) xD
MFG
Achim S. schrieb:> 010 ist acht. Zumindest in C, da oktal
Ja richtig, hatte oktal ganz vergessen...
(also ist das einer meiner Beispiele oben eigentlich falsch)
01011 -> 0b 001 000 001 001
D. R. schrieb:> Zumindest macht es keinen unterschied ob ich es jetzt so schreibe...
Schau dir doch mal im Debugger/Simulator an, was da wirklich in den
Registern steht.
Ich nehme an, du verwendest den C18 Compiler
User Guide ->
------------------------------------------------------------------------
2.7.2 Numeric Constants
MPLAB C18 supports the standard prefixes for specifying hexadecimal (0x)
and octal (0) values and adds support for specifying binary values using
the 0b prefix. For example, the value two hundred thirty seven may be
denoted as the binary constant 0b11101101
------------------------------------------------------------------------
D. R. schrieb:> Achim S. schrieb:>> Es wäre aber möglich, dass dein Compiler jede separate Folge von 8>> Nullen und Einsen als binär nimmt>> ich glaube so ist es ja ^^
Ich bin mir sehr sicher, dass dem nicht so ist ;-)
Trotzdem sollte der Fehler weit geringer als deine 250ms sein.
Wie hast du den ermittelt? Waren es vielleicht 250us?
Vermutlich gibt es mehrere Baustellen ;-)
Lösungsvorschläge:
1. Mach dir den Unterschied zwischen binär, oktal, hexadezimal und
dezimal klar.
2. Poste doch mal die Aufgabenstellung, damit wir keine dazu unpassenden
Ratschläge geben.
3. Sag doch bitte mal welche IDE und Compiler du verwendest
4. Falls MPLABX, dann Poste doch einfach das gepackte Projekt
(http://microchipdeveloper.com/mplabx:projects-package)
D. R. schrieb:> //Timer initialisieren für das Zählen von 1 sekunde> TMR0H = 00001011;> TMR0L = 11011100;
Irgendwoherkopiert oder für deinen uC richtig berechnet, das sind keine
binären Zahlen.
while(1){
LCD_WC(3);
besser
while(1)
{
int sec=sec1;
while(sec==sec1) ; // sec1 sollte volatile sein
LCD(WC(3);
damit nicht ständig das LCD geupdated wird, flimmert meist.
Eigentlich sollten die Doppelpunkte aber blinken, damit man sieht, daß
die Uhr noch läuft.
Michael B. schrieb:> Irgendwoherkopiert oder für deinen uC richtig berechnet, das sind keine> binären Zahlen.
Berechnet:
fosc = 1 MHz
fosc/4 = 250 000 Hz
1s...250 000
Presacler benötigt:
250000/4 = 62500
Startwert= 65 536 - 62 500 = 3036
H L
0 0 0 0 1 0 1 1 1 1 0 1 1 1 0 0
Michael B. schrieb:> damit nicht ständig das LCD geupdated wird, flimmert meist.
Flimmert nicht habs schon aufgebaut.
IM anhang jetzt die ZIP-File
(Timer ist jetzt für 0,79 berechnet da die Abweichung so geringer ist)
Nur eine Idee:
Ich bin früher immer drauf reingefallen, dass ich immer "-1" rechnen
muss, um den genauen Zählerwert eines Timers zu bekommen.
Als Beispiel: Ich habe 4Mhz Timer-Takt und möchte, dass dieser jede
Millisekunde einen Überlauf macht. Dann ist die Formel:
iZ = 4.000.000 / 1000 - 1;
Warum die -1? Weil die 0 nach einem Überlauf mitzählt. Es soll von 0 bis
3999 gezählt werden und nicht von 0 bis 4000, das wären 4001 Schritte.
Das hat mir damals eine genaue Frequenzausgabe einer DDS total merklich
zerstört.
D. R. schrieb:> IM anhang jetzt die ZIP-File
OK, dann verwendest du also noch die "alte" IDE.
Keine Ahnung, warum deine Abweichung so groß ist. Der interne Oszillator
muss sehr ungenau sein. Das habe ich so noch nie gesehen.
Hier noch einige Tips zu deinem Code:
Von der Berechnung des Startwertes mal abgesehen, sind die Sekunden
unterschiedlich lang, wenn mehr oder weniger der IFs abgearbeitet
werden, weil der Reload erst danach erfolgt.
-> Das muss als aller erstes passieren, oder eben nicht nachgeladen,
sondern aufaddiert werden. (Das Addieren ist in aber diesem Fall
komplizierter als man auf den ersten Blick annehmen würde ;-)
Die LCD Funktionen sollten zum Schreiben LAT Register verwenden und
nicht PORT. (RMW Effekt)
Der Datentyp int ist zum Speichern einer Variable von 0..9 ganz schön
übertrieben. Da würde man vier davon rein bekommen. -> unsigned char.
Eigentlich könntest du gleich überall mit Ziffern rechnen und dir das
Aufaddieren der '0' bei der Ausgabe sparen.
Danke für die Tipps ich schau mal was sich für mich alles umsetzten
lässt
Volker S. schrieb:> Eigentlich könntest du gleich überall mit Ziffern rechnen und dir das> Aufaddieren der '0' bei der Ausgabe sparen. if (sec2 > '9') {> sec1++;> sec2 = '0';> }
Wenn ich so schreibe, werden dann Buchstaben etc. ausgegeben
Punkt eins, das OSCAL wird nicht initialisiert. Damit ist warscheinlich
der
Takt falsch.
Punkt zwei, Timer hat einen 2clk hw sync, deshalb muss man 2 cpu cyclen
abziehen.
Punkt drei, wieso .... wird hier eine Binärzahl verwendet und wieso kein
16bit Adresse ????
Punkt vier, der Interrupt ist falsch, da wird Zeit verbraucht , und dann
wird der Timer auf den Wert gesetzt. Diese Interruptzeit muss abgezählt
werden.
Am einfachsten geht es so:
tmr1 -= 62500 ; // oder der Wert den du errechnet hast, inclk den 2 sync
cyclen.
Damit braucht man dann keine Asm cyclen Zählen, bzw im Simulator diese
raussuchen.
D. R. schrieb:> ich benötige dies> für eine Arbeit in der Schule.
Was für eine Schule ist das eigentlich?
D. R. schrieb:> Wenn ich so schreibe, werden dann Buchstaben etc. ausgegeben
Dir scheinen da einige Grundlagen zu fehlen. Die kann man vermutlich
nicht an jeder / keiner Schule vermitteln, ohne dass alle Schüler das
Interesse schon verloren haben, bevor es an's Programmieren geht ;-)
Es werden immer Zeichen ausgegeben. In den Registern für die Variablen
stehen aber nur Bitmuster (keine Zahlen). Stehen in den Variablen schon
die Bitmuster, welche den gewünschten Zeichen entsprechn, dann muss man
diese nicht mehr durch addieren der Bitmuster für '0' umwandeln...
Volker S. schrieb:> Was für eine Schule ist das eigentlich?
HTL
Volker S. schrieb:> Dir scheinen da einige Grundlagen zu fehlen
Stimmt xD
chris schrieb:> Punkt eins, das OSCAL wird nicht initialisiert. Damit ist warscheinlich> der> Takt falsch.
Takt sollte passen (normal 1 MHz), habs jetzt nochmal extra deklariert
und es bleibt alles beim alten..
chris schrieb:> Punkt zwei, Timer hat einen 2clk hw sync, deshalb muss man 2 cpu cyclen> abziehen.> Punkt drei, wieso .... wird hier eine Binärzahl verwendet und wieso kein> 16bit Adresse ????
Punkt 2: ???????
Punkt 3: wo meinst du ?
chris schrieb:> Punkt vier, der Interrupt ist falsch, da wird Zeit verbraucht , und dann> wird der Timer auf den Wert gesetzt. Diese Interruptzeit muss abgezählt> werden.> Am einfachsten geht es so:> tmr1 -= 62500 ; // oder der Wert den du errechnet hast, inclk den 2 sync> cyclen.> Damit braucht man dann keine Asm cyclen Zählen, bzw im Simulator diese> raussuchen.
Kann dir leider dort auch nicht folgen :O
D. R. schrieb:> chris schrieb:>> Punkt eins, das OSCAL wird nicht initialisiert. Damit ist warscheinlich>> der>> Takt falsch.>> Takt sollte passen (normal 1 MHz), habs jetzt nochmal extra deklariert> und es bleibt alles beim alten..>
Dieser interne RingOscillator muss calibriert werden, dies wird er ab
Werk
grob sowie Fein und als Osccal Value im Flash 2-3 mal abgelegt.
Den kann man auch selbst kalibrieren, aber man muss den Wert dann ins
osccal Register schreiben, damit die 1Mhz oder was es auch ist stimmen.
Das Datenblatt gibt weitere Auskünfte.
> chris schrieb:>> Punkt zwei, Timer hat einen 2clk hw sync, deshalb muss man 2 cpu cyclen>> abziehen.
Siehe Datenblatt, beim Schreiben wird der Timer für 2 cpu clk
angehalten.
>> Punkt drei, wieso .... wird hier eine Binärzahl verwendet und wieso kein>> 16bit Adresse ????
TMR1 = -62500 ; // startwert
Dies ist viel leserlicher, und erleichter das abziehen des Wertes im
ISR.
>> Punkt 2: ???????>> Punkt 3: wo meinst du ?>> chris schrieb:>> Punkt vier, der Interrupt ist falsch, da wird Zeit verbraucht , und dann>> wird der Timer auf den Wert gesetzt. Diese Interruptzeit muss abgezählt>> werden.>> Am einfachsten geht es so:
Wie geschrieben,
>> tmr1 -= 62500 ;
anstelle von
TMR1L = 0b10011;
TMR1H = 0b10011;
denn dann muss man die Zeit vom Interrupt sowie den Clockzycle jitter
compensieren, dies wird eine ASM zählerei und einen free running timer,
wenn es auf synchronen clock ankommt, wenn es wie hier nicht so genau
ist
genügt die Zählerei, aber mit der Subtraction braucht man dies nicht.
chris schrieb:> Punkt eins, das OSCAL wird nicht initialisiert.
Es gibt nur ein OSCTUNE
chris schrieb:> Punkt zwei, Timer hat einen 2clk hw sync, deshalb muss man 2 cpu cyclen> abziehen.
Bin mir jetz nicht hunder Prozent sicher, aber warum sollte der interne
Clock mit dem internen Clock synchronisiert werden müssen?
Müsste man dann nicht zwei nicht gezählte dazu addieren?
chris schrieb:> Punkt drei, wieso .... wird hier eine Binärzahl verwendet und wieso kein> 16bit Adresse ????
Was für eine Adresse?
chris schrieb:> Am einfachsten geht es so:> tmr1 -= 62500 ;
Ich fürchte der verwendete Compiler wird TMR0 (oder irgend ein anderen
Namen für beide Register eines Timers) nicht akzeptieren.
chris schrieb:> Punkt vier, der Interrupt ist falsch, da wird Zeit verbraucht , und dann> wird der Timer auf den Wert gesetzt.
Was ganz neues ;-)
>Volker S. schrieb:
@Ein Mitschüler,
> chris schrieb:>> Punkt zwei, Timer hat einen 2clk hw sync, deshalb muss man 2 cpu cyclen>> abziehen.> Bin mir jetz nicht hunder Prozent sicher, aber warum sollte der interne> Clock mit dem internen Clock synchronisiert werden müssen?
Man kann ihn auch als Asyncron configurieren, aber diesen Unterschied
ist minimal
> Müsste man dann nicht zwei nicht gezählte dazu addieren?
je nach Logic wie man dies macht, wenn man 100 Zählereinheiten
configurieren will schriebe ich
TMR1 = -100; // in diesem Falle muss ich es wegzählen.
wenn man aber folgendes Verwendet
TMR1 = 65436; // muss man es dazuzählen.
>> chris schrieb:>> Punkt drei, wieso .... wird hier eine Binärzahl verwendet und wieso kein>> 16bit Adresse ????> Was für eine Adresse?
Normalerweise TMR1 , bei C18 ist dies aber nicht.
verwende die Include timers.h
und benutze
WriteTimer1(ReadTimer1()-6200); // 6200 ist hier eine Hausnummer der
Sekunde.
> Was ganz neues ;-)
chris schrieb:>> chris schrieb:>>> Punkt drei, wieso .... wird hier eine Binärzahl verwendet und wieso kein>>> 16bit Adresse ????>> Was für eine Adresse?> Normalerweise TMR1 , bei C18 ist dies aber nicht.> verwende die Include timers.h> und benutze> WriteTimer1(ReadTimer1()-6200); // 6200 ist hier eine Hausnummer der> Sekunde.
Ach so meinst du das mit der Adresse. Würde mich wundern, wenn das
irgendein Compiler in diesem speziellen Fall einfach so könnte.
Mit Gewalt, *(unsigned short *)(&TMR0L) = ... , geht's ja auch nicht,
weil dann die Reihenfolge falsch ist.
Auf die Idee mit dem Abziehen bin ich noch gar nicht gekommen. Denke
wohl immer vorstellen -> dazu zählen. Muss ich mir mal anschauen, was da
für ein Maschinencode bei raus kommt.
<edit>
Vergiss es, ich würde überhaupt nie den Timer manuell umstellen,
sondern das CCP verwenden.
@reisii
Lass dich nicht verwirren und ignoriere bitte meine Fachsimpeleien...
Mal ganz was anderes:
Für PICs bietet microchip die C Standardlibrary an. Statt also das ganze
Konstrukt selber zu pflegen, und die Zeit hochzuziehen, kann man das
auch so lösen:
1
#include<time.h>
2
3
time_tZeit;
4
5
//jede Sekunde einmal aufrufen
6
Zeit++;
7
8
9
//und so liest man die Zeit aus:
10
structtm*Time=gmtime(&Zeit);
in tm findest du dan all die Sekunden, Wochentage und Jahre, aufgelistet
in einer Struktur.
Großer Vorteil der Sache: Da es eine C Standardlibrary ist, ist es
portabel.
Volker S. schrieb:> Lass dich nicht verwirren und ignoriere bitte meine Fachsimpeleien
Werde mich bemühen ^^
Naja ich bin noch immer nicht wirklich weiter gekommen :(
Volker S. schrieb:> Punkt vier, der Interrupt ist falsch, da wird Zeit verbraucht , und> dann>> wird der Timer auf den Wert gesetzt.> Was ganz neues ;-)
Ist mein Interrupt jetzt falsch ? :O
time.h schrieb:> Für PICs bietet microchip die C Standardlibrary an. Statt also das ganze
hört sich interessant an, werde ich mich erkundigen danke
Vergiss time.h. Das gibt es bei deinem Compiler nicht.
(und geht vermutlich an deiner AUFGABENSTELLUNG weit vorbei)
Dein Interrupt ist insofern falsch, dass du wie schon mehrmals gesagt,
erst Code von nicht immer gleicher Länge ausführst und dann trotzdem
immer den gleichen Wert in die Timer Register lädst. So bekommst du
(leicht) unterschiedliche Laufzeiten für die Sekunde.
Was heißt, du bist noch nicht weiter gekommen?
Was ist den dein Ziel? (Aufgabenstellung)
Volker S. schrieb:> Dein Interrupt ist insofern falsch,
hab jetzt eifnach das Timerstellen davor geschrieben ^^
Ja gut ich schätze mal es ist einfach bei Timer0 mit solchen
Verzögerungen zu rechnen ? :/
D. R. schrieb:> time.h schrieb:>> Für PICs bietet microchip die C Standardlibrary an.>> Finde keine passende information oder download für die Library
Die Information steht in der Hilfe zum Compiler, also in MPLABX. Die
C-Standardlib ist beim XC8-Compiler schon mit dabei, behauptete
zumindest die Hilfe.
Theoretisch sollte ein #include <time.h> ausreichen.
D. R. schrieb:> time.h schrieb:>> Theoretisch sollte ein #include <time.h> ausreichen.>> funktioniert nicht, glaube>> Volker SK hat recht
Sicher?
time.h ist Bestandteil der Sprache C.
ich hab jetzt keinen XC8 installiert, aber beim XC16 und XC32 - Compiler
ist time.h mit dabei.
Die Hilfe erwähnt für time.h und beteiligte Funktionen ist in der Hilfe
von MPLABX in der Sektion für den XC8 enthalten.
time.h schrieb:> Sicher?
Ja! Kein MPLABX kein XC Compiler...
Jetzt komm bloß nicht damit, dass man das ja installieren könnte.
Könnte man, aber die Aufgabe soll vermutlich mit den vorhandenen Mitteln
gelöst werden. Es geht (bei der Übungsaufgabe?) vermutlich auch gar
nicht darum, eine möglichst perfekte Uhr mit den tollsten
Bibliotheksfunktionen zu programmieren, sondern um das Verständnis, wie
so ein Timer funktioniert.
Die Uhr ist wahrscheinlich nur ein Beispiel, damit sich die Schüler
leichter etwas darunter vorstellen können. Wer eine vernünftige Uhr
haben möchte, der geht am besten in den nächsten Laden und kauft sich
eine.
In der nächsten Übung wird dann vielleicht ein anderer Timer mit einem
CCP Modul als Trigger für den AD-Wandler verwendet...
@reisii
vermutlich, wahrscheinlich, vielleicht... ?
Volker S. schrieb:> 2. Poste doch mal die Aufgabenstellung, damit wir keine dazu unpassenden> Ratschläge geben.
Volker S. schrieb:>> 2. Poste doch mal die Aufgabenstellung, damit wir keine dazu unpassenden>> Ratschläge geben
Ich soll eine Übung selbst entwickeln um das das Verständniss mit dem
Timer und Interrupt zu erarbeiten, von dem her passt das einfache mit
TMR0 eigentlich.
Die Genauigkeit war/ist nur so ein persönliches Ding für mich.
Vermutlich wird das mit Timer0 und CCP etc. noch dazukommen irgendwann.
D. R. schrieb:> Ich soll eine Übung selbst entwickeln um das das Verständniss mit dem> Timer und Interrupt zu erarbeiten, von dem her passt das einfache mit> TMR0 eigentlich.>> Die Genauigkeit war/ist nur so ein persönliches Ding für mich.>> Vermutlich wird das mit Timer0 und CCP etc. noch dazukommen irgendwann.
Ich würde als Ausgangspunkt (d.h. nicht irgendwann) dann eher einen
Timer-Modus nehmen, wo der Timer selbständig einen regelmäßigen, durch
die Hardware bestimmten Interrupt auslöst. D.h. in der ISR wird
nicht an den Timer-Registern "rumgemacht", dort steht quasi nur das
"Anwenderprogramm", das den Zeittakt verwendet.
Das wäre eine Basis, mit der man einen stabilen, vom Programm
(weitgehend) unabhängigen Zeittakt hat, den man eigentlich immer
braucht. Und das Programm ist sogar noch einfacher und übersichtlicher.
Also warum nicht gleich die "genaue" Version, wenn die "ungenaue" weder
bei der Programmierung noch bei der Anwendung Vorteile hat...
Dietrich L. schrieb:> Ich würde als Ausgangspunkt (d.h. nicht irgendwann) dann eher einen> Timer-Modus nehmen, wo der Timer selbständig einen regelmäßigen, durch> die Hardware bestimmten Interrupt auslöst.
Das ist die einzige Möglichkeit, eine stabile Frequenz zu erhalten, zur
Einstellung die Zyklenzahl von Befehlen abzuziehen war, ist und wird
immer Murks sein.
Georg
D. R. schrieb:> Ich soll eine Übung selbst entwickeln um das das Verständniss mit dem> Timer und Interrupt zu erarbeiten, von dem her passt das einfache mit> TMR0 eigentlich.
Dann solltest du das mit dem TimerO jetzt abhaken und wie von vielen
hier vorgeschlagen, dazu über gehen einen Timer zu verwenden, bei dem
das ganze Gefrickel gar nicht nötig ist.
Wie das funktioniert, solltest du aus dem ganz oben verlinkten Skript
entnehmen können. Falls das dort nicht ausreichend gut beschrieben ist,
wäre ich auch für Feedback dankbar ;-)
D. R. schrieb:> Ich soll eine Übung selbst entwickeln....
Sorry, muss noch mal nachfragen ;-)
Du bearbeitest also keine fertig gestellte Übungsaufgabe, sondern du
sollst selbst eine entwickeln, die dann von anderen bearbeitet werden
wird?
Volker S. schrieb:> Du bearbeitest also keine fertig gestellte Übungsaufgabe, sondern du> sollst selbst eine entwickeln, die dann von anderen bearbeitet werden> wird?
also ich soll eine Aufgabe stellen, dazu theorie teil, dann durchführung
etc beschreiben
Ok, dann passt schon mit Timer0.
Wenn Uhr, dann ist das Resultat der Übung eben,
dass dieser dafür nicht so gut geeignet ist.
Oder einfach 'ne LED blinken lassen...
Hast du eigentlich mal einen anderen 18F24K22 getestet,
ob da die Zeit auch so eklatant abweicht?
Volker S. schrieb:> k, dann passt schon mit Timer0.
ich muss sowieso mehr Übungen "entwickeln"
ich glaube es folgt dann mit Timer1 und CCP eine erweiterung (aber bin
gerade noch am tüfteln und kenn mich damit gar nicht aus)
Volker S. schrieb:> Hast du eigentlich mal einen anderen 18F24K22 getestet,> ob da die Zeit auch so eklatant abweicht?
Nein hab ich noch nicht
Volker S. schrieb:> Wenn es eine Bedingungen der Aufgabe ist, den Timer0 zu verwenden, dann> musst du den Timer vorstellen, indem du was zum aktuellen Timerwert dazu> addierst und nicht den Timer neu lädst.
also nicht TMR0H = 0bXXXXXXXX sondern TMR0H = TMR0H + 0bXXXXXXXX ??
Inwiefern ändert das die Situation ? bzw erreiche ich so mehr fehler
oder denke ich mal wieder falsch :(
MFG
D. R. schrieb:> Volker S. schrieb:>> Hast du eigentlich mal einen anderen 18F24K22 getestet,>> ob da die Zeit auch so eklatant abweicht?>> Nein hab ich noch nicht
Wir verwenden den ja auch meist mit internem Oszillator in den Laboren
für unsere Studies. Bei den Bedingungen in den Laborräumen ( ~20°C ;-)
sind da selbst bei serieller Datenübertragung via USART nie Probleme
aufgetreten.
-> die internen Oszillatoren sind eigentlich relativ gut.
D. R. schrieb:> also nicht TMR0H = 0bXXXXXXXX sondern TMR0H = TMR0H + 0bXXXXXXXX ??>> Inwiefern ändert das die Situation ? bzw erreiche ich so mehr fehler> oder denke ich mal wieder falsch :(
Wenn der Timer durch Addition/Subtraktion verändert wird, ist der
Zeitpunkt, bzw. wie viele Zyklen inzwischen vergangen sind nicht so
wichtig. (So lang keine Überlaufe durch die Addition entstehen)
Die Verarbeitung ist aber tricky-
TMR0H = TMR0H + T0H_KORREKTUR;
TMR0L = TMR0L + T0L_KORREKTUR;
scheitert z.B. daran, dass das neue TMR0H nicht übernommen wird, sondern
durch das erneute Auslesen von TMR0L wieder mit dem internen Wert
überschrieben wird. Der ist kurz nach dem Überlauf sehr wahrscheinlich
Null - und das steht nach der Operation dann auch drin ;-)
D. R. schrieb:> ich muss sowieso mehr Übungen "entwickeln"
Wenn das sozusagen eine größere Überarbeitung bedeutet, dann solltet ihr
mal überlegen, ob in dem Zug nicht auch die veraltete IDE und Compiler
gegen aktuelle Tools ausgetauscht werden sollten.
Beide werden seit Jahren nicht mehr gepflegt und sind für die Schüler
auch nicht mehr ganz so einfach erhältlich.
Zudem besteht keine Einschränkung mehr in Bezug auf das OS.
Die "neuen" laufen unter Windows, Linux und MAC OS.
Volker S. schrieb:> aktuelle Tools ausgetauscht werden sollten.
ich werde mal mit dem Lehrer darüber reden wir haben halt nur diese
MPLAB und den PIC22... bekommen
Volker S. schrieb:> Die Verarbeitung ist aber tricky-
ich glaub ich bleib einfach beim Timer beschreiben ^^
D. R. schrieb:> ich glaub ich bleib einfach beim Timer beschreiben ^^
Mach das. Der ganze zusätzliche Aufwand lohnt gar nicht, weil das am
Ende keiner mehr so machen würde. Es geht ja viel einfacher und
automatisch mit dem Compare Modul.
Es gibt auch noch die Möglichkeit, einen Prescaler zu verwenden.
Wenn man z.B. 64 als Prescaler nimmt und nicht durch andere Interrupts
mehr als 64 CPU-Takte verzögert wird, dann ist das Laden des Timers in
SW auch genau.
Natürlich darf man nicht auch noch den Prescaler neu starten, sondern
der muß durchlaufen.
Peter D. schrieb:> Natürlich darf man nicht auch noch den Prescaler neu starten, sondern> der muß durchlaufen.
Das kann man sich hier leider nicht aussuchen.
#####################################################
When assigned to the Timer0 module, all instructions
writing to the TMR0 register (e.g., CLRF TMR0, MOVWF
TMR0,BSF TMR0, etc.) clear the prescaler count.
#####################################################