Hallo Leute, ich versuche seit Tagen den PIC24FJ16GA004 per SLEEP-Befehl schlafen zu legen und dann per UART-Interrupt wieder aufzuwecken. Ohne SLEEP funktioniert alles wunderber, wenn ich den SLEEP-Befehl einfüge, dann geht der PIC schlafen und läßt sich nicht mehr aufwecken, obwohl er Daten von außen bekommt. Weiß da jemand einen Trick? Mit Errata kam ich nicht weiter. Das Einzige, was funktioniert, wenn der Watchdog aktiviert ist und im Sleep-Modus überläuft, dann wacht der PIC auf. Gruß Andy
Du solltest Dir unbedingt mal das Kapitel 21.11 im Family Reference Manual anschauen - da offensichtlich noch nicht getan. Ich zitieren: "The UART does not function in Sleep mode." Ist ja auch logisch, da im Sleep üblicherweise die Taktquelle abgeschaltet ist, die für die Funktion der UART nun einmal nötig ist. Allerdings gibt es ein Auto-Wake-up Feature. Möglicherweise ist das eine Option für Dich.
diesen Umstand kenne ich. Beim UART ist der Receive/Transmit-Interrupt aktiviert, der den PIC aufwecken sollte. Ohne den Sleep-Modus funktionieren alle Interrupts so wie sie sollten. Ich habe auch den Idle-Modus ausprobiert, mit gleichem Ergebnis. Aus irgendeinem Grund kann der UART-Receive-Interrupt den PIC nicht aufwecken.
Ich frage mich gerade, warum ich hier meine Zeit investiere, um Dir zu helfen. Es ist mal wieder typisch: es werden zwei Zeilen hingetipt und dann darf man hier erst einmal herumorakeln und dem TE mühsam die Details aus der Nase ziehen, die er einfach eingangs hätte hinschreiben können. Ein paar Zeilen Code zu kopieren und hier einzufügen ist doch auch keine unlösbare Aufgabe? Es gibt haufenweise mögliche Gründe, warum das so mit dem Wakeup nicht funktioniert. Z.B. an falsch gesetzten CPU- oder Interrupt-Prioritäten. Einfach zu testen, indem Du den PIC durch andere Interrupts mit identisch eingestellten Prioritäten versuchst aufzuwecken. DAS würde ich als erstes Testen. Um den PIC per USART aufzuwecken, muss das Prozedere von Section 21.11.1 eingehalten werden. Setzt Du das WAKE-Bit vorm Schlafengehen? Schickst Du tatsächlich ein Sync Break als Wakeup-Signal? Wenn nein: tja dann klappt das halt auch nicht.
tut mir leid, hast ja recht
1 | void UART1_Init(void) |
2 | {
|
3 | IPC2bits.U1RXIP = 4; |
4 | IPC3bits.U1TXIP = 4; |
5 | |
6 | // UART konfigurieren:
|
7 | // Baudrate (aufgerundet) einstellen
|
8 | U1BRG = (unsigned int)((((unsigned long)FCY + ((4*(unsigned long)BAUDRATE)/2)) / (4*(unsigned long)BAUDRATE)) - 1); |
9 | // Modus: enable, stop in idle mode, use only U2TX and U2RX, 8-N, 1 stop bit
|
10 | // U1MODE = (1 << 15) | (1 << 13) | (0 << 8) | (0 << 1) | (0 << 0);
|
11 | U1MODE = (1 << 15); |
12 | |
13 | U1MODEbits.BRGH = 1; |
14 | |
15 | // Status: irq when tx done, transmit enable, irq when rx done
|
16 | U1STA = (1 << 10); |
17 | |
18 | // TX-Interrupt-Flag löschen (wird durch Initialisierung ausgelöst)
|
19 | IFS0bits.U1TXIF = 0; |
20 | |
21 | // Interrupts aktivieren
|
22 | IEC0bits.U1TXIE = 1; // TX |
23 | IEC0bits.U1RXIE = 1; // RX |
24 | }
|
25 | |
26 | |
27 | void hardwareInit(void) |
28 | {
|
29 | //Oszillator initialisieren
|
30 | |
31 | OSCCON = 0x0000; |
32 | |
33 | OSCCONbits.COSC0 = 1; //Interner FRC mit Postscaler (FRCDIV) ist eingestellt. |
34 | OSCCONbits.COSC1 = 1; |
35 | OSCCONbits.COSC2 = 1; |
36 | |
37 | OSCCONbits.SOSCEN = 0; //Secondary Oscillator deaktiviert. |
38 | |
39 | CLKDIV = 0x0000; |
40 | |
41 | CLKDIVbits.RCDIV0 = 0; |
42 | CLKDIVbits.RCDIV1 = 1; |
43 | CLKDIVbits.RCDIV2 = 0; |
44 | |
45 | //PPS initialisieren
|
46 | |
47 | |
48 | //*************************************************************
|
49 | // Unlock Registers
|
50 | //*************************************************************
|
51 | __builtin_write_OSCCONL(OSCCON & 0xbf); //clear the bit 6 of OSCCONL to |
52 | //unlock Pin Re-map
|
53 | //******************************************************************
|
54 | |
55 | //************************************************************
|
56 | // Configure Input Functions
|
57 | //************************************************************
|
58 | //
|
59 | // Zuweisen U1Rx zu Pin RP15
|
60 | RPINR18bits.U1RXR = 15; |
61 | |
62 | // #ifdef DEBUG
|
63 | // Zuweisen U2Rx zu Pin RP11
|
64 | RPINR19bits.U2RXR = 11; |
65 | // #endif
|
66 | |
67 | //************************************************************
|
68 | // Configure Output Functions
|
69 | //************************************************************
|
70 | //
|
71 | // Zuweisen U1Tx zu Pin RP13
|
72 | //***************************
|
73 | RPOR6bits.RP13R = 3; |
74 | |
75 | // #ifdef DEBUG
|
76 | // Zuweisen U2TX zu Pin RP10
|
77 | RPOR5bits.RP10R = 5; |
78 | // #endif
|
79 | |
80 | // Zuweisen OC1 zu Pin RP21
|
81 | RPOR10bits.RP21R = 18; |
82 | |
83 | //************************************************************
|
84 | // Lock Registers
|
85 | //************************************************************
|
86 | __builtin_write_OSCCONL(OSCCON | 0x40); //set the bit 6 of OSCCONL to |
87 | //lock Pin Re-map
|
88 | //******************************************************************
|
89 | |
90 | |
91 | //PORTs initialisieren
|
92 | |
93 | TRISA = (1<<0) //RA0,RA1,RA7 sind Eingänge, RA8-RA10 sind Ausgänge |
94 | | (1<<1) |
95 | | (1<<7) |
96 | ;
|
97 | TRISB = (1<<0) //RB0,RB1,RB2,RB3,RB11,RB12,RB15 sind Eingänge |
98 | | (1<<1) |
99 | | (1<<2) |
100 | | (1<<3) |
101 | | (1<<11) |
102 | | (1<<12) |
103 | | (1<<15) |
104 | ;
|
105 | |
106 | TRISC = (1<<0) //RC0,RC1,RC2 sind Eingänge |
107 | | (1<<1) |
108 | | (1<<2) |
109 | ;
|
110 | |
111 | AD1PCFG = 0xFFFF; //Alle Portpins erstmal digitale I/Os |
112 | |
113 | LATA = 0x0000; |
114 | LATB = 0x0000; |
115 | LATC = 0x0000; |
116 | }
|
117 | |
118 | |
119 | |
120 | // JTAG | Code Protect | Write Protect | Background Debugger | Clip-on Emulation mode
|
121 | // ICD pins select | Watchdog Timer | Windowed WDT | Watchdog prescaler | Watchdog postscale)
|
122 | _CONFIG1(JTAGEN_OFF & GCP_OFF & GWRP_OFF & BKBUG_OFF & COE_OFF & ICS_PGx2 & FWDTEN_OFF & WINDIS_OFF & FWPSA_PR32 & WDTPS_PS4096) |
123 | // Two Speed Start-up | Secondary Oscillator | Voltage Regulator Standby-mode Wake-up Timer
|
124 | // Oscillator Selection | Clock switching and clock monitor | OSCO/RC15 function
|
125 | // RP Register Protection | I2C1 pins Select | Oscillator Selection)
|
126 | _CONFIG2(IESO_ON & SOSCSEL_SOSC & WUTSEL_LEG & FNOSC_FRCDIV & FCKSM_CSDCMD & OSCIOFNC_ON & IOL1WAY_OFF & I2C1SEL_PRI & POSCMOD_NONE) |
127 | |
128 | |
129 | |
130 | int main(void) |
131 | {
|
132 | EnableWDT(WDT_ENABLE); //Watchdog-Timer per Software (SWDTEN) aktivieren. |
133 | hardwareInit(); |
134 | ...
|
135 | |
136 | while(1) |
137 | {
|
138 | ClrWdt(); |
139 | |
140 | ...
|
141 | |
142 | //EnableWDT(WDT_DISABLE);
|
143 | U1MODE |= (1 << 7); //Set WAKE-Bit für UART1 |
144 | Sleep(); |
145 | |
146 | }
|
147 | |
148 | }
|
Ich benutze den 2en UART, um Debug/Statusmeldungen auszugeben. Wenn ich disen UART initialisiere und eine kleine Zeichenkette ausgeben lasse, dann funktioniert das Aufwecken aus dem Sleep. Dieser Uart ist ohne Interrupts aufgesetzt.
andi schrieb: > Ich benutze den 2en UART, um Debug/Statusmeldungen auszugeben. Wenn ich > disen UART initialisiere und eine kleine Zeichenkette ausgeben lasse, > dann funktioniert das Aufwecken aus dem Sleep. Dieser Uart ist ohne > Interrupts aufgesetzt. Äh, da kann ich nicht ganz folgen. Wie kannst Du denn mit der zweiten UART eine Zeichenkette versenden, während der PIC schläft? Und nochmal die wichtige Frage: klappt das Aufwecken durch einen anderen Interrupt, z.B. einen INT_EXT?
Die Zeichenkette verschicke ich kurz davor und wenn ich dann den PIC schlafen lege, dann wacht er auch wie erwartet auf, nur halt wenn ich diese Debug-Ausgabe abstelle, dann geht das Aufwecken nicht mehr. Einen anderen Interrupt habe ich noch nicht probiert, weil ich so auf das eigentliche UART-Interrupt fixiert war, werde ich aber machen. andi
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.