Sleep mode with PIC16F18345

This forum handles questions and discussions concerning Microchip’s 8-bit compilers, assemblers, linkers and related tools.

Sleep mode with PIC16F18345

Postby jo7 » Thu Jul 12, 2018 2:06 pm

Hello,
The PIC I'm using has three power off modes: DOZE mode, IDLE mode, and standby mode (P113). I would like using the button to vary these three modes by an interruption.

On my test plate, I put a push button connected to RC5 (at rest 5V on RC5 and if a press on the BP, 0V on RC5), I thus wish to use the interrupts and the different mode of consumption of the mode sleep of my PIC16F18345
1 / BP at rest-> no interruption on RC5-> PIC in SLEEP mode
2 / Press BP-> interrupt on RC5-> PIC in DOZE mode -> Program in operation
3 / RE Press BP-> interrupt on RC5-> stop program-> PIC in IDLE Mode

My current code does the following thing: power on -> sleep mode, press the button -> normal mode
I can not vary the different modes. Thank you in advance !




Code: Select all
// CONFIG1
#pragma config FEXTOSC = OFF    // FEXTOSC External Oscillator mode Selection bits (Oscillator not enabled)
#pragma config RSTOSC = HFINT1  // Power-up default value for COSC bits (HFINTOSC (1MHz))
#pragma config CLKOUTEN = OFF   // Clock Out Enable bit (CLKOUT function is disabled; I/O or oscillator function on OSC2)
#pragma config CSWEN = ON       // Clock Switch Enable bit (Writing to NOSC and NDIV is allowed)
#pragma config FCMEN = ON       // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is enabled)

// CONFIG2
#pragma config MCLRE = ON       // Master Clear Enable bit (MCLR/VPP pin function is MCLR; Weak pull-up enabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config WDTE = OFF       // Watchdog Timer Enable bits (WDT disabled; SWDTEN is ignored)
#pragma config LPBOREN = OFF    // Low-power BOR enable bit (ULPBOR disabled)
#pragma config BOREN = OFF      // Brown-out Reset Enable bits (Brown-out Reset disabled)
#pragma config BORV = LOW       // Brown-out Reset Voltage selection bit (Brown-out voltage (Vbor) set to 2.45V)
#pragma config PPS1WAY = ON     // PPSLOCK bit One-Way Set Enable bit (The PPSLOCK bit can be cleared and set only once; PPS registers remain locked after one clear/set cycle)
#pragma config STVREN = ON      // Stack Overflow/Underflow Reset Enable bit (Stack Overflow or Underflow will cause a Reset)
#pragma config DEBUG = OFF      // Debugger enable bit (Background debugger disabled)

// CONFIG3
#pragma config WRT = OFF        // User NVM self-write protection bits (Write protection off)
#pragma config LVP = ON         // Low Voltage Programming Enable bit (Low Voltage programming enabled. MCLR/VPP pin function is MCLR. MCLRE configuration bit is ignored.)

// CONFIG4
#pragma config CP = OFF         // User NVM Program Memory Code Protection bit (User NVM code protection disabled)
#pragma config CPD = OFF        // Data NVM Memory Code Protection bit (Data NVM code protection disabled)


// PORT A
#define ICSPDAT         RA0                     // Port de programmation
#define POWER           RA1                     // Retour d etat charge batterie
#define MCLR            RA3                     // Port de programmation


// PORT B
#define ledR            RB7                     // +LED rouge

// PORT C
#define BP              RC5                     // Bouton poussoir


#define ON              0                       // Led tirée au +VCC
#define OFF             1                       // Led tiréé au gnd

//#define _XTAL_FREQ      1000000              // Oscillateur réglé à 1MHz

//int etat_Bp;                                   // Variable bouton

#include <xc.h>
#include <pic16f18345.h>

