mir ist kein wirklich gutes Subjekt eingefallen, daher habe ich es mal sehr allgemein formuliert. Ihr wisst sicher, dass ich als Newbie etwas Probleme habe, das was ich will auch in Worte/Begrifflichkeiten zu fassen,
die µC-kompatibel sind. Daher finde ich es auch schwer mir Antworten zu ergooglen (klar, wenn schon die Frage schlecht formuliert ist :-)
Was will ich ?
Ich möchte für einen Zeitabschnitt/Periode (nehmen wir hier mal 1msec)
analoge Werte via ADC sampeln. Die werden aufaddiert und dann der Mittelwert für diese Periode berechnet. Die Anzahl der Samples sei erst mal egal, Hauptsache ist, dass die Periode (relativ) exakt eingehalten wird.
Da es bei µC keinen Systemzeit/etc gibt wäre ein (grober Algorithmus ungefähr folgender :
1 Starte einen Timer/Zähler
2 Lese die Werte aus dem ADC ein
3 Wenn der Zähler abgelaufen ist : Mittelwertberechnung und dann etwas Programmlogik.
4 Zurück zu 1
Für euch sicher kein Problem mir dieses Vorgehen etwas genauer zu beschreiben, bzw C-Codefragmente, Tutorials oder ähnliches als Hilfe beizusteuern ?
Hallo
Du könntest dich an dein Problem herantasten. So machen das im Allgemeinen alle. Zuerst mal ein ADC-programm zum Laufen bringen, dann einen Timer und dann beides verbinden. Weiss nicht, ob dein PIC vom MCC unterstützt wird, sonst kannst du da schon mal die Basis-Funktionen bekommen. Arbeitest du mit MPLAB X und dem XC8?
Hallo
Du könntest dich an dein Problem herantasten. So machen das im
Allgemeinen alle. Zuerst mal ein ADC-programm zum Laufen bringen, dann
einen Timer und dann beides verbinden. Weiss nicht, ob dein PIC vom MCC
unterstützt wird, sonst kannst du da schon mal die Basis-Funktionen
bekommen. Arbeitest du mit MPLAB X und dem XC8?
Gruß
Klar, aber manchmal möchte ich mich etwas schneller herantasten.
ADC habe ich soweit fertig, dass ausgelesen werden kann.
Der PIC wird von MCC unterstützt, Basis ist da, Begriffe wie FOSC FOSV4 etc
finde ich verwirrend ....
Im Moment scheint mir folgender Link zur Timerprogrammierung vielversprechend:
https://deepbluembedded.com/timer-modules/
Ein allgemeines Problem bei der Suche nach Tutorials ist, dass viele schon irgendwie outdatet sind und man das erst merkt, wenn man viel Zeit verbraten hat.
Komme ich mit der "The general formula for Timer1 Module .." zum Ziel eine
Periode von 1msec zu implementieren ?
man muss versuchen das Grundprinzip zu verstehen, weil das Prinzip ist immer gleich. Leider finde ich auch für andere PICs keine Timer AppNote. Aber 3 Anleitungen auf Youtube. Ob die qualitativ gut sind weiß ich nicht, wäre jedenfalls ein Anfang.
Auch wenn die sich nicht explizit auf deinen µC Typ beziehen kann man das adaptieren. Die Registernamen sollten gleich bzw. ähnlich sein. Mit einmal Timer Kapitel lesen im Manual sollte eine Anpassung möglich sein. Du musst verstehen was die warum machen und notfalls die gleiche Funktionalität in den Registern zusammensuchen. Also versteife dich nicht so sehr auf die Register- und Bitnamen.
man muss versuchen das Grundprinzip zu verstehen, weil das Prinzip ist
immer gleich. Leider finde ich auch für andere PICs keine Timer AppNote.
Aber 3 Anleitungen auf Youtube. Ob die qualitativ gut sind weiß ich
nicht, wäre jedenfalls ein Anfang.
Auch wenn die sich nicht explizit auf deinen µC Typ beziehen kann man
das adaptieren. Die Registernamen sollten gleich bzw. ähnlich sein. Mit
einmal Timer Kapitel lesen im Manual sollte eine Anpassung möglich sein.
Du musst verstehen was die warum machen und notfalls die gleiche
Funktionalität in den Registern zusammensuchen. Also versteife dich
nicht so sehr auf die Register- und Bitnamen.
Danke für die Links.
Wie (fast immer) behandelt man in den Tutorials die Erzeugung eines "genauen" delays. Ich habe aber nach so etwas wie "Solange 1msec noch nicht vorbei ist" gesucht, denn in delays mit beliebigen Schleifen wird einfach nur "sinnlos" Zeit verbraten. Im Grunde genommen implementiere ich eine primitive Nebenläufigkeit mittels Zeitscheiben. Also so etwas wie:
1
wiederholeunendlich
2
{
3
EinePeriodeTask1
4
EinePeriodeTask2
5
...
6
EinePeriodeTaskN
7
}
Mit Hilfe von MCC habe ich nun folgendes gemacht:
o es wird eine Flagvariable instantiert, die mir zeigen soll, wenn eine Periode (hier: 1msec) abgelaufen ist:
1
volatileboolperiodFinished=false;
o Timer0 wird so konfiguriert , dass er nach 1msec einen Interrupt auslöst
1
voidTMR0_Initialize(void)
2
{
3
// Set TMR0 to the options selected in the User Interface
4
5
// PSA not_assigned; PS 1:2; TMRSE Increment_hi_lo; mask the nWPUEN and INTEDG bits
o in der zugeordneten ISR wird ein Flag auf true gesetzt, wenn die msec vorbei ist.
1
voidTMR0_DefaultInterruptHandler(void){
2
periodFinished=true;
3
}
Jedes mal, wenn ich im main einen Programmzweig habe, der genau eine
Periode dauern soll wird davor der Timer neu initialisiert
und dann solange der Zweig abgearbeitet, bis die Periode vorbei ist
1
while(!periodFinished)
2
{
3
// TuwasSinvolles};
4
}
Was ich noch nicht gut gelöst habe ist, dass ich jedes mal den Timer neu initialisiere. Mir wäre eine startTimer und eine stopTimer-Function lieber.
Also:
o Initialisieren des Timers am Anfang von main()
Schleife :
a) Aufruf von startTimer wenn eine Periode Arbeit anliegt
b) Arbeiten bis Periode vorbei : (periodFinished == true)
c) danach kann der Timer erst mal ruhen : stopTimer
d) zurück zu a)
So könnte ein startTimer stopTimer aussehen:
1
voidstartTimer()
2
{
3
periodFinished=false;
4
IrgendwiedenTimerstarten
5
}
6
7
voidstopTimer()
8
{
9
IrgendwiedenTimerstopen/einfrierendeaktivieren
10
}
Wenn mir jemand einen Tipp geben könnte, wie ich start/stopTimer implementiere
wäre ich sehr dankbar.
Ich weiss nicht, warum du dich so gegen das Lesen des datenblattes sperrst.
Dieser PIC z.B. hat für mich eine Besonderheit, da der Timer0 nicht gestoppt oder gestartet werden kann. Der Timer 1 schon. T1CONbits.TMR1ON = 1; startet den Timer. Aber wenn du so eine Abneigung gegen Datnblätter hast, wäre Arduino oder ein anderer Compiler, wo es für alle Funktionen eine Funktion in einer C-Bibliothek gibt, besser für dich geeignet.
Ich weiss nicht, warum du dich so gegen das Lesen des datenblattes
sperrst.
Dieser PIC z.B. hat für mich eine Besonderheit, da der Timer0 nicht
gestoppt oder gestartet werden kann. Der Timer 1 schon. T1CONbits.TMR1ON
= 1; startet den Timer. Aber wenn du so eine Abneigung gegen Datnblätter
hast, wäre Arduino oder ein anderer Compiler, wo es für alle Funktionen
eine Funktion in einer C-Bibliothek gibt, besser für dich geeignet.
Gruß
Ich sperre mich nicht, ich decodiere vdie Datenblätter nicht exakt genug.
:-)
Danke für den Hinweis
Hauptsache ist, dass die Periode (relativ) exakt eingehalten
wird.
Nun, das ist kein Problem, da die ADCs mit konstantem Takt laufen. Du läßt also den ADC durchlaufen, zählst die Anzahl der ADC-Interrupts mit und hast damit eine konstante Periode.
In den ADC-Interrupts addierst Du die Ergebnisse auf und teilst sie z.B. alle 256 Wandlungen /256, d.h. schmeißt das untere Byte der Summe weg.
Mir scheint bisher das ganze recht wenig zielgerichtet.
Im Datenblatt 20.2.5 AUTO-CONVERSION TRIGGER sind unter anderem die Timer 2,4,6 sowie die beiden CCP Module gelistet, welche bei einem Match (Timer == Periode, bzw. Compare) den ADC automatisch periodisch starten können.
Wenn der ADC fertig ist löst er, sofern entsprechend konfiguriert, einen Interrupt aus und man kann den Wert abspeichern bzw. aufaddieren
Dabei zählt man einfach mit, wie viele Werte man schon hat, berechnet bei entsprechender Anzahl den Mittelwert...
Mir scheint bisher das ganze recht wenig zielgerichtet.
Im Datenblatt 20.2.5 AUTO-CONVERSION TRIGGER sind unter anderem die
Timer 2,4,6 sowie die beiden CCP Module gelistet, welche bei einem Match
(Timer == Periode, bzw. Compare) den ADC automatisch periodisch starten
können.
Wenn der ADC fertig ist löst er, sofern entsprechend konfiguriert, einen
Interrupt aus und man kann den Wert abspeichern bzw. aufaddieren
Dabei zählt man einfach mit, wie viele Werte man schon hat, berechnet
bei entsprechender Anzahl den Mittelwert...
Das liest sich wie ein gutes Verfahren, ich werde es bei einer Optimierung des Programms ausprobieren. Im Moment liegt mein Focus darauf zu testen, ob meine Idee funktionieren könnte, es ist (noch) unoptimiert und relativ geradeaus implementiert.