Hat jemand eine Idee...?
Also ich nutze den das MPLAB X IDE V3.45 und dazu den XC8 Compiler Und schreibe dann die Interrupts so :
1 | void interrupt high_priority ISRH(void){ |
2 | |
3 | // Overflow von Timer_0 ?
|
4 | if (INTCONbits.TMR0IF){ |
5 | |
6 | //.... mache was ..... wenn Timer 0 Overflow ausgelöst hat
|
7 | |
8 | INTCONbits.TMR0IF=0; |
9 | }
|
10 | |
11 | }
|
und die define sind auch sehr unleserlich entweder man definiert es hexdezimal oder mit 1<<x Bsp.
1 | #define T1_ON 0x04
|
2 | |
3 | oder ... |
4 | |
5 | #define T2_ON 1<<4
|
3. Und kommt der SLEEP() Befehl nicht in die "main" ? Der PIC muss die ISR sauber verlassen und dann darf er schlafen geht, bin ich der Meinung. Ich benutze den PIC18F25K22, aber es sollte so ähnlich sein. das sollten Sie an ihrem Programm mal überprüfen. ggf. mal ins Datenblatt schauen ! Mfg
:
Bearbeitet durch User
Ich verstehe die ganzen #defines überhaupt nicht. Wenn der richtige
Prozessor im Projekt gesetzt ist, erledigt xc.h das alles automatisch.
Da kommt im eigenen Code so etwas gar nicht vor. Und da ist dann auch
sichergestellt, daß man ohne Compilerfehler nur SFRs bzw Bits benutzen
kann, die auf diesem Prozessor auch existieren.
Aber auch diese leuchtet mir nicht ein:
> TMR1H = 0x10000000;
TMR1H wird ja wohl kein 32 Bit Register sein.
MfG Klaus
Norbert S. schrieb: > Und kommt der SLEEP() Befehl nicht in die "main" ? Ich habe alles ausprobiert. Darum diese Variable InterruptDa.
Timer1 läuft mit dem externer 32768Hz Quarzoszillator. Diese TMR1H = 0b10000000; ist dazu um Interruptintervall auf 1 Sekunde zu Stellen (ohne das sind das 2 Sekunden). System Clock ist auf interne Oszillator mit 4Mhz gesetzt. Timer1 läuft und externer Signal von 32768Hz ist ständig da (Oszilloskop...) auch nach dem SLEEP(); Was muss ich machen um den PIC aufwecken? Muss ich vielleicht den Watchdog aktivieren?
skorpionx schrieb: > Timer1 läuft mit dem externer 32768Hz Quarzoszillator. Diese > TMR1H = 0b10000000; ist dazu um Interruptintervall auf 1 Sekunde zu > Stellen (ohne das sind das 2 Sekunden). System Clock ist auf interne > Oszillator mit 4Mhz gesetzt. Timer1 läuft und externer Signal von > 32768Hz ist ständig da (Oszilloskop...) auch nach dem SLEEP(); > Was muss ich machen um den PIC aufwecken? Muss ich vielleicht den > Watchdog aktivieren? Die Defines sind derartig schwierig zu lesen, sorry, das tu ich mir nicht an. Norbert S. hat eh schon hingeschrieben, wies geht. Also: Jedes Register kannst du einfach beschreiben mit z.B. T1CONbits.TON = 1; und so weiter. Da gibts einen Header von Microchip, der automatisch inkludiert ist, sobald du xc.h einbindest. Da hat Mircohip für jedes einzelne Register Bitfelder deklariert, die <Registername>bits heißen. Und das passt genau zu deinem PIC, für jedes gibts einen eigenen Header, es wird automatisch der für deinen verwendet. Dabei gilt: Registername im Datenblatt = Registername im Header. Wodurch du die entsprechende Sektion im Datenblatt nur aptippen musst. Das ist viel weniger fehleranfällig, weil die nötigen defines üblicherweise stimmen. Was beim Timer der Fehler sein kann: - IE-Flag nicht gesetzt - Interrupt Priorität auf 7 - TON-Bit des Timers nicht gesetzt - Timer-Register falsch beschrieben usw usf. Wirf doch auch mal den Debugger an, tu einen Breakpoint in main und schau dir die ganzen Bits an.
Hurra schrieb: > Das ist viel weniger fehleranfällig, weil die nötigen defines > üblicherweise stimmen. Hurra schrieb: > Interrupt Priorität auf 7 Ich arbeite mit PdfDoku. Suche ich entsprechende Register und kopiere ich einzelne Kommentare (die sind für mich wichtig). Das mit Bits und Schieberei wird alles durch Präprozessor erledigt. Im Programm wird das alles mit einer Zuweisung erledigt, anders als bei einzelnen Zuweisungen (z.B. T1CONbits.TON = 1;) .Dadurch wird auch kleinere Code generiert. Aber das ist Nebensache. Leider habe ich noch keine Lösung gefunden. Alle deine Vorschläge sind schon im Programm. Nur diese Sache mit dem „Interrupt Priorität“ verstehe ich nicht. Im Doku habe ich nichts davon gefunden.
skorpionx schrieb: > Hurra schrieb: >> Das ist viel weniger fehleranfällig, weil die nötigen defines >> üblicherweise stimmen. > > Hurra schrieb: >> Interrupt Priorität auf 7 > > Ich arbeite mit PdfDoku. Suche ich entsprechende Register und kopiere > ich einzelne Kommentare (die sind für mich wichtig). Das mit Bits und > Schieberei wird alles durch Präprozessor erledigt. Im Programm wird das > alles mit einer Zuweisung erledigt, anders als bei einzelnen Zuweisungen > (z.B. T1CONbits.TON = 1;) .Dadurch wird auch kleinere Code generiert. > Aber das ist Nebensache. > Leider habe ich noch keine Lösung gefunden. Alle deine Vorschläge > sind schon im Programm. Nur diese Sache mit dem „Interrupt Priorität“ > verstehe ich nicht. Im Doku habe ich nichts davon gefunden. Wenn nur die Sache mit dem schnelleren Code wichtig ist, dann kopier dir doch die Bitfelder aus dem Header und mache eine Konstante draus. Der Compiler müsste dass dann die Register in einer einzelnen Zuweisung schreiben. Möglich ist auch, dass der Compiler ohnehin alle zusammenfasst. Bei einer Initroutine wäre mir die Laufzeit allerdings egal. Das läuft sowieso nur ein einziges mal ab. Ich würde mal einen Breakpoint vor das sleep setzen und prüfen: - Ist der Interrupt ein? - Passt die Priorität? - ist der Timer an? - Inkrementiert der Timer wirklich? - Ist das Resetregister WIRKLICH das was du reingeschrieben hast? - Passt die clocksource für den Timer? - Ist Timer 1 auch wirklich eine wakeup-source? Du hast schon sleep und nicht deep-sleep? Das ist ein wichtiger Unterschied, was die wakeup-Sources angeht. Ja, Debuggen mit 32kHz ist unlustig. Aber es geht. Ich habe bei einem ähnlichen Projekt (Temperaturanzeige) nebenbei Witcher 3 gespielt. Bis der Brakepoint triggert und die Variablen im Watch geladen sind, kann man bequem ein paar Quests machen... Eine gute Methode ist auch, den ganzen Code zunächst mal mit dem FRC zu testen. Das geht deutlich flotter.
Wo wird GIE gesetzt? Ich sehe nur ein #define (bin aber auch kein C-Nutzer). Gruß J.R.
Defined sind falsch, teilweise mehr als 8 Bit. Diese Defines sind horrend, sollte ein anderer Prozessor verwendet werden, oder auch zwei von derselben Source.
Hurra schrieb: > Ist Timer 1 auch wirklich eine wakeup-source? Und das ist die Frage...Timer1 läuft zwar im SLEEP() aber ob der Überlauf weckt auf den PIC, das bin ich nicht sicher...
Moin Leute, einen schönen zweiten Weihnachtstage! Ich schiesse nur ins Blaue rein, ohne Datenblatt, und erinner mich bei anderen PICs ganz dunkel daran das man einen externen Oszi braucht. Check das doch mal ab. Best wishes dat Beast
Ob dein Programm läuft oder nicht, sollte man zuerst einmal die Hardware überprüfen. Hier mal ein kleines Programm, welches eine LED an PORT A0 blinken läßt. Der Controller läuft mit 4MHz internen Takt und an RA4 und RA5 ist ein 32768 KHz Quarz dran. Das Programm ist nach dem Start im Sleep Modus, LED leuchtet. Nach einer Zeit wird durch den Timer1, der Sleep Modus beendet und die LED geht aus. Und dann wieder von vorne. Probiere es mal aus und wenn es nicht läuft dann stimmt was nicht mit deiner Hardware.
Hw wird schon gehen. Es gibt mehrere Fehler. Wahrscheinlich Arduino Generation. Datenblatt, das sieht man sich nicht an, Programmierung ad absurdum mit fehlerhaftem Programmcode. Fehler Nr 1 Timer1 läuft mit internem clock. Fehler Nr 2 Timer1 clock wird mit internem clock synchronisiert. Beide Fehler bewirken auch einzeln dass Timer1 im Sleep nicht weiterzählt. Fehler Nr 3, Sleep im Interrupt. Dabei ist GIE off, sprich der Prozessor kann nur durch ein WDT oder Reset/BOR aufgeweckt werden. Eventuell geht es doch durch ein Bug im Sleep modus, sollte ein retfie direkt nach dem Sleep Befehl stehen, man muss aber das Programm disassrmblieren oder sich den ASM Code ansehen und auch da ist es nicht sicher ob es funktioniert, habe mir diesen Bug nie besonders genau angesehen, immer nur den workaround verwendet wenn nötig.
pic schrieb: > Hw wird > schon gehen. > Es gibt mehrere Fehler. Wahrscheinlich Arduino Generation. Datenblatt, > das sieht man sich nicht an, Programmierung ad absurdum mit fehlerhaftem > Programmcode. Also ich kann jetzt nur von mir spechen, aber ein längeres fehlerfreies Programm habe ICH noch nie eingetippt. Nicht auf Anhieb. Tippst du ausschließlich fehlerfreien Code ein? Wie schaffst du das?
Arduino Generation: Kopieren soviel code wie möglich. Lies niemals das Datenblatt. Wenn es nicht funktioniert, lass andere möglichst in diversen Foren dein Problem suchen und beheben. Wenn der TO die Kopiererei nicht so verteidigt hätte, hatte ich es nicht so geschrieben. Auch ist er nicht auf deine konstruktiven Ansätze eingegangen. Wenn im Datenblatt nicht extra ein Kapitel wäre, was zu beachten ist dass der Timer1 im Sleep mit externem Quarz die CPU bei Uberlauf aufweckt, könnte man es ohne weiteres der Unerfahrenheit mit der Pic Architektur zuschreiben, aber ....
Stefan schrieb: > Probiere es mal aus und wenn es nicht Es läuft! Wenn das kein Scherz (könntest du auch Source zeigen...)ist, dann habe ich mindestens Hoffnung.
Wenn du TMR1CS (0b10<<7) aufTMR1CS (0b10<<6) anders sowie T1SYNC auf 1 setzt und sleep vom Interrupt in die while schleife nach dem SleepZahler++; anderst, flag brauchst du keines, dann funktioniert dein code warscheinlich auch.
Hört sich doch gut an. Dann liegt es nicht an der Hardware. Hier das Programm dazu:
1 | program test4 |
2 | |
3 | sub procedure Interrupt() |
4 | if (TMR1IF_bit) then |
5 | TMR1IF_bit = 0 |
6 | TMR1H = 0x0f |
7 | TMR1L = 0x2C |
8 | end if |
9 | end sub |
10 | |
11 | |
12 | sub procedure InitTimer1() |
13 | T1CON = %10001101 |
14 | TMR1IF_bit = 0 |
15 | TMR1H = 0x0f |
16 | TMR1L = 0x2C |
17 | TMR1IE_bit = 1 |
18 | INTCON = 0xC0 |
19 | |
20 | end sub |
21 | |
22 | main: |
23 | |
24 | ANSELA = 0 |
25 | PORTA = 0 |
26 | LATA = 0 |
27 | TRISA = 0 |
28 | TRISA.4 = 1 |
29 | TRISA.5 = 1 |
30 | |
31 | OSCCON = 104 |
32 | InitTimer1
|
33 | |
34 | while True |
35 | LATA.0 = 1 |
36 | |
37 | sleep
|
38 | |
39 | nop
|
40 | nop
|
41 | nop
|
42 | |
43 | LATA.0 = 0 |
44 | delay_ms(3000) |
45 | |
46 | wend
|
47 | |
48 | end. |
Stefan schrieb: > OSCCON = 104 Leider in deinem Programm hast du einen Fehler. 104 das ist 0b01101000. Du hast zwar mit Bit 6-3 1101 4MHz HF Internal Oscillator gewählt aber durch Bit 1-0 hast du die Entscheidung an Configuration Word 1 übertragen: bit 1-0 SCS<1:0>: System Clock Select bits 1x = Internal oscillator block 01 = Timer1 oscillator 00 = Clock determined by FOSC<2:0> in Configuration Word 1. und dort muss du noch das beschreiben: #pragma config FOSC = // Oscillator Selection oder statt 104 andere Zahl mit anderen zwei untersten Bit schreiben. Ich kämpfe weiter.. Melde dich wenn du etwas neues hast...
Nein da muß nichts geändert werden. Im Compiler Menu wird der Controller auf den internen Takt umgestellt. Damit ist das FOSC<2:0> durch den Compiler gesetzt.
Stefan schrieb: > FOSC<2:0> durch den Compiler gesetzt. Was wird dann gesetzt?: FOSC<2:0>: Oscillator Selection bits 111 = ECH: External Clock, High-Power mode (4-32 MHz): device clock supplied to CLKIN pin 110 = ECM: External Clock, Medium-Power mode (0.5-4 MHz): device clock supplied to CLKIN pin 101 = ECL: External Clock, Low-Power mode (0-0.5 MHz): device clock supplied to CLKIN pin 100 = INTOSC oscillator: I/O function on CLKIN pin 011 = EXTRC oscillator: External RC circuit connected to CLKIN pin 010 = HS oscillator: High-speed crystal/resonator connected between OSC1 and OSC2 pins 001 = XT oscillator: Crystal/resonator connected between OSC1 and OSC2 pins 000 = LP oscillator: Low-power crystal connected between OSC1 and OSC2 pins Ich möchte weiter die sache untersuchen...
Es wird das gesetzt was du im Compiler ausgewählt hast. Bei meinem Programm was ich als HEX Datei geschickt habe, wird das INTOSC gesetzt.
Das mußt du natürlich in deinem Compiler auch setzen, sonst läuft er nicht auf den internen Takt. Standartmäßig ist es auf externen Takt gestellt. Also in den Projekt Settings umstellen.
Ichhabe zwischenzeitig eine Lösung gefunden. Hauptänderungen: #pragma config FOSC = XT // Oscillator Selection (INTOSC oscillator: I/O function on CLKIN pin) #define TMR1CS (0b01<<7) //Timer1 clock source is system clock (FOSC) Systemclock hat jetzt dieser 32768 Hz. Wenig, aber für meine Zwecke(Uhr) wird das reichen. Vielleicht findet jemand noch eine besser Lösung. Im SLEEP sieht man auf dem Oszi auch sehr kleine Amplitude vom Oszillator.Es wird Strom gespart. Ich möchte dieser Uhr für meine Heizungsteuerung verwenden. Uhr setzen und auslesen über Kommunikation durch I/O.
Warum läßt du den Controller nicht mit 4 MHz intern laufen ? Und nimmst den Quarz nur für den Timer 1, so wie ich es gemacht habe ?
Stefan schrieb: > Warum läßt du den Controller nicht mit > 4 MHz intern laufen ? Weill für diese Konstellation wurde meinen PIC nicht vom SLEEP aufgeweckt. Prüfe noch dein Programm. Z.B. kann auch watchdog den SLEEP beenden. Diese delay_ms(3000) ist für mich ein Rätsel. Und Frequenz vom Blinken stimmt auch nicht.
Da mein Programm läuft, liegt der Fehler in deinem Programm. Der Timer 1 läuft mit 32768 KHz und der Controller mit 4 MHz Takt. Da du weder das Compiler Programm beherschst noch die Programmiersprache kannst, würde ich dir empfehlen mit einem kleinen Programm an zu fangen, damit du in die Materie rein kommst. delay_ms(3000) bedeutet 3 Sekunden warten.
Haupt Problem war: TMR1CS<1:0>: Timer1 Clock Source Select bits: #define TMR1CS (0b10<<7) //Crystal oscillator on T1OSI/T1OSO pins Nach dem ist das geändert habe auf: #define TMR1CS (0b01<<7) //Timer1 clock source is system clock (FOSC) läuft das alles. Wie sollte man die Beschreibung verstehen?. Aber nur diese Option funktioniert mit SLEEP. Auch interne Frequenz kann man z.B. auf 4 Mhz setzen.
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.