Forum: Mikrocontroller und Digitale Elektronik PIC18 in Sleep Modus und per UART Interrupt wieder heraus


von Schläfer (Gast)


Lesenswert?

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
}

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
Noch kein Account? Hier anmelden.