Hi,
I have tried the example in the manual (page 364 of the 8 bit manual) and cannot get it to wake.
Device = 18F25K20
Declare Xtal = 64
'-------------------------------------------------------------
' Setup the fuses for the 4xPLL
'
Config_Start
FOSC = HSPLL ' HS oscillator, PLL enabled and under software control
Debug = Off ' Background debugger disabled' RB6 and RB7 configured as general purpose I/O pins
XINST = Off ' Instruction set extension and Indexed Addressing mode disabled (Legacy mode)
STVREN = Off ' Reset on stack overflow/underflow disabled
WDTEN = Off ' WDT disabled (control is placed on SWDTEN bit)
FCMEN = Off ' Fail-Safe Clock Monitor disabled
IESO = Off ' Two-Speed Start-up disabled
WDTPS = 128 ' Watchdog is 1:128
BOREN = Off ' Brown-out Reset disabled in hardware and software
BORV = 18 ' VBOR set to 1.8 V nominal
MCLRE = On ' MCLR pin enabled, RE3 input pin disabled
HFOFST = Off ' The system clock is held Off until the HF-INTOSC is stable.
LPT1OSC = Off ' T1 operates in standard power mode
PBADEN = Off ' PORTB<4:0> pins are configured as digital I/O on Reset
CCP2MX = PORTC ' CCP2 input/output is multiplexed with RC1
LVP = Off ' Single-Supply ICSP disabled
Cp0 = Off ' Block 0 (000800-001FFFh) not code-protected
CP1 = Off ' Block 1 (002000-003FFFh) not code-protected
CPB = Off ' Boot block (000000-0007FFh) not code-protected
CPD = Off ' Data eeprom not code-protected
WRT0 = Off ' Block 0 (000800-001FFFh) not write-protected
WRT1 = Off ' Block 1 (002000-003FFFh) not write-protected
WRTB = Off ' Boot block (000000-0007FFh) not write-protected
WRTC = Off ' Configuration registers (300000-3000FFh) not write-protected
WRTD = Off ' Data eeprom not write-protected
EBTR0 = Off ' Block 0 (000800-001FFFh) not protected from table reads executed in other blocks
EBTR1 = Off ' Block 1 (002000-003FFFh) not protected from table reads executed in other blocks
EBTRB = Off ' Boot block (000000-0007FFh) not protected from table reads executed in other blocks
Config_End
Symbol RED_LED = LATC.6 ' Red LED
TRISC.6=0 ' Set LED pin to output
INTCONbits_GIE = 0 ' disable global interrupts
Input PORTB.4 ' Make PORTB.4 an Input
INTCON2bits_RBPU = 0 ' Enable pull ups
INTCONbits_RBIE = 1 ' Enable a "Change on port B" interrupt
' Flash the LED on power up
RED_LED = 1
DelayMS 1000
Do
DelayMS 100
Low RED_LED ' Turn off the LED
INTCONbits_RBIF = 0 ' Clear the PORTB[4..7] interrupt flag
Sleep ' Put the microcontroller to sleep
DelayMS 100 ' When it wakes up, delay for 100ms
High RED_LED ' Then light the LED
Loop ' Forever
Bob
this works
;-------------------------------------------------------------------------------
;**** Added by Fuse Configurator ****
; Use the Fuse Configurator plug-in to change these settings
Device = 18F25K20
Declare Xtal = 20
Config_Start
FOSC = HS ;HS oscillator
FCMEN = OFF ;Fail-Safe Clock Monitor disabled
IESO = OFF ;Oscillator Switchover mode disabled
PWRT = OFF ;PWRT disabled
BOREN = SBORDIS ;Brown-out Reset enabled in hardware only (SBOREN is disabled)
BORV = 18 ;VBOR set to 1.8 V nominal
WDTEN = OFF ;WDT is controlled by SWDTEN bit of the WDTCON register
WDTPS = 32768 ;1:32768
CCP2MX = PORTC ;CCP2 input/output is multiplexed with RC1
PBADEN = OFF ;PORTB<4:0> pins are configured as digital I/O on Reset
LPT1OSC = OFF ;Timer1 configured for higher power operation
HFOFST = On ;HFINTOSC starts clocking the CPU without waiting for the oscillator to stablize.
MCLRE = OFF ;RE3 input pin enabled; MCLR disabled
STVREN = OFF ;Stack full/underflow will not cause Reset
LVP = OFF ;Single-Supply ICSP disabled
XINST = OFF ;Instruction set extension and Indexed Addressing mode disabled (Legacy mode)
Debug = OFF ;Background debugger disabled, RB6 and RB7 configured as general purpose I/O pins
Cp0 = OFF ;Block 0 (000800-001FFFh) not code-protected
CP1 = OFF ;Block 1 (002000-003FFFh) not code-protected
CP2 = OFF ;Block 2 (004000-005FFFh) not code-protected
CP3 = OFF ;Block 3 (006000-007FFFh) not code-protected
CPB = OFF ;Boot block (000000-0007FFh) not code-protected
CPD = OFF ;Data EEPROM not code-protected
WRT0 = OFF ;Block 0 (000800-001FFFh) not write-protected
WRT1 = OFF ;Block 1 (002000-003FFFh) not write-protected
WRT2 = OFF ;Block 2 (004000-005FFFh) not write-protected
WRT3 = OFF ;Block 3 (006000-007FFFh) not write-protected
WRTC = OFF ;Configuration registers (300000-3000FFh) not write-protected
WRTB = OFF ;Boot Block (000000-0007FFh) not write-protected
WRTD = OFF ;Data EEPROM not write-protected
EBTR0 = OFF ;Block 0 (000800-001FFFh) not protected from table reads executed in other blocks
EBTR1 = OFF ;Block 1 (002000-003FFFh) not protected from table reads executed in other blocks
EBTR2 = OFF ;Block 2 (004000-005FFFh) not protected from table reads executed in other blocks
EBTR3 = OFF ;Block 3 (006000-007FFFh) not protected from table reads executed in other blocks
EBTRB = OFF ;Boot Block (000000-0007FFh) not protected from table reads executed in other blocks
Config_End
;**** End of Fuse Configurator Settings ****
Declare Create_Coff On
Symbol RED_LED = LATC.6 ' Red LED
TRISC.6=0 ' Set LED pin to output
INTCON.7 = 0 ' disable global interrupts
INTCON.3 = 1
IOCB.4 = 1
Input PORTB.4 ' Make PORTB.4 an Input
INTCON2.7 = 0 ' Enable pull ups
' Flash the LED on power up
RED_LED = 1
DelayMS 1000
Do
DelayMS 100
Low RED_LED ' Turn off the LED
INTCON.0 = 0 ' Clear the interrupt flag
Sleep ' Put the microcontroller to sleep
DelayMS 100 ' When it wakes up, delay for 100ms
High RED_LED ' Then light the LED
Loop ' Forever
Hi Pepe,
You need to enable global interrupts before "Do"
There is no need to enable global interrupts if they are not going to be used as the manual says.
Hi Pepe,
That did not work either (in a VSM) so looked a bit further here https://www.labcenter.com/documents/?312 and from what I can make out it does not model the wake from sleep.
VSM sleep.jpg
I will have to dig out the hardware to try it on that.
Bob
In version 8.13 of proteus works
How can you put the microprocessor into a deep sleep and with a strict minimum power consumption and wake it up just by putting one of the Port B from low to high or vice versa? I remember have seen some code in late Proton compiler?
Yves
Hi,
I am using V8.8, it might be my schematic. It is pretty annoying that you cannot import a newer design even though it probably does not use anything tht the older version has. I might have upgraded but they could not be bothered to reply to my emails when I had an offer.
This is what I have for then input?
Bin schematic.jpg
Bob
The main problem with waking via a PORTB change is that any of the upper 4 pins of PORTB that see a change will wake up the device, so it is a bit clumsy.
You are better using an INTx event to wake the device up with an external peripheral, so that it is more efficient. Also, the newer PIC devices can make any of their pins operate as an INTx event, so the circuit and code become even more efficient.
However, the, now older, PIC18F25K20 device has three INTx events, which are: INT0 on PORTB.0, INT1 on PORTB.1, and INT2 on PORTB.2, and they can individually be set to create an event with a rising or falling edge occuring on them. i.e. Brought up to VDD or brought down to Gnd.
The program listing below shows a method of waking a PIC18F25K20 device from sleep via any three of the INT pins, and will flash an LED when awake and transmit to a serial terminal which INT event woke up the device:
'
' /\\\\\\\\\
' /\\\///////\\\
' \/\\\ \/\\\ /\\\ /\\\
' \/\\\\\\\\\\\/ /\\\\\ /\\\\\\\\\\ /\\\\\\\\ /\\\\\\\\\\\ /\\\\\\\\\\\ /\\\\\\\\\
' \/\\\//////\\\ /\\\///\\\ \/\\\////// /\\\/////\\\ \////\\\//// \////\\\//// \////////\\\
' \/\\\ \//\\\ /\\\ \//\\\ \/\\\\\\\\\\ /\\\\\\\\\\\ \/\\\ \/\\\ /\\\\\\\\\\
' \/\\\ \//\\\ \//\\\ /\\\ \////////\\\ \//\\/////// \/\\\ /\\ \/\\\ /\\ /\\\/////\\\
' \/\\\ \//\\\ \///\\\\\/ /\\\\\\\\\\ \//\\\\\\\\\\ \//\\\\\ \//\\\\\ \//\\\\\\\\/\\
' \/// \/// \///// \////////// \////////// \///// \///// \////////\//
' Let's find out together what makes a PIC Tick!
'
' Demonstrate waking up from sleep via an INT0 or INT1 or INT2 event caused by PORTB.0 or PORTB.1 or PORTB.2 being brought to ground.
' This is known as a falling edge, and can be changed to a rising edge via a change of the meta-macros used in the program listing.
'
' The SFRs and bit names are for a PIC18F25K20 device and will need changing for various other PIC devices.
'
' Written for the Positron8 BASIC Compiler by Les Johnson.
'
Device = 18F25K20 ' Tell the compiler what device to compile for
Declare Xtal = 64 ' Tell the compiler what frequency the device is operating at (in MHz)
'
' Setup USART1
'
Declare HSerial1_Baud = 9600 ' Set USART1 Baud rate to 9600
Declare HRsout1_Pin = PORTC.6 ' Tell the compiler what pin is used for USART1 TX
'
' Setup the peripheral pins
'
Symbol LED_Pin = PORTC.0 ' The LED attaches to this pin
Symbol Button0_Pin = PORTB.0 ' The button attached to this pin is for an INT0 event
Symbol Button1_Pin = PORTB.1 ' The button attached to this pin is for an INT1 event
Symbol Button2_Pin = PORTB.2 ' The button attached to this pin is for an INT2 event
'
' Create some meta-macros for a PIC18F25K20 device to make the code easier to follow and change
'
'------------------------------------------------------------------
' Global Interrupt meta-macros
'
$define Int_Global_Enable() INTCONbits_GIE = 1 ' Enable global interrupts
$define Int_Global_Disable() INTCONbits_GIE = 0 ' Disable global interrupts
$define Int_Periph_Enable() INTCONbits_PEIE = 1 ' Enable peripheral interrupts
$define Int_Periph_Disable() INTCONbits_PEIE = 0 ' Disable peripheral interrupts
'------------------------------------------------------------------
' INT0 meta-macros for a PIC18F25K20 device
'
$define INT0_IntFlag INTCONbits_INT0IF ' The flag for an INT0 event on PORTB.0
$define Int_INT0_Enable() INTCONbits_INT0IE = 1 ' Enable the INT0 interrupt
$define Int_INT0_Disable() INTCONbits_INT0IE = 0 ' Disable the INT0 interrupt
$define Int_INT0_Rising() INTCON2bits_INTEDG0 = 1 ' Trigger an INT0 event on a rising edge
$define Int_INT0_Falling() INTCON2bits_INTEDG0 = 0 ' Trigger an INT0 event on a falling edge
$define INT0_ClearIntFlag() INT0_IntFlag = 0 ' Clear the INT0 flag
'------------------------------------------------------------------
' INT1 meta-macros for a PIC18F25K20 device
'
$define INT1_IntFlag INTCON3bits_INT1IF ' The flag for an INT1 event on PORTB.1
$define Int_INT1_Enable() INTCON3bits_INT1IE = 1 ' Enable the INT1 interrupt
$define Int_INT1_Disable() INTCON3bits_INT1IE = 0 ' Disable the INT1 interrupt
$define Int_INT1_Rising() INTCON2bits_INTEDG1 = 1 ' Trigger an INT1 event on a rising edge
$define Int_INT1_Falling() INTCON2bits_INTEDG1 = 0 ' Trigger an INT1 event on a falling edge
$define INT1_ClearIntFlag() INT1_IntFlag = 0 ' Clear the INT1 flag
'------------------------------------------------------------------
' INT2 meta-macros for a PIC18F25K20 device
'
$define INT2_IntFlag INTCON3bits_INT2IF ' The flag for an INT2 event on PORTB.2
$define Int_INT2_Enable() INTCON3bits_INT2IE = 1 ' Enable the INT2 interrupt
$define Int_INT2_Disable() INTCON3bits_INT2IE = 0 ' Disable the INT2 interrupt
$define Int_INT2_Rising() INTCON2bits_INTEDG2 = 1 ' Trigger an INT2 event on a rising edge
$define Int_INT2_Falling() INTCON2bits_INTEDG2 = 0 ' Trigger an INT2 event on a falling edge
$define INT2_ClearIntFlag() INT2_IntFlag = 0 ' Clear the INT2 flag
'------------------------------------------------------------------------------
' The main program starts here
' Place the microcontroller to sleep and wake via a falling edge on either INT0 or INT1 or INT2
' INT0 is PORTB.0 on this device, and INT1 is PORTB.1, and INT2 is PORTB.2
'
Main:
Setup() ' Setup the program and the peripherals
Do ' Create a loop
HRsoutLn "Waiting for Button Press to Wake Up"
PinLow LED_Pin ' Extinguish the LED
INT0_ClearIntFlag() ' Clear the INT0 flag before going to sleep
INT1_ClearIntFlag() ' Clear the INT1 flag before going to sleep
INT2_ClearIntFlag() ' Clear the INT2 flag before going to sleep
Sleep ' Put the microcontroller to sleep
PinHigh LED_Pin ' Illuminate the LED when the device wakes up
If INT0_IntFlag = 1 Then ' Was it an INT0 that woke the device up?
HRsoutLn "Device Now Awake via INT0" ' Yes. So transmit to a serial terminal
Elseif INT1_IntFlag = 1 Then ' Was it an INT1 that woke the device up?
HRsoutLn "Device Now Awake via INT1" ' Yes. So transmit to a serial terminal
Elseif INT2_IntFlag = 1 Then ' Was it an INT2 that woke the device up?
HRsoutLn "Device Now Awake via INT2" ' Yes. So transmit to a serial terminal
EndIf
DelayMS 200 ' A delay after the device wakes up
Loop ' Do it forever
'------------------------------------------------------------------------------
' Setup the program and peripherals
' Input : None
' Output : None
' Notes : To change the edge of an INTx, change the Int_INTx_Falling() to Int_INTx_Rising() macros
' And remove the pull-up resistors and add external pull-down resistors to the pins.
'
Proc Setup()
Low PORTA ' \
Low PORTB ' | Make all pins output low to begin with, so they do not draw any current
Low PORTC ' /
Int_Global_Disable() ' Disable global interrupts, just to make sure they are off
PinMode(Button0_Pin, Input_Pullup) ' Make the INT0 pin an input and enable its pull-up resistor
PinMode(Button1_Pin, Input_Pullup) ' Make the INT1 pin an input and enable its pull-up resistor
PinMode(Button2_Pin, Input_Pullup) ' Make the INT2 pin an input and enable its pull-up resistor
Int_INT0_Falling() ' Trigger an INT0 event on a falling edge
Int_INT0_Enable() ' Enable the INT0 interrupt
Int_INT1_Falling() ' Trigger an INT1 event on a falling edge
Int_INT1_Enable() ' Enable the INT1 interrupt
Int_INT2_Falling() ' Trigger an INT2 event on a falling edge
Int_INT2_Enable() ' Enable the INT2 interrupt
EndProc
'------------------------------------------------------------------------------
' Setup the fuses for the 4xPLL with an external crystal on a PIC18F25K20 device
'
Config_Start
FOSC = HSPLL ' HS oscillator, PLL enabled and under software control
Debug = Off ' Background debugger disabled' RB6 and RB7 configured as general purpose I/O pins
XINST = Off ' Instruction set extension and Indexed Addressing mode disabled (Legacy mode)
STVREN = Off ' Reset on stack overflow/underflow disabled
WDTEN = Off ' WDT disabled (control is placed on SWDTEN bit)
FCMEN = Off ' Fail-Safe Clock Monitor disabled
IESO = Off ' Two-Speed Start-up disabled
WDTPS = 128 ' Watchdog is 1:128
BOREN = Off ' Brown-out Reset disabled in hardware and software
BORV = 18 ' VBOR set to 1.8 V nominal
MCLRE = On ' MCLR pin enabled, RE3 input pin disabled
HFOFST = Off ' The system clock is held Off until the HF-INTOSC is stable.
LPT1OSC = Off ' T1 operates in standard power mode
PBADEN = Off ' PORTB<4:0> pins are configured as digital I/O on Reset
CCP2MX = PORTC ' CCP2 input/output is multiplexed with RC1
LVP = Off ' Single-Supply ICSP disabled
Cp0 = Off ' Block 0 (000800-001FFFh) not code-protected
CP1 = Off ' Block 1 (002000-003FFFh) not code-protected
CPB = Off ' Boot block (000000-0007FFh) not code-protected
CPD = Off ' Data eeprom not code-protected
WRT0 = Off ' Block 0 (000800-001FFFh) not write-protected
WRT1 = Off ' Block 1 (002000-003FFFh) not write-protected
WRTB = Off ' Boot block (000000-0007FFh) not write-protected
WRTC = Off ' Configuration registers (300000-3000FFh) not write-protected
WRTD = Off ' Data eeprom not write-protected
EBTR0 = Off ' Block 0 (000800-001FFFh) not protected from table reads executed in other blocks
EBTR1 = Off ' Block 1 (002000-003FFFh) not protected from table reads executed in other blocks
EBTRB = Off ' Boot block (000000-0007FFh) not protected from table reads executed in other blocks
Config_End
Below is a screenshot of the above program listing working in version 7.10 of the Proteus simulator. Pressing one of the three buttons will trigger a specific INT event and wake the device from sleep, and the event that woke up the device will be transmitted to a serial terminal:
Wake Via INTx.jpg
The program listing and Proteus .dsn file is also attached below.