Dear All,
I've got an issue with PIC16F1847 and wake up by button press from sleep. I've got button connected to RB0 and it should wake up the PIC from sleep and turn on FET by function TurnOnDisplay();. However it never gets flag FlagForBtnPress set in interrupts. I've tried to understand this from datasheet:
"On waking from Sleep, if the GIE bit is also set, the
processor will branch to the interrupt vector. Otherwise,
the processor will continue executing instructions after
the SLEEP instruction. The instruction directly after the
SLEEP instruction will always be executed before
branching to the ISR."
So I added INTCON = 0b11011000; before and after the sleep. Once it worked but when I tried removing either line it didn't go to interrupt anymore and after adding both never worked anymore. I don't understand that why it won't go to interrupt anymore. I measured the current and in sleep it draw 110uA and when I press the button 1mA so the PIC wakes up but disregards the interrupt. What's am I doing wrong? Using mikroC PRO for PIC. If I uncomment the "asm reset" line, it works from button press, so I can be sure it actually wakes up.
Interrupt:
void Interrupt(void){
if (INTF_bit){ // Pin Interrupt happened
INTF_bit = 0;
FlagForBtnPress = 1;
}
if (IOCIF_bit) {
IOCBF0_bit = 0;
FlagForBtnPress = 1;
}
}
In main loop.
// Go to sleep
if (FlagForSleep == 1)
{
if (ForceReading > 30) FlagForSleep = 0;
else {
Turnoffdisplay(); // Timer triggered sleep
FlagForSleep = 0;
INTCON = 0b11011000;
asm sleep;
INTCON = 0b11011000;
//asm reset; // if this is uncommented, it works
}
}
// Wake up from sleep and / or reset max reading
if (FlagForBtnPress) {
if (PORTA.f4 == 1) {
TurnOnDisplay();
SetTheADC();
}
FlagForBtnPress = 0;
maxForce = 0; // Reset max Force from button press
VDetFlagPreviousStage = 0;
}
Edit: Ok, if I set the flag directly after the sleep, it obviously works and no need to reset. But the question remains, why it won't go to the interrupt handler when it wakes up from button press? When it is normally running and pressing the button, it sets the flag in interrupt.
if (FlagForSleep == 1)
{
if (ForceReading > 30) FlagForSleep = 0;
else {
Turnoffdisplay(); // Timer triggered sleep
FlagForSleep = 0;
asm sleep;
FlagForBtnPress = 1;
}
}