PIC wacht nicht auf durch AD Interrupt
Mittwoch, 23. Mai 2012
 
 

PIC Mikrocontroller Forum  |  PIC Mikrocontroller  |  CCS Compiler  |  AD-Wandler (CCS)  |  PIC wacht nicht auf durch AD Interrupt « vorheriges nächstes »
Seiten: [1] Nach unten Drucken
Autor Thema: PIC wacht nicht auf durch AD Interrupt  (Gelesen 2666 mal)
 
Michael
Newbie
*
Offline Offline

Beiträge: 18


Profil anzeigen
« am: Oktober 12, 2009, 09:58:49 »

howdiho

Ich bastel gerade ein Thermometer (PT100).
Wenn ich einfach eine endlosschleife nutze funktiniert die ad-wandlung ohne probleme

Allerdings will ich möglichst wenig strom verbrauchen (Batterie) und beim start der adc den pic schlafen legen und ihn durch den ad-interrupt aufwachen lassen.
das sieht so aus:
Code:
while(1)
   { 
   disable_interrupts(GLOBAL); //alle interupts deaktivieren
   enable_interrupts(INT_AD);  //ad interrupt aktivieren
   clear_interrupt(INT_AD);    //interruptflag löschen
   read_adc(ADC_START_ONLY);   //adc starten
   sleep();                    //pic schlafen legen
   disable_interrupts(GLOBAL); //interrupts deaktivieren nach dem aufwachen
   adwert=read_ADC(ADC_READ_ONLY); //wert auslesen
   advolt=0.019607843*adwert;  //als Volt ans diplay
   sprintf(text,"%1.2fV       ",advolt);  //in char umwandeln
   display(text);             //ans LCD schicken
   delay_ms(800);             //0,8s warten (temp lösung wird durch timer3 ersezt)
   clear_display();           //display löschen
   }
}

Das problem ist, der pic wacht nicht auf Traurig

hat vlt jemand eine idee?
ach ja
Code:
setup_adc_ports(AN0);            //AD-Pin festlegen
setup_adc(ADC_CLOCK_INTERNAL);   //internen takt für ad-wandler nutzen
das ist meine ad initialisierung
Gespeichert
Stampede
Globaler Moderator
Hero Member
*****
Offline Offline

Beiträge: 969



Profil anzeigen WWW
« Antworten #1 am: Oktober 12, 2009, 13:55:32 »

Hallo,

welchen PIC nutzt du?
Wenn du den PIC schlafen legst, kannst du einstellen, ob er beim Aufwachen den nächsten Befehl abarbeiten soll, oder in die ISR springt. Hast du das auch richtig eingestellt?

Gruß
Stefan
Gespeichert

Michael
Newbie
*
Offline Offline

Beiträge: 18


Profil anzeigen
« Antworten #2 am: Oktober 12, 2009, 16:05:11 »

Ich nutze nen PIC18f458

Wusste gar nicht, das man das einstellen kann.
Hatte mein auslesen der adwandlung auch schon in die isr geschrieben, aber der interrupt wird gar nicht erst ausgelöst.
Wenn ich ihn halten will, bringt er ne fehlermeldung und ich muss ihn resetten, also gehe ich davon aus, dass er zwar schläft, aber eben nicht mehr aufwacht, ergo kein interrupt ausgelöst wird.
Gespeichert
Coltfisch
Sr. Member
****
Offline Offline

Beiträge: 496



Profil anzeigen WWW
« Antworten #3 am: Oktober 12, 2009, 17:56:04 »

Wenn du den PIC schlafen legst, kannst du einstellen, ob er beim Aufwachen den nächsten Befehl abarbeiten soll, oder in die ISR springt. Hast du das auch richtig eingestellt?
Sieht eigentlich gut aus. Indem die Interrupts global deaktiviert werden und nur der Interrupt des ADCs aktiviert wird, sollte der PIC zwar aufwachen aber nicht in eine ISR springen. Eigentlich.
Ich habe mit den Wrapper-Funktionen des CCS C Compilers schon so einiges erlebt; Du solltest mal das Listfile Deines Programms posten bzw. selber nachsehen, ob das ADC-Interrupt-Flag überhaupt korrekt gesetzt wird.
Gleiches gilt für die Festlegung der Taktquelle des ADCs. Das Aufwachen funktioniert nur, wenn die interne RC-Taktquelle verwendet wird. Das hast Du zwar korrekt im Code vorgegeben, ob diese Einstellung allerdings auch im ADCON2-Register richtig ankommt, ist eine andere Frage...

Es ist beim CCS-Compiler grundsätzlich sicherer auf die Wrapperfunktionen zu verzichten und die Register von Hand zu beschreiben.

Du könntest Testweise noch einen externen Interrupt aktivieren und schauen, ob Du den PIC durch Triggern des entsprechenden Pins aus dem Schlaf erwecken kannst.

Zitat
Wenn ich ihn halten will, bringt er ne fehlermeldung und ich muss ihn resetten
Was meinst Du damit? Tritt das Problem nur im Debug-Modus auf?

