Forum: Mikrocontroller und Digitale Elektronik Kapazitätsmessgerät mit PIC16F877A bauen


von Oswald (Gast)


Lesenswert?

Hi Leute,

ich brauche etwas Hilfe bei meinem Projekt, ein Kapazitätsmessgerät zu
bauen mit einem PIC16F877A und einem LCD... Grundlage ist die Vorlage
von www.Sprut.de

Da ich aber in C mit den MikroC Pro für PIC programmiere, muss ich den
Quellcode umschreiben bwz. selbst schreiben.. Hier der

Programmablauf

    * Initialisierung der Ports
    * Initialisierung des ADC
    * Initialisierung des LCD-Displays

    *   Beginn der Endlosschleife.
    * Entladen:
          o RC0 auf output , RC0=low
          o in einer Schleife warten, bis ADC-Ergebnis <8 (<40 mV)
    * Kapazitätsregister auf 0 setzen
    * Timer0 auf 0,1733ms einstellen
    * Laden: RC0=high
    * Unterschleife
          o darauf warten, dass Timer0 überläuft:
          o Timer wieder auf 0,1733 ms einstellen
          o Spannung mit ADCmessen
          o wenn Spannung >2,5V, dann zu 'Anzeige' springen
          o Kapazitätsregister um 1 erhöhen
          o falls Kapazitätsregister überläuft, zu 'Anzeige' springen
          o Sprung zum Anfang dieser Unterschleife
    * Anzeige:
          o RC0 = input
          o Kapazität in BCD wandeln
          o BCD-Wert an LCD ausgeben
    * Sprung zum Beginn der Endlosschleife



Wie setze ich das mit dem Einlesen der analogen Spannung und dem
Zähler/Timer um ?

von Master S. (snowman)


Lesenswert?

> Timer0 auf 0,1733ms einstellen
verstehe ich nicht

vorschlag:

RC0--widerstand--+
                 |
ADC--------------+
                 |
                === C
                 |
                GND

RC0 ist immer ausgang, kann auch ein anderer pin sein
ADC ist immer eingang

programm-endlosschleife:
 - RC0 = 0
 - warten bis ADC < 40mV oder was auch immer
 - Timer0 auf 0 setzten
 - RCO = 1
 - warten bis ADC >= 2.5V oder was auch immer
 - Timer0 auslesen
 - wert von Timer0 umrechnen und anzeigen

> Wie setze ich das mit dem Einlesen der analogen Spannung und
> dem Zähler/Timer um ?
ADC: ich bin sicher, dass dein MicroC eine demo-datei bereit hät ;-)
Timer: siehe oben, ggf. falls dir der Timer0 zu schnell taktet, mit 
interrupt arbeiten, in der du eine variable hochzählst

von Oswald (Gast)


Lesenswert?

Sprut :"Ein µF entspricht einer Ladezeit von 0,1733 Millisekunden. 
10000µF entsprechen folglich 1,733 Sekunden. 5771µF entsprechen 1 
SekundeLadezeit. "

daher der Timer...ja die Demo gibt es! NUR wirft der immer nen Fehler 
aus bei der definition der PINS :  "Undeclared identifier 'ANSEL' in 
expression "

Bin da etwas überfragt. Ja der Ablauf is schon soweit im Kopf^^ Nur wie 
sage ich dem er soll die eit zählen bis die Spannung am Eingang xx 2,5 V 
hat? Die Umrechnung in einen Wert, der am LCD ausgegeben wird läuft auch 
schon..nur dieses Zwischenstück funzt net-.-

THX

von Master S. (snowman)


Lesenswert?

stell dir einen Timer0-interrupt vor, der jedes mal geschieht, wenn der 
Timer0 von 255 wieder auf 0 geht. da du den Timer0-takt kennst (1/4 des 
quarztaktes) weisst du, wieviele ms für so einen durchlauf benötigt 
werden. in diesem interrupt kannst du eine variable, nennen wir sie 
CountNumberOfInterrupts, hochzählen. wenn du also in deinem ablauf unter 
die 40mV kommst, tust du den Timer0 resetten (auf 0 setzen) und diese 
variable auch auf 0 setzen. dann beginnst du den kondensator zu laden 
und misst du kontinuierlich die spannung bis diese 2.5V erreicht. im 
hintergrund zählt der Timer0 immer wieder von 0-255 hoch und generiert 
jedes mal einen interrupt, in dem diese varable hochgezählt wird. bei 
erreichen der 2.5V liesst du diese variable aus und weisst somit, 
wieviel zeit verstrichen ist. aus der zeit kannst du auf die kapaziät 
schliessen.

Interrupt_Timer0() {
  CountNumberOfInterrupts++;
  Timer0-interrupt-flag zurücksetzen;
}

main() {
  alles inizialisieren
  MeasuredVoltage = 2500;
  while(1) {
    RC0 = 0; //kondensator wird entladen
    while (ADC > 8); // warten bis 40mV unterschritten werden
    Timer0 = 0;
    CountNumberOfInterrupts = 0;
    RC0 = 1; // kondensator wird geladen
    while (ADC < 500); // warten bis 2.5V überschritten werden
    wandle CountNumberOfInterrupts in anzahl uF um
    anzahl uF auf dem Display anzeigen
  } // while(1)
} // main()


ps: wenn du Timer1 oder noch besser Timer2 noch übrig hast, würde ich 
diesen nehmen: Timer1 ist ein 16bit und Timer2 kannst du perfekt 
konfigurieren..

von Peter D. (peda)


Lesenswert?

Hat denn der PIC keinen Analog-Komparator?

Mit dem kannst Du wesentlich genauer messen.

Der ADC holt Dir nur 2 zusätzliche Fehlerquellen mit rein, durch die 
begrenzte Auflösung und die benötigte Wandlerzeit.

Beim AVR kann man sogar das Input-Cature durch den Komparator triggern 
lassen, d.h. man kriegt eine Zeitauflösung die dem CPU-Takt entspricht.


Peter

von Master S. (snowman)


Lesenswert?

(fast) alle alten 16er PIC haben keinen comparator, die neueren 16er 
z.t. schon - ein grund mehr die 16er nie für neue projekte zu benutzen 
sondern gleich die 18er oder 24er. ..ich mag die PICs aber die PIC16xx 
kann ich echt nicht ausstehen - naja, das stand hier aber nicht zur 
diskussion.

bezüglich fehlerquelle: ich denke, da das programm immer gleich abläuft, 
gibts sowieso nur einen offset im wert, welcher man ggf. rausrechnen 
kann. bei genügend langsamer wandlung dürfte dies sowieso nicht sehr 
gravierend sein.

von Oswald (Gast)


Lesenswert?

Danke Master Snowman!!!

werde es mal ausprobieren...wenn man es so liest, klingt es recht 
einfach..

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.