News:

Let's find out together what makes a PIC Tick!

Main Menu

Cannot wake on change on port B

Started by RGV250, Oct 23, 2022, 10:57 PM

Previous topic - Next topic

RGV250

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

Pepe

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
   
 

Bravo

Hi Pepe,
You need to enable global interrupts before "Do"
Retired RF Tech

Pepe

There is no need to enable global interrupts if they are not going to be used as the manual says.

RGV250

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

Pepe

In version 8.13 of proteus works

Yves

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

 
Yves

RGV250

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

top204

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.