PDA

View Full Version : @ SLEEP with interrupts 16F88



drewlash
- 8th February 2005, 17:17
I am working on a project involving two 16F88 chips. I am using the hardware usart. I need to put the chips to sleep and have them wake up with the interrupt pin RB0 or the RX interrupt.
This is part of the code

Main_Prog:
IF MAIN_INT THEN ' RB0 HIGH
GOSUB Handle_Buttons
ENDIF

IF PIR1.5 THEN ' USART RECIEVE INTERRUPT FLAG
GOSUB Rx_Sub
ENDIF


INTCON = %11010000 ' SET GIE, PEIE, AND INTE
PIE1 = %00100000 ' SET RCIE
PIR1 = %00000000 ' CLEAR INTERRUPT FLAGS
OPTION_REG = %11000000 'PULL UPS ENABLED
@ SLEEP

GOTO Main_Prog

If I take all the code from intcon to @sleep out (last 5 lines in Main_Prog), then it works perfectly, however, as soon as I start putting those lines back in, I get different, inconsisten results each time.

It appears that the RB0 interrupt works, however, the chip will never wake up with the USART Recieve Interrupt. It also appears that with the sleep in there, it no longer sends the usart signals.

If anyone has any ideas on what may be wrong or any tips on using the usart recieve interrupt, it would be greatly appreciated.

Thanks,
Andrew Lash

mister_e
- 8th February 2005, 20:13
what about your USART and others define???

can you post your WHOLE code.

drewlash
- 8th February 2005, 20:34
The program is too long to post all of it. Below I'll post the code related to the usart use.

DEFINE HSER_CLROERR 1
DEFINE HSER_RCSTA 90h
DEFINE HSER TXSTA 20h
DEFINE HSER_BAUD 9600



'this is at the beginning of the code, before it enters the main loop.
'Disable interrupts
INTCON = %00000000
PIE1 = %00000000
PIR1 = %00000000
OPTION_REG = %11000000


'Send/Recieve Codes
GROUND_ALL CON $00
ANT_1_SELECT CON $01
ANT_2_SELECT CON $02
ANT_3_SELECT CON $03
ANT_4_SELECT CON $04
ANT_REQUEST CON $09
RADIO_SENSE_OFF CON $10
RADIO_SENSE_ON CON $11
REQUEST_MODE CON $12
REQUEST_RF CON $13
RF_SENSED_OFF CON $14
RF_SENSED_ON CON $15
RF_SENSED CON $16
RADIO_OFF CON $17


Send_Code VAR BYTE 'Var to pass to the send routine
RX_Code VAR word 'Var to get the code from the remote



Tx_Sub:
hserout ["M", send_code]
return

Rx_Sub:
HSERIN [rx_code.byte0, rx_code.byte1]
gosub Handle_RX
return

Handle_RX:
if rx_code.byte0 = "R" then 'Make sure code is from remote
if rx_code.byte1 = Ground_ALL then 'command recieved to ground all
'code for ground all
endif
' repeat for each command
ENDIF

return

The send/recieve works fine if the sleep isn't in there. As soon as I try putting the chips to sleep, it stops working.

drewlash
- 10th February 2005, 20:59
No matter what I do, I just can't get the chips to wake up from the recieve interrupt. Has anyone ever used the 16F88 with the USART receive interrupt successfully? What am I doing wrong? Any ideas? My program receives the data fine as long as I don't try putting it to sleep. The RB0 interrupt pin will also work to wake it up from sleep, but not the RCIE interrupt.

I've been stuck on this for over a week now. Any help would be greatly appreciated!

Thanks,
Andrew Lash

mister_e
- 10th February 2005, 21:07
not sure of it but... what about if you change

DEFINE HSER_CLROERR 1
DEFINE HSER_RCSTA 90h
DEFINE HSER TXSTA 20h
DEFINE HSER_BAUD 9600

to
DEFINE HSER_CLROERR 1
RCSTA=$90
TXSTA=$20
SPBRG = 32 ' if you osc=20

drewlash
- 10th February 2005, 21:24
That doesn't change the operation of the program at all, just tried it, and nothing changed. The receive interrupt still does not work.

Thanks,
Andrew Lash

Bruce
- 10th February 2005, 22:30
The USART can only wake this device from SLEEP when used in (Synchronous Slave Mode).

Peripherals that rely on the on-chip clock (like the USART in Asynchronous mode) cannot generate interrupts, since during SLEEP, no on-chip clocks are present.

mister_e
- 11th February 2005, 05:55
mmm, interesting Bruce. I never check the datasheet for that because i've never never never use USART interrupt to wake-up an application... great to know that!!

SO, The choice you have is to use the interrupt on PORTB change. In the interrupt handler, check if it's an RB0 or other. Link another PORTB pin to the USART RX and that's it... in this case it will be safer to send one or few "header character" to ensure getting all data from your PC.

There's maybe some other way to do that but this is the only one who comes here... can also be done with some FlowControl pin on the DB9...