Hi,
ich möchte ein Event loggen (wenn Spannung über Schwellwert). Dazu
wollte ich den Comparator benutzen: der Interrupt des Comparators soll
dann einen Timer starten.
Der Timer bekommt seinen Takt vom internen Oszillator (16MHz) / 4 und
Prescale 16 sollte also mit 250Hz laufen. Kann man das ganze irgendwie
im Hintergrund laufen lassen, so dass die anderen Funktionen des PIC
nicht beeinträchtigt werden oder muss ich bei jedem Timerüberlauf die
Sekunden per Software berechnen und hochzählen?
Danke
Diotor schrieb:> Kann man das ganze irgendwie> im Hintergrund laufen lassen, so dass die anderen Funktionen des PIC> nicht beeinträchtigt werden oder muss ich bei jedem Timerüberlauf die> Sekunden per Software berechnen und hochzählen?
Wie von meinem Vorredner gesagt machen und dann für den Timerüberlauf
auch einen Interrupt ...
Danke für die Antworten, so wie ich das Versteh wäre die Umsetzung
folgende:
PSEUDOCODE
while(!ComparatorInterrupt);
TMR1ON
if(TMR1Interrupt)
...
somit könnte ich also den Zähler umsetzen, aber der PIC kann in dieser
Zeit z.B. kein I2C Protokoll sprechen. Darum wollte ich fragen ob der
Zähler hardwaremäßig im Hintergrund laufen kann, sprich parallel laufen
kann.
das Ganze mal in Pseudocode ohne Interrupt (die Register für den
Comparator habe ich jetzt mal nicht rausgesucht, weiss ich nicht
auswendig). Der Timer muss gf. noch den Startwert 0 erhalten.
1
do until comparator ; wait for comparator
2
loop
3
4
clear_bit PIR1, TMR1IF ; Timer 1 flag bit rücksetzen
Hi,
usuru schrieb:> das Ganze mal in Pseudocode ohne Interrupt (die Register für den> Comparator habe ich jetzt mal nicht rausgesucht, weiss ich nicht> auswendig). Der Timer muss gf. noch den Startwert 0 erhalten.>>
1
>
2
> do until comparator ; wait for comparator
3
> loop
4
>
5
> clear_bit PIR1, TMR1IF ; Timer 1 flag bit rücksetzen
6
> set_bit T1CON, TMR1ON ; Timer 1 starten
7
>
8
> do until PIR1, TMR1IF ; wait for Timer 1 Overflow
9
> loop
10
>
11
>
Das würde aber genau das bedeuten was der TE nicht will...
Die Blockade des sonstigen Programmablaufs.
Diotor schrieb:> somit könnte ich also den Zähler umsetzen, aber der PIC kann in dieser> Zeit z.B. kein I2C Protokoll sprechen. Darum wollte ich fragen ob der> Zähler hardwaremäßig im Hintergrund laufen kann, sprich parallel laufen> kann.
JA - das kann der PIC. Wie von anderen schon geschrieben - Du musst mit
Interrupt arbeiten.
Ich habe aber trotzdem noch nicht ganz kapiert was du vorhast...
Also klar ist: Der PIC überwacht eine Spannung, überschreitet diese den
Grenzwert, dann soll der Zähler gestartet werden...
Aber was soll dann passieren? Also was willst du nun auswerten? Die Zeit
die seit diesem Ereigniss verstrichen ist? DAs ist AUCH für den
folgenden Code von Bedeutung...
Aber hie rmal ohne Garantie auf korrekten Syntax wie ich das gerade im
Kopf habe. (Arbeite durchaus mit mehreren Prozessoren und habe keine
Lust jetzt genau nachzuschauen...)
#irgendetwas Codeähnliches
double zaehl
void main(void)
{
// Hier steht das Hauptprogramm
while(1)
{
void interrupt isr(void)
{
if (TMR1IF) // Hat der Timer 1 den Interrupt ausgelöst?
{
zaehl++
TMR1IF = 0; // Timer interrupt zurücksetzen
}
if (weitere Interrupabfrage) // {
...
...
...
}
}
Jetzt wird nach dem Start des Timer 1 bei jedem überlauf ein Interrupt
ausgelöst. während der Interruptbearbeitung wird der Zähler zaehl um
eins erhöht. Willst du dann irgendwann die Zeit wissen die seit der
Auslösung vergangen ist musst du "(zaehl*256)/250= Zeit in Sekunden"
berechnen.
Zwischen den einzelnen Interrups arbeitet der PIC normal weiter.
Selbst wenn du die Interruptbearbeitung kurzzeitig blockierst belibt
dein Zählergebniss sogar noch richtig solange die Pause nicht länger als
eine Überlaufperiode ist...
Aber vorsicht: ICh habe gerade mit heftigen Kopfschmerzen und Fieber zu
kämpfen. ggf. schreibe ich hier auch gerade Quatsch...
Gruß
Carsten
Ja genau will einfach die Zeit wissen wann die Spannungsspitze war.
Ist Interrupt ein Schlüsselwort oder wie muss ich den Code verstehen,
bzw wie wird die Interruptroutine aufgerufen?
Diotor schrieb:> Ja genau will einfach die Zeit wissen wann die Spannungsspitze war.> Ist Interrupt ein Schlüsselwort oder wie muss ich den Code verstehen,> bzw wie wird die Interruptroutine aufgerufen?
Ich bin jetzt davon ausgegangen das dir das bekannt ist, denn du hast ja
oben erwähnt das der Timerstart auch über den Comparatorinterrupt
geschehen soll.
ICh kenne deine Vorkenntnisse jetzt nicht, also auch nicht ob du z.b
etwas von der ASM Programierung der Pics verstehst...
Daher hier nur die Kurzform und anschließend der Verweis auf
Beispielcode samt Literatur ;-)
Also, intern läuft das mit dem Interrupt ja so ab, das der µC bei einem
Ereigniss welches einen Interrupt auslöst auf eine bestimmte
Speciherstelle im Programmspeicher springt und den Befehl der dort steht
ausführt. Bei den 16er Pics war dafür zum Beispiel 0004 üblich.
Bei 18F kenne ich jetzt 08 und 18. Bei dem 18er gibt es zwei
Interrupteinsprünge weil es zwei Prioritäten gibt... Weiteres unter den
Links...
Entweder geht nun an dieser Stelle die Interruptbearbeitung los, oder
man schreibt einfach einen Sprungbefehl zu einer Abarbeitungsroutine die
schlicht irgendwo im Code stehen kann.
Bei ASM ist das ganz einfach gewesen, da hat man im Editor einfach mit
dem Befehl ORG 004 die Speicherzelle ausgewählt und ab da
losgeschrieben.
(vorher von der Startadresse aber noch einen Sprung auf das
Hauptprogramm gemachtm also die Interruptbehandlung übersprungen)
Da war es auch noch recht übersichtlich alles direkt auf 04 folgen zu
lassen.
Bei C geht das nicht so ohne weiteres als C Befehl. (Zumindest habe ich
es anders gelernt)
Deshalb bindet man diesen einen Sprungbefehl als Assemblerbefehl ein und
setzt den an die Interruptadresse. Das Sprungziel hingegen ist aber der
Beginn einer C Funktion. Diese könntest du auch
"unterbrechungsabarbeitungsschleifevonmirselbst" nennen, passt nur nicht
zu den Konventionen, Libs und Programmstückchen zum einbinden. Daher
würde ich mich an die von Microchip vorgegebene Namensgebung halten.
Also zusammenfassend:
1. Die Interruptroutine ist eine von dir selbst erstellte Funktion die
nicht anders ist als andere Funktionen. Allerdings müssen in dieser
Funktion die Interruptflags abgefragt werden wenn man die Interrups
unterscheiden will - Und auch die Flags gelöscht werden, sonst geht es
gleich wieder los.
2. Rein kommt man über einen Sprungbefehl den man an einer festen Stelle
im Speicher ablegen muss. Das ist das Besondere am Interrupt !
Wie es jetzt genau geht, da schaue dir mal Übungsbeispiele ("Lesson
Files") an die man mit dem Pickit3 Debug Express bekommt. Diese kann man
frei runterladen, dürfte für alle 18er Pics identisch sein, mit den
Einsprungadressen müsstes du evtl noch mal im 13K50 Datenblatt
nachschauen (meine die waren aber gleich, bin mir abe rnicht sicher
-zuviele Proz in verwendung ;-) !)
Zu den "Lesson Files" bekommt man noch das Begleithandbuch in dem etwas
dazu erklärt ist. Die Lektionen bauen aufeinander auf, falls etwas unkla
sein sollte ggf. auch mal die Lektion vorher anschauen.
Du kannst sicher auch etwas Copy & Paste machen.
Die Files und das Handbuch findest du hier am ende der Seite:
http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1406&dDocName=en538340&redirects=pickit3
Du möchtest haben:
"PICkit 3 Debug Express Lesson Files"
"PICkit 3 Debug Express Lessons User's Guide"
Interrupt ist Abschnitt 8, habe gerade noch einmal nachgesehen
Davor mal zu schauen ist aber nicht verkehrt...
Ich hoffe das hilft dir weiter ;-)
Die Zeiterfassung solltest du dann selber hinbekommen.
Wenn du aber doch anregungen brauchst, auf Sprut.de gibt es Beispiele
für eine Uhr, sind zwar in ASM und für den 16er, aber die Grundidee kann
man dann auch auf C und 18er übertragen. Geht ja nur ums Prinzip.
Ausserdem möchte ich wetten im Netz findet sich auch was für C und 18er.
Bei den Sprut beispielen schätze ich aber das die wirklich rudimentär
sind, also nur das notwendige drin ist.
Ach ja: Wie genau soll die Uhr denn sein?
Soll die genauer als eine Sekunde sein musst du natürlich noch
zusätzlich zum Zähler in der Interruptbearbeitung auch noch bei der
Auswertung den momentanen Stand des TMR1 auslesen...
Gruß
Carsten
Hallo,
Schoener Post, Carsten.
Noch eine kurze Anmerkung zum Komparator:
Das Ding ist nur bedingt schnell. Neben dem eigentlichen Propagartion
Delay ist auch zu beachten, dass der Eingang ausreichend ueber dem
eingestellen Referenzpegel liegt und dass dies lange genug der Fall ist.
Das musst du bei deinem Signal bzw. dessen Auswertung reuecksichtigen.
Mal so ein Beispiel: Ich habe einen Komparator auf 3,5V Vref
eingestellt, und da ein 4 MHz Sinus drangehaengt, dessen Amplitude bei
rund 3,7V lag (DC Level 2,5V). Der Komparator hat das dann, auch nach
vielen Perioden, nicht erkannt. Wenn dein Signal aber deutlich langsamer
ist, ist das kein Problem.
Gruss,
Stampede