void interrupt ISR ()
{
   if(PIE0bits.IOCIE)  // IT changement d'etat bouton
    {

    CPUDOZEbits.IDLEN = 1;
    IOCCFbits.IOCCF5 = 0;                      // RAZ flag IT

   }
   else if (PIE0bits.IOCIE){

     CPUDOZEbits.DOZEN = 1;
     IOCCFbits.IOCCF5 = 0;                      // RAZ flag IT
     
   }

}

void main(void) {
   
    OSCCON1 = 0x37;                       // Oscillateur interne
    OSCFRQ = 0x06;                        // Frequence oscillateur a 16MHz
    CPUDOZE = 0x00;                       // Choix DOZE/IDLE mode pour economie d energie en veille
    VREGCON = 0x03;                       // Choix DOZE/IDLE mode pour economie d energie en veille
   
    // Reglages des entrees/sorties
    TRISA = 0x37;                         // Choix entrees/sorties
    LATA = 0x00;                          // RAZ des ports
    ANSELA = 0x37;                        // Choix mode analogique/numerique   
    WPUA = 0x20;                          // Resistances de pull-up interne
   
    TRISB = 0xFF;                         // Choix entrees/sorties
    LATB = 0x00;                          // RAZ des ports
    ANSELB = 0x70;                        // Choix mode analogique/numerique
    WPUB = 0x00;                          // Resistances de pull-up interne
   
    TRISC = 0xFF;                         // Choix entrees/sorties
    LATC = 0x00;                          // RAZ des ports
    ANSELC = 0xDF;                        // Choix mode analogique/numerique
    WPUC = 0x20;                          // Resistances de pull-up interne
   
    //WDTCON = 0x3C;
   
    //Reglage des interuptions
    INTCON = 0b11000000;                 // Autorisation des interruptions : GIE=1, PEIE=1 , INTED=0 donc sur front descendant

    IOCCNbits.IOCCN5 = 1;                // Interruption sur la pin RC5 negative activee
    PIE0bits.IOCIE = 1;                  // Valide le changement d'etat
    IOCCFbits.IOCCF5 = 0;                // RAZ flag IT
   
    SLEEP();
   
    while(1){
      }         
}


 
jo7
 
Posts: 4
Joined: Fri Jun 22, 2018 1:27 pm

Re: Sleep mode with PIC16F18345

Postby Jorgef » Thu Jul 12, 2018 7:13 pm

Hi

I think your approach is way too simplistic.
I would not recomend changing modes inside an ISR. Its better to use a variable updated in the ISR to select the mode, and then change the mode in the main loop.

In terms of hardware, triggering interrupts from a push-button is a bad practice.
The transitions of a push-button are not clean, they suffer from mecanichal bouncing of the contacts.
Either you use a good debouncing circuit between the push-button and the PIC pin, or you will have multiple interrupts at each press and release of the push-button, making your final mode totally random.

It you want to test the different modes, just ditch the interrupts thing. Scan the push-button in the main loop using software debouncing and then act on the cleaned push-button actions.
Best regards
Jorge
Jorgef
Verified identity
 
Posts: 9
Joined: Wed May 30, 2018 8:46 pm
PIC experience: Professional 5+ years with MCHP products

Re: Sleep mode with PIC16F18345

Postby brownt » Sat Jul 14, 2018 3:02 pm

How will he scan in main() if the system is in sleep mode?
brownt
 
Posts: 1
Joined: Mon Dec 04, 2017 4:33 am
PIC experience: Experienced Hobbyist

Re: Sleep mode with PIC16F18345

Postby Jorgef » Sat Jul 14, 2018 6:43 pm

Hi

Correct, forgot to explain that part.
Ocasionally I forget that I'm writing for noobs.
Sorry.

Go to sleep with GIE = 0 to prevent branching to the ISR on wake-up.
Use IOC to wake-up, but only to wake-up, not to act in the program state.
After a full scan/debounce cycle act acordingly.

HIH
Best regards
Jorge
Jorgef
Verified identity
 
Posts: 9
Joined: Wed May 30, 2018 8:46 pm
PIC experience: Professional 5+ years with MCHP products


Return to MPLAB XC8

Who is online

Users browsing this forum: No registered users and 0 guests