Forum: Mikrocontroller und Digitale Elektronik Capture PIC


von Mark (Gast)


Lesenswert?

Guten Tag
Ich habe über die Suchfunktion sehr viel über die Capturefunktion
gelernt und verstehe nun das Grundprinzip. Ich arbeite mit dem
PIC18F4680 (10Mhz)und schreibe mein Programm mittels CCS compiler.
Habe nun schon seit langer Zeit versucht ein Rechteckignal(1-40Hz)
einzulesen. Mein vorgehen:

Timer einschalten. (Timer1)

"Steigende Flanke detektieren" einschalten.

"Fallende Flanke detektieren" einschalten.

Interruprutine für fallende und steigende Flanke einschalten.


Wird eine steigende Flanke erkannt, wird eine Interruptrutine gestartet.
Ich speichere in dieser Routine den Fotografierten Wert (ccp1) in eine
globale Variabel(t1).

Wird eine fallende Flanke erkannt, wird eine weitere Interruptrutine
gestartet. Ich speichere in dieser Routine den Fotografierten Wert
(ccp2) in eine Variabel(t2). In dieser Interruprutine wird auch gleich
der Wert der Positivenflanke berechnet:
positiveflanke = t2-t1;
Die Variabeln habe ich als long definiert um dem Timerüberlauf entgegen
zu wirken.

Als ergebniss (positiveflanke) erhalte ich Verschiedene Werte die
irgendwo im Bereich des Zählers liegen.

Ich habe auch schon versucht den Timer bei jeder steigenden Flanke auf 0
zu setzen. Aber das Resultat bleibt gleich.

Habe ich grundsätzlich einen falschen Ablauf geplant? Hat jemand einen
Code an dem ich mich orientieren könnte?

Mfg Mark


von Hans-Ulrich R. (Gast)


Lesenswert?

Schau mal ins Example-directory vom Compiler.
EX_CCPMP.C :Uses the PIC CCP module to measure a pulse width

von Mark (Gast)


Lesenswert?

Danke. Habe zu beginn diesen Code benutzt. Werde es wohl morgen nochmals 
damit versuchen....

mfg Mark

von Mark (Gast)


Lesenswert?

Hmm... Habe es nun mal mit dem Code versucht. Speziel ist, das ich 
messwerte für die Pulsweite erhalte, obwohl ich gar kein Signal in den 
PIC gebe.

Habe den PIN (PIN17/CCP1) als Eingang deklariert.

von Hans-Ulrich R. (Gast)


Lesenswert?

Dann leg den Pin17 mal auf Masse, wahrscheinlich fängt der sich 
irgendwas ein.

von Mark (Gast)


Lesenswert?

Danke.. Ist nun schon mal besser.

von Mark (Gast)


Lesenswert?

Lege ich den Pin auf 0 (keine pulse) und schalte den Pic ein, stoppe das 
Programm und lade die Daten der Register(CCP1 für Flankehigh und CCP2 
für FlankeLow) über MPLAP ICD2 auf meinen Rechner, ist ersichtlich der 
Pic eine negative Flanke gesehen hat. Es stehen aber gar keine Flanken 
am Eingang.. ?!?! Gibt es niemanden der einen funktionierenden Code hat?

von Mark (Gast)


Lesenswert?

Habe ich einen Fehler im Code?


long rise,fall,pulse_width;

void main()
{

setup_timer_1(T1_INTERNAL|T1_DIV_BY_2);    // Start timer 1
setup_ccp1(CCP_CAPTURE_RE);                // Configure CCP1 capture 
rise
setup_ccp2(CCP_CAPTURE_FE);                // Configure CCP2 capture 
fall

enable_interrupts(INT_CCP2);               // Setup interrupt falling 
edge
enable_interrupts(GLOBAL);

}

