Ich nutze einen PIC18LF25K50 mit MPLAB v2.25.
Ich versuche den Pic in den Sleep Modus zu versetzen und dann per UART
Interrupt wieder aufzuwecken.
Da im Sleep Modus der Oscillator etc. disablet ist und keine Clock
anliegt versuche ich die Auto Wake Option des PICs, die im Datasheet
(http://ww1.microchip.com/downloads/en/DeviceDoc/30684A.pdf 17.4.3 auf
S. 276) berschrieben ist zu nutzen.
Bevor der Controller in den Sleep Modus geht muss das WUE Bit via
Software gesetzt werden. In der ISR Routine wird dieses Bit dann
abgefragt, wenn es anliegt wird laut Datasheet eine Break Sequenz über
das UART Modul gelesen. Diese Daten können verworfen werden. Danach wird
das WUE Bit per Hardware automatisch gelöscht und die Nutzdaten können
übertragen werden.
Mein Problem ist nun, dass das WUE Bit in der ISR Routine nie gesetzt
ist, deswegen sind auch nie valide Daten im Empfangsbuffer vorhanden.
Vielleicht hat ja schon Jemand diesen Modus genutzt?
Mein Code sieht in etwa so aus:
1 | unsigned char getcUSART1 (void)
|
2 | {
|
3 | char c;
|
4 | if (RCSTAbits.OERR) // in case of overrun error
|
5 | { // we should never see an overrun error, but if we do,
|
6 | RCSTAbits.CREN = 0; // reset the port
|
7 | c = RCREG;
|
8 | RCSTAbits.CREN = 1; // and keep going.
|
9 | }
|
10 | else
|
11 | {
|
12 | c = RCREG;
|
13 | }
|
14 | // not necessary. EUSART auto clears the flag when RCREG is cleared
|
15 | // PIR1bits.RCIF = 0; // clear Flag
|
16 | return c;
|
17 | }
|
18 |
|
19 |
|
20 |
|
21 |
|
22 | // start ISR code
|
23 | #pragma code isr = 0x08 // store the below code at address 0x08
|
24 | #pragma interrupt isr // let the compiler know that the function isr() is an interrupt handler
|
25 | void isr(void)
|
26 | {
|
27 | if(PIR1bits.RCIF == 1) // if the USART receive interrupt flag has been set
|
28 | {
|
29 | if(BAUDCON1bits.WUE == 1) // This is a Wake-Up Interrupt -> A Break Character is read into the UART, afterwards WUE is cleared -> valid data
|
30 | // The UART hardware CLEARS the WUE bit when the character AFTER the BREAK is received
|
31 | {
|
32 | getcUSART1(); // Read RCREG Data but discard, because this is the Break Character
|
33 | }
|
34 | else // Data is valid -> read in buffer_rx
|
35 | {
|
36 | rx_char = getcUSART1();
|
37 | buffer_rx[i] = rx_char;
|
38 | if(rx_char == '\r' || i == n || rx_char == 'e') // Überprüfe ob Buffer voll oder Endekennung
|
39 | {
|
40 | flag = 1;
|
41 | }
|
42 | i++;
|
43 | }
|
44 | }
|
45 | }
|
46 | #pragma code // return to the default code section
|
47 | // end ISR code
|
48 |
|
49 |
|
50 | void main()
|
51 | {
|
52 | // ...
|
53 | ClrWdt(); // Clear Watchdog
|
54 | while(1)
|
55 | {
|
56 | if(flag == 1)
|
57 | {
|
58 |
|
59 | if(strcmppgm2ram(buffer_rx,(const far rom char*)"teste") == 0 )
|
60 | {
|
61 | // do something
|
62 | }
|
63 |
|
64 | clean_rxbuffer();
|
65 | i = 0;
|
66 | flag = 0;
|
67 | }
|
68 |
|
69 | BAUDCON1bits.WUE = 1; // Set the WUE Bit Immediately Before entering sleep
|
70 | Sleep();
|
71 | }
|
72 | }
|