Grüße in die Runde, gibt es hier Leute, die sich "sehr gut" mit dem PIC18F/ MPLAB X IDE und ADC Interrupt´s auskennen? Pic's werden ja nicht gerade oft hier behandelt :-( Danke schon mal.
Es geht so. Also JA. Das war aber bestimmt nicht deine Frage...
Grüße, mal sehen ob ich mit meinem Problem / Verständnis weiter komme. Ich habe den ADC als Interrupt im MCC aktiviert und im automatisch generierten File taucht neben Timer ISR auch der ADC ISR auf. interrupt_manager.c else if(PIE1bits.ADIE == 1 && PIR1bits.ADIF == 1) { ADC_ISR(); } Nun habe ich meine eigene ADC ISR im main.c definiert (genauso wie für TMR0-3). void My_ADC_ISR(void); //ADC ISR ADC_SetInterruptHandler (My_ADC_ISR); //Register the interrupt Handler Im Programm habe ich eine Variable definiert, welche mir bei Erreichen des jeweiligen Channel die Variable anpasst, damit, wenn der ISR auslöst, ich weiß, welcher Channel den Wert bringt. ADC_StartConversion(BatterySignal); //AN4 No_ADC = 4; In der ADC ISR wird folgendes gemacht. void My_ADC_ISR (void){ //ADC ISR if (No_ADC == 0) { ThrottleSignalValue = ADC_GetConversion(ThrottleSignal); } if (No_ADC == 1) { LDRSignalValue = ADC_GetConversion(LDRSignal); } if (No_ADC == 2) { CurrentSignalValue = ADC_GetConversion(CurrentSignal); } if (No_ADC == 4) { BatterySignalValue = ADC_GetConversion(BatterySignal); } //LED_Toggle(); } Leider wurde mit Einfügen des ADC Interrupt irgendwas bewirkt, dass jetzt sogar ein LCD Text vor der while (1) Schleife nicht mehr angezeigt wird. Gern kann ich auch den gesamten Code posten, falls gewünscht. Wo liegt mein Fehler? Danke.
Daniel E. schrieb: > ADC Interrupt´s Daniel E. schrieb: > Pic's werden ja nicht gerade oft hier behandelt Dafür werden Deppenapostrophen hier gerne "behandelt". Bitte keine solchen. http://www.deppenapostroph.info
Daniel E. schrieb: > ThrottleSignalValue = ADC_GetConversion(ThrottleSignal); Heißt das nicht 'ADC_GetConversionResult();'? Ich vermute Du hängst in einer ADC IRQ Endlosschleife, weil Du den ADC Wert nie abholst und der IRQ deshalb weiter ansteht. Deshalb immer den ADC lesen und dann entscheiden was damit zu tun ist. In Deiner Konstruktion landest Du im endlos IRQ sobald kein Vergleich triggert. Um sowas zu checken setze ich einen 'idle' Debug Pin in der Main, das in jeder IRQ Routine rückgesetzt wird. So sehe ich auf dem Oszi wie viel freie zeit die MCU noch hat und wenn der dauernd Low wird, komme ich aus einem IRQ nicht mehr raus. Warum eigentlich das? > ADC_StartConversion(BatterySignal); //AN4 > No_ADC = 4; Du definierst eine extra Variable um herauszufinden auf welchem Channel der ADC steht? Das steht doch im channel selection register. Bist Du Dir mit der Syntax sicher? In meiner Erinnerung wird der channel gesetzt, dann der ADC gestartet, dann auf ADC fertig gewartet und dann wird gelesen. Das ADC start UND channel selection in einem Aufruf geschieht, daran kann ich mich nicht erinnern.
Grüße in die Runde und Danke. Ich habe mich hier orientiert: https://microchipdeveloper.com/projects:mcu1101-project-3 anderseits wird in dem Video hier dein Begriff "ADC_GetConversionResult();" https://www.youtube.com/watch?v=4WaB_Lj8FnY verwendet. Ich hab mal das mcc file vom ADC angehangen. Lassen wir mal den Begriff erstmal außen vor.... Woher weiß ich, wenn ich aus der Main raus springe in die ADC ISR, welcher channel grad dran ist und wie bekomme ich deiner/eurer Meinung nach den richtigen Wert in die entsprechende Variable ? Irgendwie steh ich da auf dem Schlauch.... Danke.
Daniel E. schrieb: > Irgendwie steh ich da auf dem Schlauch.... Lös Dich mal von den ADC LIB Funktionsaufrufen und schau Dir die ADC Register an. Du schreibst da rein auf welchem Channel der messen soll und das steht da auch noch drin bis du was anderes reinschreibst. Und was da drinsteht kannst Du auch wieder lesen. Diese Lib Funktionen machen mit viel gechecke und rumgedödel ganz simple Sachen mit der Hardware. Ich finde das meist leichter direkt mit den Registern zu arbeiten. Das Problem an all dieses schicken GUI Hilfen ist für Dich gerade das Du so weit weg von der HW bist, das Du nur Checkboxen und Funktionsaufrufe siehst. Dahinter sind aber ganz langweilige Bits in irgendwelchen Registern und dieses ganze Bling Bling hält Dich davon ab auch mal ins DB und Family reference Datasheet zu sehen, wo die HW ganz exakt beschrieben ist die Du gerade hardwarenah betüterst.
Grüße und Danke. Mit deinem ADC_GetConversionResult(); liegts Du richtig. void ADC_StartConversion(adc_channel_t channel) mit der Funktion wird ja schon der Kanal und ADC eingeschaltet und die Wandlung gestartet. Damit brauch ich nur noch das Ergebnis abzuholen. adc_result_t ADC_GetConversionResult(void) { // Conversion finished, return the result return ((adc_result_t)((ADRESH << 8) + ADRESL)); } Mir ist noch nicht klar, unabhängig der noch anderen unklaren Punkte, warum Ich vermute Du hängst in einer ADC IRQ Endlosschleife, weil Du den ADC Wert nie abholst und der IRQ deshalb weiter ansteht. Selbst wenn ich den Wert nicht abhole, setzt doch die ADC ISR das Flag zurück bis es vom nächsten Event wieder aktiviert wird oder ? void ADC_ISR(void) { // Clear the ADC interrupt flag PIR1bits.ADIF = 0; if(ADC_InterruptHandler) { ADC_InterruptHandler(); } } void ADC_SetInterruptHandler(void (* InterruptHandler)(void)){ ADC_InterruptHandler = InterruptHandler; } In der Main starte ich den ADC wie folgt ADC_StartConversion(LDRSignal); //AN1 wäre dies der nun der richtiges ADC ISR Inhalt ? if(channel == LDRSignal) { LDRSignalValue = ADC_GetConversionResult; } Falls ich falsch liege, gern auch bitte ein Codebeispiel, damit wird evtl. das Problem eher gelöst ;-) Danke.
Ich rate dir, den Microchip Code Configurator MCC zu installieren und zum Testen zu nutzen. Dort kannst Du die ADC Funktionalität aktivieren und der Configurator erzeugt dir Code. Zugegeben, er generiert einen A...-voll Overhead, aber ich habe noch nie erlebt, dass er nicht funktioniert. Dort kannst Du Dir anschauen wie es gemacht wird. Dann kannst Du den Code optimieren, d. h. den ganzen überflüssigen Rotz rausschmeißen. Ich benutze den ganz gerne gerade für die grundlegende Konfiguration (Oszillator, etc.) und wenn der PIC Reserven hat, fass ich den generierten Code auch nicht an. Zusätzlich unbedingt das Datenblatt konsultieren und verstehen. Gerade die ADC haben ein bestimmtes Timing.
Hey Runtervoter, kannst Du mal begründen, was an meinem Beitrag auszusetzen ist?
Du hast den Thread nich gelesen! Dein Beitrag ist vollkommen unnötig, überflüssig..... Hier einfach des Lesens nicht wert.
Daniel E. schrieb: > Selbst wenn ich den Wert nicht abhole, setzt doch die ADC ISR das Flag > zurück bis es vom nächsten Event wieder aktiviert wird oder ? Was sagt das DB dazu? Hör auf zu vermuten. Fang an zu lesen! Einige Flags werden gelöscht wenn man die Buffer-Register betütert, andere muss man selber löschen. Tut man beides nicht ist man eben in einer Endlosschleife. Nochmal: Du bist bare metal unterwegs. Keine Lib, kein geheimer Zauber macht hier was für Dich, wenn Du selber es nicht tust. Und wenn man Hardwarenah programmieren will MUSS man die Hardware auch kennen. Also fang doch mal an die kennenzulernen.
Danke an ein Paar Posts für nichts! Meine Anfangsfrage war, kennt sich jemand mit dem PIC aus und nicht, wo kann ich was nachlesen. Trotzdem Danke!
Daniel schrieb: > Meine Anfangsfrage war, kennt sich jemand mit dem PIC aus und nicht, wo > kann ich was nachlesen. Mal ehrlich: Du bleibst besser beim Arduino und lässt Dir von den Libs den Hintern nachtragen. Hardwarenah programmieren wollen aber vollkommen unwillig die Beschreibung der Hardware zu lesen passt so garnicht zusammen. Was erwartest Du? Das wir für Dich das DB zu diesem speziellen PIC lesen und Dich an die Hand nehmen? Klar kenne ich PICs. Meinst Du ich muss nicht ganz oft ins DB sehen?
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.