Hallo miteinander Als stillschweigender mikrocontroller.net-Leser habe ich eine Frage und hoffe, mir kann jemand helfen. Und zwar arbeite ich aktuell an einem LCR-Messgerät. Kurz zum Aufbau: L wird in der bekannten Schwingkreisbeschaltung mit dem LM311 eingesetzt - der Ausgang wird an RA4 des Mikrocontrollers gelegt, um die Impulse zu zählen (Frequenz). C wird mit dem Baustein 74HC4046A bestimmt, auch hier wird RA4 als Zähleingang verwendet. R wird über einen ADC (mit Spannungsteiler inkl. Bereichsumschaltung über zuschaltbaren Widerstand) gemessen. Insgesamt bereitet mir die Messung der Induktivität die meisten Schwierigkeiten. Wie gehe ich da am besten vor, also Timer starten, messen, Timer stoppen etc..? Arbeite mit dem CCS Compiler, aber die Hilfe von euch muss nicht in Code-Form sein, ein simpler Ablaufbeschrieb reicht eigentlich. Habe bereits im Internet gesucht, aber so richtig klar ists mir nicht... Sofern nötig, könnte ich auch Schemaausschnitte anhängen. Vielen Dank für eure Hilfe. Gruss
Exodus schrieb: > Hallo miteinander > > Als stillschweigender mikrocontroller.net-Leser habe ich eine Frage und > hoffe, mir kann jemand helfen. > > Und zwar arbeite ich aktuell an einem LCR-Messgerät. > Kurz zum Aufbau: > > L wird in der bekannten Schwingkreisbeschaltung mit dem LM311 eingesetzt > - der Ausgang wird an RA4 des Mikrocontrollers gelegt, um die Impulse zu > zählen (Frequenz). > > C wird mit dem Baustein 74HC4046A bestimmt, auch hier wird RA4 als > Zähleingang verwendet. > > R wird über einen ADC (mit Spannungsteiler inkl. Bereichsumschaltung > über zuschaltbaren Widerstand) gemessen. > > Insgesamt bereitet mir die Messung der Induktivität die meisten > Schwierigkeiten. > > Wie gehe ich da am besten vor, also Timer starten, messen, Timer stoppen > etc..? > Arbeite mit dem CCS Compiler, aber die Hilfe von euch muss nicht in > Code-Form sein, ein simpler Ablaufbeschrieb reicht eigentlich. > Habe bereits im Internet gesucht, aber so richtig klar ists mir nicht... > Sofern nötig, könnte ich auch Schemaausschnitte anhängen. > > Vielen Dank für eure Hilfe. > > Gruss Hallo Exodus, Fuer Zeitmessungen wird normalerweise am besten die CAPTURE hardware verwendet. Dazu musst Du zuerst die Zeitbasis mit einem der TIMER festlegen. Mittels Interupt kann man dann den Zaehlerstand ablesen. Sehe Dir mal den Beispiel File an: "EX_CCPMP.C". (Findest Du im PICC compiler Directory) __________________ | | ---------- -------------------- R.E. F.E. Damit kannst Du direkt die Zeitdauer eines Signal messen. mfg, Gerhard #if defined(_PCM_) #include <16F877.h> #fuses HS,NOWDT,NOPROTECT,NOLVP #use delay(clock=20000000) #use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7) #elif defined(_PCH_) #include <18F452.h> #fuses HS,NOWDT,NOPROTECT,NOLVP #use delay(clock=20000000) #use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7) #endif long rise,fall,pulse_width; #int_ccp2 void isr() { rise = CCP_1; fall = CCP_2; pulse_width = fall - rise; // CCP_1 is the time the pulse went high } // CCP_2 is the time the pulse went low // pulse_width/(clock/4) is the time // In order for this to work the ISR // overhead must be less than the // low time. For this program the // overhead is 45 instructions. The // low time must then be at least // 9 us. void main() { printf("\n\rHigh time (sampled every second):\n\r"); setup_ccp1(CCP_CAPTURE_RE); // Configure CCP1 to capture rise setup_ccp2(CCP_CAPTURE_FE); // Configure CCP2 to capture fall setup_timer_1(T1_INTERNAL); // Start timer 1 enable_interrupts(INT_CCP2); // Setup interrupt on falling edge enable_interrupts(GLOBAL); while(TRUE) { delay_ms(1000); printf("\r%lu us ", pulse_width/5 ); } } Damit diese Beispiel funktioniert musst Du das Eingangsignal an PIN-C1 und C2 anschliessen. Mit einer kleinen Programmaenderung geht das auch mit nur einem Eingang.
Hallo Danke erstmal für die Antwort. Das "Problem" ist, dass die Hardware schon fertig ist und auch bestückt - kann also die Anschlussbelegung nicht mehr ändern. Als ich die Schaltung entworfen habe (und auch jetzt noch), war ich der Meinung dass das Ganze über RA4 relativ elegant machbar ist. Hab entsprechende Beispiele auch schon gesehen, aber das Ganze will nicht wirklich.. Hier hab ich noch einen Code-Schnippsel von mir:
1 | void c_measure(void) |
2 | {
|
3 | int8 prescaler = 0; |
4 | disp_delete (); |
5 | ueberlauf = 0; |
6 | |
7 | setup_timer_0(RTCC_EXT_L_TO_H|RTCC_DIV_256); |
8 | enable_interrupts(INT_RTCC); |
9 | enable_interrupts(GLOBAL); |
10 | |
11 | //Grobmessung mit einem Vorteiler von 256 und t=256us
|
12 | //Ergebnis in MHz
|
13 | //Anhand dieser Messung wird der Vorteiler bestimmt
|
14 | |
15 | set_timer0 (0); |
16 | delay_us(256); |
17 | timer_0 = get_timer0(); |
18 | //timer_0 = timer_0 + (ueberlauf * 256);
|
19 | ueberlauf = 0; |
20 | |
21 | //Bestimmung des Vorteilers
|
22 | if (timer_0>=2) |
23 | {
|
24 | setup_timer_0(RTCC_EXT_L_TO_H|RTCC_DIV_2); |
25 | prescaler = 2; |
26 | }
|
27 | if (timer_0>=4) |
28 | {
|
29 | setup_timer_0(RTCC_EXT_L_TO_H|RTCC_DIV_4); |
30 | prescaler = 4; |
31 | }
|
32 | if (timer_0>=8) |
33 | {
|
34 | setup_timer_0(RTCC_EXT_L_TO_H|RTCC_DIV_8); |
35 | prescaler = 8; |
36 | }
|
37 | if (timer_0>=16) |
38 | {
|
39 | setup_timer_0(RTCC_EXT_L_TO_H|RTCC_DIV_16); |
40 | prescaler = 16; |
41 | }
|
42 | if (timer_0>=32) |
43 | {
|
44 | setup_timer_0(RTCC_EXT_L_TO_H|RTCC_DIV_32); |
45 | prescaler = 32; |
46 | }
|
47 | else
|
48 | {
|
49 | prescaler = 1; |
50 | setup_timer_0(RTCC_EXT_L_TO_H); |
51 | }
|
52 | |
53 | //Genaue Messung mit korrektem Vorteiler
|
54 | set_timer0 (0); |
55 | delay_ms(500); |
56 | timer_0 = get_timer0(); |
57 | timer_0 = (timer_0 * 2) + (ueberlauf * prescaler); |
58 | ueberlauf = 0; |
59 | }
|
Ist dieser Ansatz korrekt..? Gruss
Ich bins nochmal, hab gerade noch einmal versucht das ganze in Betrieb zu nehmen. Die Software zur Messung von L sieht im Moment so aus:
1 | ueberlauf = 0; |
2 | setup_timer_0(RTCC_EXT_H_TO_L|RTCC_DIV_32); |
3 | enable_interrupts(INT_RTCC); |
4 | enable_interrupts(GLOBAL); |
5 | |
6 | set_timer0 (0); |
7 | delay_ms(1000); |
8 | disable_interrupts(INT_RTCC); |
9 | timer_0 = get_timer0(); |
10 | timer_0 = timer_0 + (ueberlauf * 32); |
In der Interruptroutine von TIMER0 wird jedesmal die Variable "ueberlauf" inkrementiert. Nun sollte das Ergebnis eine Frequenz in Hz sein, oder? Wie rechne ich jetzt zurück auf die Induktivität? Wäre echt super, wenn mir hier jemand dabei helfen könnte... Danke und Gruss
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.