/*********************************************************************** 
**
Rechtecksignal einlesen
************************************************************************ 
**
#int_ccp2
void isr()
{
 rise = CCP_1;
 fall = CCP_2;
 pulse_width = fall - rise;// CCP_1 is the time the pulse went high
}

von Peter D. (peda)


Lesenswert?

Ich vermute mal, beim PIC ists so, wie bei den anderen.

Wenn man ne Flanke capturen will, dann doch nicht irgendeine von vor 
tausend Jahren, sondern genau die nächste nach der Freigabe.

D.h. man muß unmittelbar vor jeder Freigabe das Interruptflag löschen 
(gilt eigentlich für alle Ereignis-Interrupts).


Peter

von Hans-Ulrich R. (Gast)


Lesenswert?

Dabei ist die Frage, was der Compiler für Code daraus generiert. Kannst 
du mal die List-Datei posten? Oder zumindest die relevanten Abschnitte?

von Mark (Gast)


Lesenswert?

so habe genung vom capture. geht auch so...
for(;;)
{
if (input(PIN_C2))
  set_timer1(0);
else
  x=get_timer1();

x=pulsweite
}

von Hans-Ulrich R. (Gast)


Lesenswert?

Geht so, ist aber ungenau (mißt zu wenige Takte), das der Timer nicht 
sofort die 0 übernimmt. Du solltest ins Datenblatt schauen, wie das mit 
dem Timer ist.

siehe
http://ww1.microchip.com/downloads/en/DeviceDoc/39625c.pdf
Seite 154 und folgende

von Mark (Gast)


Lesenswert?

Ich messe eine Frequenz von 1-30Hz.

--------------------------------------------------
Messe 1ne Periode.

for(;;)
{

if (input(PIN_C2)&&(s==0))
  {
  z=0;
  y=0;
  set_timer1(0);
  s=1;
  }

if ((input(PIN_C2)==0)&&(s==1))
  {
  s=2;
  }
if (input(PIN_C2)&&(s==2))
  {
  x=get_timer1();
  s=0;
  }
Nebenbei wird noch der Timerüberlauf mittels interupt ausgewertet.

----------------------------------------------

Der Timerüberlauf beträgt bei 1Hz(Pulsgenerator einstellung) ca. 152 und 
bei ca 30Hz(Pulsgeneratoreinstellung) ca. 2
Nun muss ich wissen wie lange ein Takt des Timmers ist.
Könnt ihr mir helfen?
Also ich denke....
Quarz des PIC18F4680 = 10MHz.
Intern im Pic wird mit 4Mhz gearbeitet... glaube ich
Timer Vorteiler habe ich keinen.
Also wird im PIC alle (1/4000000=0.25uS)0.25uS eins zum Timers addiert 
bzw. ein Befehl ausgeführt?


Das heisst für die 150 mal Überlauf gilt:
152*65535=9830250 Takte für eine Periode
9961320*0.25uS= Zeit für eine Periode = 2.5s??

von Hans-Ulrich R. (Gast)


Lesenswert?

Laut Datenblatt:
The operating mode is determined by the clock select
bit, TMR3CS (T3CON<1>). When TMR3CS is cleared
(= 0), Timer3 increments on every internal instruction
cycle (Fosc/4).

Also 10 MHz/4 = 2,5 MHz.

von Hans-Ulrich R. (Gast)


Lesenswert?

Sorry, das Zitat redet ja von Timer3...

Ist aber trotzdem Fosc/4, siehe Datenblatt Seite 154

von Mark (Gast)


Lesenswert?

ok ich rechne mal...

Quarz =10MHz =Fosc
Timerfrequenz= Fosc/4 ; 10000000/4=2500000Hz
1/f=sek ; 1/2500000Hz= 0.4uS/Takt.

Für 1Hz(Pulsgenerator)misst der Pic 5*Timerüberlauf für eine Periode.
5*Timerüberlauf* s/Takt = Time
5*65535*0.0000004s=0.6553s
sollte aber 1s sein. Wo ist mein Rechnungsfehler?

von Mark (Gast)


Lesenswert?

KORREKTUR: FÜR 1HZ MISST der PIC 152*Timerüberlauf

von Mark (Gast)


Lesenswert?

ok ich rechne mal...

Quarz =10MHz =Fosc
Timerfrequenz= Fosc/4 ; 10000000/4=2500000Hz
1/f=sek ; 1/2500000Hz= 0.4uS/Takt.

Für 1Hz(Pulsgenerator)misst der Pic 152*Timerüberlauf für eine Periode.
152*Timerüberlauf* s/Takt = Time
152*65535*0.0000004s=3.9845s
sollte aber 1s sein. Wo ist mein Rechnungsfehler?

von Hans-Ulrich R. (Gast)


Lesenswert?

Hast du vielleicht die PLL an, sodaß der Takt in Wirklichkeit 40 MHz 
ist?

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.