|
|
View previous topic :: View next topic |
Author |
Message |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Jun 07, 2011 6:14 pm |
|
|
This code appears to do what you want. Here is the output on TeraTerm:
Quote: |
DSWAKEL: 01 // DSPOR bit = 1. This is the initial power-up of the board.
DSWAKEH: 00
//-------------------
// Next, I pressed the pushbutton on Pin B0.
DSWAKEL: 00
DSWAKEH: 01 // DSINT0 = 1. The board woke-up on the falling edge.
// Then I released the pushbutton on pin B0.
DSWAKEL: 00
DSWAKEH: 01 // DSINT0 = 1. The board did a wake-up on the rising edge.
//-------------------
// Then I press and release the button again. It works here too.
DSWAKEL: 00
DSWAKEH: 01
DSWAKEL: 00
DSWAKEH: 01
//----------------------
And again, and it still works.
DSWAKEL: 00
DSWAKEH: 01
DSWAKEL: 00
DSWAKEH: 01
|
The pushbutton circuit looks like this:
Code: |
+3.3v
|
<
> 10K
< ___ Push button switch
To | _|_|_
pin -----------------o o------
B0 |
--- GND
-
|
Here is the test program. I don't know if all the 10ms delays in here are
necessary. Some of them are. This program was tested with compiler
versions 4.095 and 4.121.
Code: |
#include <18F24J11.h>
#fuses HS, NOWDT
#use delay(crystal=20M)
#use rs232(baud=9600, UART1, ERRORS)
#byte WDTCON = 0xFC0
#byte DSCONH = 0xF4D
#byte DSCONL = 0xF4C
#byte RTCCFG = 0xF3F
#byte DSWAKEH= 0xF4b
#byte DSWAKEL= 0xF4a
#byte OSCCON = 0xFD3
#bit IDLEN =OSCCON.7 // Used to set IDLE low-power mode
#bit DSEN = DSCONH.7 // Used to set deep sleep
#bit REGSLP =WDTCON.7
#bit RELEASE = DSCONL.0
#bit RTCSYNC = RTCCFG.4
#bit DS_WAKEUP_BIT = WDTCON.3 // Bit that detects wake up from DS
#bit DSRTC = DSWAKEL.3
//==============================================
void main(void)
{
// Release the PIC's i/o pins for normal operation
// after waking up from Deep Sleep. Important !
RELEASE = 0;
delay_ms(10);
printf("\n\r");
printf("DSWAKEL: %x \n\r", DSWAKEL);
printf("DSWAKEH: %x \n\r", DSWAKEH);
delay_ms(10);
// Clear the wake-up source registers, regardless
// of what the PIC data sheet says.
DSWAKEL = 0;
DSWAKEH = 0;
// Look at the current state of the push-button switch.
// Based on that, set the edge that we expect to see next.
if(input(PIN_B0) == 1) // If switch is high
ext_int_edge(H_TO_L); // Then expect a falling edge next
else // If switch is low
ext_int_edge(L_TO_H); // Then expect a rising edge next
clear_interrupt(INT_EXT);
enable_interrupts(INT_EXT);
delay_ms(10);
// Enable Deep Sleep mode.
REGSLP = 1; // enable low-power operation in sleep mode
IDLEN = 0;
#asm // Time-critical section must be in ASM
BSF DSEN
SLEEP
NOP
#endasm
printf("Should never get here\n\r");
while(1);
} |
|
|
|
heUAcyp
Joined: 16 Mar 2011 Posts: 33
|
|
Posted: Wed Jun 08, 2011 6:12 am |
|
|
Sir thank you very very much for your help.
Interrupt is working with a small problem. I have tested the suggested code and get the expected results on the HyperTerminal:
Quote: | DS_WAKEUP_BIT: 00
DS_WAKEUP_BIT: 00
DSWAKEH: 00
DSWAKEL: 00
DS_WAKEUP_BIT: 01
DS_WAKEUP_BIT: 01
DSWAKEH: 01
DSWAKEL: 00
DS_WAKEUP_BIT: 01
DS_WAKEUP_BIT: 01
DSWAKEH: 01
DSWAKEL: 00 |
The code I am using is:
Code: | #include <18F25J11.h>
#device ADC=10
#include <STDIO.H>
#include <stdlib.h>
#include <math.h>
#include <STRING.H>
#include <2408.c>
#fuses HS,NOWDT,NOPROTECT
#use delay(clock=4000000)
#use rs232 (baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
//
#byte WDTCON = 0xFC0
#byte DSCONH = 0xF4D
#byte DSCONL = 0xF4C
#byte RTCCFG = 0xF3F
#byte DSWAKEH= 0xF4b
#byte DSWAKEL= 0xF4a
#byte OSCCON = 0xFD3
#byte INTCON = 0xFF2
#byte INTCON2 = 0xFF1
//
#bit IDLEN=OSCCON.7 // used to set IDLE low-power mode ( will be set to zero for both deep-sleep and sleep modes)
#bit DSEN = DSCONH.7 // used to set deep sleep (1 for deep-sleep)
#bit REGSLP =WDTCON.7
#bit RELEASE = DSCONL.0
#bit RTCSYNC = RTCCFG.4
#bit DSINT0 = DSWAKEH.0 // bit for INT0 interrupt - change detection
#bit DS_WAKEUP_BIT = WDTCON.3 // bit that detects wake up from deep sleep
#bit INT0IE = INTCON.4
#bit INT0IF = INTCON.1
#bit INTEDG0 = INTCON2.6
void EnterDeepSleep()
{
// Enable Deep Sleep mode.
REGSLP = 1; // enable low-power operation in sleep mode
IDLEN = 0;
#asm // Time-critical section must be in ASM
BSF DSEN
SLEEP
NOP
#endasm
}
void PerformingTaskON()
{
output_high(PIN_A1) ;
}
void main()
{
//disable_interrupts(GLOBAL);
RELEASE = 0; // Activate i/o pins
delay_ms(10);
printf("\n\r\n\r");
printf("DS_WAKEUP_BIT: %x \n\r", DS_WAKEUP_BIT);
delay_ms(10);
printf("DS_WAKEUP_BIT: %x \n\r", DSINT0);
delay_ms(10);
printf("DSWAKEH: %x \n\r", DSWAKEH);
delay_ms(10);
printf("DSWAKEL: %x \n\r", DSWAKEL);
delay_ms(10);
//
if((DS_WAKEUP_BIT == 1) && (DSWAKEH == 1)&&(DSINT0==1))
{
PerformingTaskON() ;
delay_ms(200);
DSWAKEL = 0;
DSWAKEH = 0;
}
// Clear the wake-up source registers, regardless
// of what the PIC data sheet says.
DSWAKEL = 0;
DSWAKEH = 0;
//
// Look at the current state of the push-button switch.
// Based on that, set the edge that we expect to see next.
if(input(PIN_B0) == 1) // If switch is high
ext_int_edge(H_TO_L); // Then expect a falling edge next
else // If switch is low
ext_int_edge(L_TO_H); // Then expect a rising edge next
clear_interrupt(INT_EXT);
enable_interrupts(INT_EXT);
delay_ms(10);
EnterDeepSleep() ;
printf("Should never get here\n\r");
while(true)
{
}
}
|
However, PIC does not go back to sleep when I try to perform a task.
With a simple test task (if function commented in above code), when interrupt fires, I am turning a LED on. The problem is , LED does not turn back to off afterwards, meaning that PIC is not getting back to deep sleep mode.
in my complete design I will keep real time while in deep sleep , than wake up only to save the date and time to an external EEPROM when interrupt fires and go back to sleep. I have written and tested the other parts of the code and they are working. But I want PIC to be awake only while performing a task and than go back to sleep again.
Something is still wrong, I tried to add the if function to various places in the code flow and it still not working. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Jun 08, 2011 12:25 pm |
|
|
I assume that setting pin A1 to high level turns the LED on. I don't see
any place in your code where you turn the LED off. You never set pin A1
to a low level.
Going into Deep Sleep mode doesn't turn it off. Read the data sheet:
Quote: |
4.6.2 I/O PINS DURING DEEP SLEEP
During Deep Sleep, the general purpose I/O pins will retain their previous states.
|
Download the PIC data sheet and read the whole section on Deep Sleep. |
|
|
heUAcyp
Joined: 16 Mar 2011 Posts: 33
|
|
Posted: Wed Jun 08, 2011 2:55 pm |
|
|
Thank you boss |
|
|
|
|
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
|