Forum: Mikrocontroller und Digitale Elektronik PIC18 Timer0 auslesen in C


von David M. (mic_dave)


Lesenswert?

Hallo zusammen,
ich bin hier schon den ganze Tag am verzweifeln. Und zwar möchte ich mir 
gerne den Wert des Timer0 ausgeben. Ich habe ihn als 16- Bit Timer 
initialisiert.
Nun die Funktionsweise:
Beim Tastendruck soll eine Nachricht an den Rechner über eine RS232- 
Schnittstelle gesendet werden. Diese Nachricht sieht wie folgt aus:
1
sprintf(text, "(1, %d, %d, %d, %d)", TASTER1, tmr0h, tmr, tmr0l);
(tmr beinhaltet die Anzahl der Überläufe)

Als Ausgabe bekomme ich dann folgendes:
(1, 0, 39, 5312, 0)
Und diese letzte Null steht immer da (tmr0l). Ich weis aber nicht, woran 
das liegt. Er müsste mir da ja eigentlich den Wert tmr0l anzeigen.
Hier mal die Codeschnippsle:

Interrupt:
1
  unsigned int tmr0l = TMR0L;
2
  unsigned int tmr0h = TMR0H;
3
  int_send(tmr, tmr0l, tmr0h);

int_send:
1
void int_send(unsigned long tmr, unsigned int tmr0l, unsigned int tmr0h){
2
  if(INTCON3bits.INT2IF){
3
4
    INTCON3bits.INT2IE = 0;
5
6
    if(INTCON2bits.INTEDG2){
7
      INTCON2bits.INTEDG2 = 0;
8
    }
9
    else{
10
      INTCON2bits.INTEDG2 = 1;
11
    }
12
    INTCON3bits.INT2IF = 0;
13
14
    sprintf(text, "(1, %d, %d, %d, %d)", TASTER1, tmr0h, tmr, tmr0l);
15
    putUsart(text);
16
17
    INTCON3bits.INT2IE = 1;
18
  }
19
20
  if(INTCON3bits.INT1IF){
21
22
    INTCON3bits.INT1IE = 0;
23
24
    if(INTCON2bits.INTEDG1){
25
      INTCON2bits.INTEDG1 = 0;
26
    }
27
    else{
28
      INTCON2bits.INTEDG1 = 1;
29
    }
30
    INTCON3bits.INT1IF = 0;
31
32
    tmr0l = TMR0L;
33
    tmr0h = TMR0H;
34
    sprintf(text, "(2, %d, %d, %d, %d)", TASTER2, tmr0h, tmr, tmr0l);
35
    putUsart(text);
36
37
    INTCON3bits.INT1IE = 1;
38
  }
39
40
  return;
41
}

Ich bedanke mich schon vielmals für eure Hilfe.
Falls noch irgendetwas Fehlen sollte, einfach bescheid sagen :)

David

von Bernd R. (Firma: Promaxx.net) (bigwumpus)


Lesenswert?

Also,
es ist richtig, daß Du erst TMR0L auslesen mußt, damit TMR0H gebuffert 
wird.

Es ist unnötig innerhalb der ISR den IE auf 0 zu setzen und später 
wieder auf 1 - INTs sind während der ISR quasi sowieso abgeschaltet 
(außer du nutzt Prioritäten).

Innerhalb einer ISR einen Text auszugeben ist quasi Mist.
Eine ISR soll gaaaaanz schnell abgearbeitet werden um dann das lange 
Hauptprogramm weiter zu verfolgen. Das ist dann eine Schleife, die auf 
Zustandsmeldungen der ISRs reagiert.

Trotzdem ist es rätselhaft, warum TMR0L immer 0 ist.

Die Namensgebung finde ich sehr riskant. Ich würde statt tmr0l eher 
tmr0l_ oder ähnliches nehmen, damit nicht irgendwo etwas wegen 
Groß-/Kleinschreibung=egal schief läuft.

von B. L. (b8limer)


Lesenswert?

Aber die Anzahl der Überläufe (tmr) bekommst du angezeigt?
Wenn du die Überlaufe angezeigt bekommst dann läuft der Timer zumindest 
schonmal. Wenn nicht, schau warum er nicht läuft.
Man sieht zu wenig von deinem Code - könnte es sein, dass du ausversehen 
den Timerinterrupt nur "scharf" geschalten hast, wenn du einen Taster 
drückst? Dann springt er sofort in die ISR.
Welche Taktquelle hat der Timer? Ist sie richtig konfiguriert?
Ansonsten kann ich mich nur meinem Vorredner anschließen. ISR so kurz 
wie nur irgend möglich. Keine "printf", etc, nichts was rechenintensiv 
wäre. Und riskante Doppelbennenungen vermeiden. Nie irgendwas so nennen 
wie es der Compiler tun könnte. Eigenlich sollte der C-Compiler Groß- 
und Kleinschreibung unterscheiden aber es passieren da u.U auch Fehler.

von David M. (mic_dave)


Lesenswert?

Vielen dank erstmal für eure Antworten. Ja das mit der Namesgebeung ist 
mir echt misslungen, wird auch sofort abgeändert. tmr wird korrekt 
angezeigt. Und wie ich die Ausgaben aus dem ISR bekomme, wollte ich mir 
auch noch überlegen, da, wie ihr schon sagtet, der ISR so kurz wie 
möglich gehalten werden sollte. Aber nun nochmal zum eigentlichen 
Problem. Wenn ich meine Ausgabe nun wie folgt gestalte:
1
    sprintf(text, "(2, %d, %d, ", TASTER1, tmr);
2
    putUsart(text);
3
    sprintf(text, "%d, %d)<1>", TMR0H, TMR0L);
4
    putUsart(text);
d.h. wenn ich die Ausgabe in mehrere Teile aufspalte, dann funktioniert 
das. Es ist also kein Problem am Timer, sondern an dem sprintf, was mir 
ein Rätsel ist.
Hat da irgendjemand eine Idee, woran das liegen könnte?

David

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.