Gruß
Daniel



Gespeichert
Michael
Newbie
*
Offline Offline

Beiträge: 18


Profil anzeigen
« Antworten #4 am: Oktober 13, 2009, 08:44:06 »

Also, hab das lst file durchforstet und mit dem datenblatt abgeglichen.
Ist alles einwandfrei.
Code:
....................    disable_interrupts(GLOBAL); //alle interupts deaktivieren
05F8:  BCF    FF2.6
05FA:  BCF    FF2.7
05FC:  BTFSC  FF2.7
05FE:  BRA    05FA
....................    enable_interrupts(INT_AD);  //ad interrupt aktivieren
0600:  BSF    F9D.6
....................    clear_interrupt(INT_AD);    //interruptflag löschen
0602:  BCF    F9E.6
....................    read_adc(ADC_START_ONLY);   //adc starten
0604:  BSF    FC2.2
....................    sleep();                    //pic schlafen legen
0606:  SLEEP
Werd jetz mal den externen interrupt testen
« Letzte Änderung: Oktober 13, 2009, 10:11:13 von Michael » Gespeichert
Michael
Newbie
*
Offline Offline

Beiträge: 18


Profil anzeigen
« Antworten #5 am: Oktober 14, 2009, 12:10:24 »

Ich hab das ganze prog noch einmal neu aufgesezt, um zu sehen, ob vlt irgend eine einstellung nicht richtig war...
ohne erfolg

Er wacht nicht auf oder der adc löst den interrupt nicht aus

Code:
#int_AD
AD_isr()
{
clear_interrupt(INT_AD);
}


int ad;

void main()
{

   setup_adc_ports(AN0);
   setup_adc(ADC_CLOCK_INTERNAL);
   setup_psp(PSP_DISABLED);
   setup_spi(FALSE);
   setup_wdt(WDT_OFF);
   setup_timer_0(RTCC_INTERNAL);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
   setup_comparator(NC_NC_NC_NC);
   enable_interrupts(INT_AD);
   enable_interrupts(GLOBAL);

while(1)
   {
   clear_interrupt(INT_AD);
   read_ADC(ADC_READ_ONLY);
   sleep();
   ad=read_ADC(ADC_READ_ONLY);
   }
}

Laufen die Timer wenn der pic schläft? Ich vermute mal nein...
Gespeichert
Coltfisch
Sr. Member
****
Offline Offline

Beiträge: 496



Profil anzeigen WWW
« Antworten #6 am: Oktober 14, 2009, 12:21:24 »

Zitat
Laufen die Timer wenn der pic schläft?
Ohne einen zusätzlichen Quarz - Nein.

Was hat der Test mit dem externen Interrupt gebracht?

Zeig mal ein vollständiges Testprogramm.
Gespeichert
Michael
Newbie
*
Offline Offline

Beiträge: 18


Profil anzeigen
« Antworten #7 am: Oktober 14, 2009, 13:02:19 »

Alles klar, die lösung ist einfach Oo

Man darf die Interrupts nicht global deaktivieren und danach nur den ad interrupt aktivieren ....

Also mit enable_interrups(GLOBAL) funktionierts ....
Gespeichert
Coltfisch
Sr. Member
****
Offline Offline

Beiträge: 496



Profil anzeigen WWW
« Antworten #8 am: Oktober 14, 2009, 13:41:56 »

Zitat
Man darf die Interrupts nicht global deaktivieren und danach nur den ad interrupt aktivieren ....
Aber sicher darf man das!
-> Datenblatt, Kapitel 24.3.1, "Wake-up from sleep":
Zitat
"...For the device to wake-up through an interrupt event, the corresponding
interrupt enable bit must be set (enabled). Wake-up is regardless of the state of the GIE bit. If the GIE bit is clear (disabled), the device continues execution at the instruction after the SLEEP instruction. If the GIE bit is set (enabled), the device executes the instruction after the SLEEP instruction and then branches to the interrupt address."

Das Aktivieren der globalen Interrupts behebt bei Dir vielleicht (zufällig) die Symptome, in Deinem Programm ist aber definitiv noch etwas anderes faul.
« Letzte Änderung: Oktober 15, 2009, 09:17:43 von Coltfisch » Gespeichert
Michael
Newbie
*
Offline Offline

Beiträge: 18


Profil anzeigen
« Antworten #9 am: Oktober 15, 2009, 13:34:32 »

Ich teste das morgen früh gleich mal.
Gespeichert
Edson
Globaler Moderator
Sr. Member
*****
Offline Offline

Beiträge: 373



Profil anzeigen
« Antworten #10 am: Oktober 15, 2009, 15:15:45 »

Hab das Thema wieder auf ungelöst gestellt.

Grüße,
Edson
Gespeichert
Seiten: [1] Nach oben Drucken 
« vorheriges nächstes »
Gehe zu:  

Powered by MySQL Powered by PHP Made for Mozilla (Firefox) Made for Internet Explorer
Seite erstellt in 0.035 Sekunden mit 18 Zugriffen.
 
Top! Top!