Forum: Mikrocontroller und Digitale Elektronik Signalzeiten messen mit PIC18F


von Chris H. (xkris)


Lesenswert?

Hallo,

ich versuche grad mit einem PIC18F Pausenzeiten eines Rechtecksignals zu 
erfassen. Das zu messende Signal liegt an einem Interrupt-fähigen Pin.

Das Programm funktioniert folgendermaßen:
Bei der Initialisierung wird der Pin so konfiguriert, das er bei 
fallender Flanke einen Interrupt auslöst. Wenn dies der Fall ist, 
springt er in die ISR und startet den Timer indem ich den Timer_enable 
der vorher 0 war toggle.
Dann wird der Interrupt wieder aktiviert (muss per software gemacht 
werden)und so konfiguriert, das er bei steigender Flanke auslöst. Dann 
wird die ISR verlassen. Wenn die steigende Flanke kommt und einen 
interrupt auslöst, springt das Programm wieder in die ISR, toggelt den 
Timer, also stoppt ihn diese Mal, der Wert wird ausgelesen, der 
Interrupt wieder scharf geschaltet und wieder auf falling edge gesetzt, 
so dass er bei nächster fallender Flanke wieder anfängt zu messen, dann 
wird der Timer noch genullt und das wars.

Aber leider spuckt der Algoritmus nicht die Timerwerte aus, die ich 
erwarte. Kann es sein, dass der Prozessor langsamer läuft oder das sonst 
irgendetwas anders ist, wenn ich per ICSP programmiere und debugge? Oder 
hab ich etwas grundlegendes übersehen?Ich benutze die MPLAB IDE und 
programmiere in C.

Nachtrag: Mein Messsignal ist ein normales 1kHz Rechtecksignal, also 
0.5ms Pausenzeit, die ich gern messen würde. Mein PIC läuft mit 40Mhz, 
als ein Timercount entspricht einem Befehlszyklus = 4 Taktzyklen = 
0.1µs, sollte also genügen

von Dirk F. (sensornix)


Lesenswert?

Hallo

Welchen PIC? Welcher Timer? Was misst du? Was sollte herauskommen?
Has du dir mal die Errata-Sheets angesehen, ob der Timer auch so
tut wie im Datenbaltt angegeben?

Grüße SensorNix

von Chris H. (xkris)


Lesenswert?

Hallo,

also ich benutze den PIC18F458.Ich habe RB5 über einen 4.7k pullup auf 
+5V liegen. RB5 ist verbunden mit RB1/INT1 welcher als Interrupt Pin 
konfiguriert ist. In periodischen Abständen schalte ich RB5 auf Input 
low, ziehe somit das Signal an RB1 ebenfalls auf low. Dieses Ereignis 
soll den Timer starten. Wenn RB5 nach einer gewissen Zeit wieder auf 
Eingang geschaltet wird, also hochohmig, liegen an RB1 und RB5 wieder 
5V, dann reagiert der Interrupt wieder auf dieses Ereignis und der Timer 
wird angehalten und der Wert ausgelesen.

1
if(INTCON3bits.INT1IF)   //INT1 has occurred
2
  {
3
    INTCON3bits.INT1IF = 0;   //***bit0***  clear INT1 interrupt flag
4
    T0CONbits.TMR0ON = !T0CONbits.TMR0ON;   // ***bit7*** toggle timer start/stop bit
5
    if (!T0CONbits.TMR0ON)   // if timer has just been stopped...
6
    {
7
      timer_value=TMR0L+(TMR0H*0x100);  //writes timer value to variable
8
      TMR0L=0x00;   //clears timer registers
9
      TMR0H=0x00;
10
      INTCON2bits.INTEDG1 = 0;  //set INT1 for stopping on falling edge
11
    }
12
    else
13
    {
14
      INTCON2bits.INTEDG1 = 1;  //set INT1 for stopping on rising edge
15
    }
16
    
17
  }

Das seltsame ist, wenn ich mir den Inhalt des Timer Registers nach
1
TMR0L=0x00;
2
TMR0H=0x00;

anzeigen lassen, stelle ich fest, dass TMR0H sich davon nicht 
beeindrucken läßt. Es behält seinen Wert. TMR0L hingegen hat 
anschliessend 0x00, so wie ich es eigentlich auch erwarte.

von Dirk F. (sensornix)


Lesenswert?

Muß nicht erst das High Byte und anschießend das Low Byte geschrieben 
weden?

von Dirk F. (sensornix)


Lesenswert?

Siehe Datenblatt Abschnitt 11.4

timer_value=TMR0L+(TMR0H*0x100);

könnte auch Probleme machen.
Wird der Ausdruck von vorne oder von hinten abgearbeitet?

von Chris H. (xkris)


Lesenswert?

hast Recht, das war der Grund für Problem

Danke nochmals

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.