|
|
View previous topic :: View next topic |
Author |
Message |
championx
Joined: 28 Feb 2006 Posts: 151
|
wake on RDA interrupt |
Posted: Fri Dec 09, 2016 2:39 pm |
|
|
Hi! I'm using a 16F1847 to a project and i want to wake up from sleep by entering a character on the uart.
Code: | #include <16f1847.h>
#fuses INTRC_IO,NOPROTECT, PUT, NOMCLR, WDT_SW, BROWNOUT, NOLVP, PLL_SW, FCMEN
#use delay(clock=8000000)
#use rs232(baud=9600, xmit=PIN_B2, rcv=PIN_B1, errors)
char character;
main()
{
setup_uart( UART_WAKEUP_ON_RDA );
enable_interrupts(int_rda);
enable_interrupts(global);
while(true)
{
sleep();
printf("char: %c ",character);
}
}
#int_rda
interrupt_from_rx()
{
character = getc();
} |
but the pic enters sleep mode and never wake up again.
compiler version 5.045
do I missed something?
thanks! |
|
|
jeremiah
Joined: 20 Jul 2010 Posts: 1349
|
|
Posted: Fri Dec 09, 2016 3:02 pm |
|
|
The UART requires a running clock to work. When the PIC is asleep, the clock stops. One option we use sometimes is to assign a I/O interrupt to the receive pin of the UART, then when the first character is received, the I/O interrupt, which doesn't require a clock, wakes up the PIC and thus the UART. That first character will be garbage though, so you have to handle that with how you parse the UART data. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19516
|
|
Posted: Fri Dec 09, 2016 3:22 pm |
|
|
The first thing to understand, is that if you do this, normally the first character received will be garbage. The UART won't be being clocked properly when this is received.
The sequence basically has to be 'send a character to wake', then pause and send the data you want to receive.
Your chip has a very specific ability to wake. However _no character will be received_.
If you look at the data sheet:
Code: |
bit 1 WUE: Wake-up Enable bit
Asynchronous mode:
1 = Receiver is waiting for a falling edge. No character will be received, byte RCIF will be set. WUE
will automatically clear after RCIF is set.
0 = Receiver is operating normally
|
The sequence has to be:
Code: |
#int_rda
void interrupt_from_rx(void)
{
character = getc();
}
void main(void)
{
disable_interrupts(GLOBAL); //You need this disabled to prevent the RX
//handler from being called without a character.
enable_interrupts(INT_RDA);
while(true)
{
setup_uart( UART_WAKEUP_ON_RDA );
//This needs to be set _every time you want to do this.
character=0;
sleep();
delay_cycles(1); //instruction after sleep should always be NOP
clear_interrupts(INT_RDA); //this is the one occasion you can
//clear this without reading a character
enable_interrupts(GLOBAL);
while (character==0) //wait for the next character to arrive
;
printf("char: %c ",character);
}
}
|
What happens is that the chip will go to sleep, and wake when the RDA triggers, _without a character being received_. Then if you wait a short time, and send another character, this will be received and printed, and the chip will go back to sleep. |
|
|
championx
Joined: 28 Feb 2006 Posts: 151
|
|
Posted: Wed Dec 14, 2016 11:47 am |
|
|
You were right Ttelmah! thanks. Now it work like a charm!
Thanks a lot. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19516
|
|
Posted: Wed Dec 14, 2016 3:19 pm |
|
|
Good.
Quite a lot of the 'bigger' PIC18's have the ability to go to sleep but leave the UART clocked. This then allows characters to be received. The chip you have is one of a very limited number where you can effectively stop everything, and have a falling edge on the UART input be treated as if it was a normal 'static' interrupt like INT_EXT, so can wake up, but won't receive the character. With a bit more work you can have it wake, receive a specific amount of data, then go back to sleep. Quite nice. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|