PIC Development Board with PK3

jpanhalt

Joined Jan 18, 2008
11,087
I need to buy new brain instead of buying a new calculator and that is not possible

PIC18F45K80 is running with internal clock 8Mhz . so 8Mhz Fosc / 4 = 2Mhz
No new brain needed. You need to learn to check your work. If you do not learn to do that, you will have a difficult time in the workforce. I have fired very few people in my life. The most common reason by far was that they did not check their own work. Someone else had to check everything. Thus, they were superfluous.

Now, take this equation you posted:
1/8000000/256 = 7813 Hz

Even if you had used 2,000,000 instead of 8,000,000, the answer is not in Hz. The reciprocal of hertz is in time/cycle. Had you done the math correctly, you would have found 128 us per tick (cycle), which is exactly what JohnInTexas showed. You should have gotten the correct answer from that.
 

trebla

Joined Jun 29, 2019
599
Global interrupt enable must go after all other peripherial/timer interrupt enabled and interrupt flags cleared. Always clear interrupt flag before enabling corresponding interrupt source or you will get the interrupt instantly after enabling it.
 

Thread Starter

Djsarakar

Joined Jul 26, 2020
489
Even if you had used 2,000,000 instead of 8,000,000, the answer is not in Hz. The reciprocal of hertz is in time/cycle. Had you done the math correctly, you would have found 128 us per tick (cycle), which is exactly what JohnInTexas showed. You should have gotten the correct answer from that.
I am completely agree with you and I apologize I was misunderstood by post #27 https://forum.allaboutcircuits.com/threads/why-led-is-not-turning-off-8051-timers.172425/page-2
 

JohnInTX

Joined Jun 26, 2012
4,787
+1 @jpanhalt and @trebla
FWIW, I ran it up and get 1.035ms interrupt period. Did you set the simulators Instruction Frequency to 2MHz in Project Properties?
Also, you reset TMR0IF and the timer value in the wrong place in the interrupt routine. Do you see the problem?

I need to buy new brain ...
IMO, your primary problem is that instead of taking the time to fully understand a concept and develop a solution from that understanding, you try to imitate something you've seen or done before and hastily throw something together. An example is right here. You kept loading TMR0H because that's what you did in the 8051 stuff, even after being told that it wasn't applicable - twice. You copied code from the internet to do your labs and now find that you didn't learn much from your labs.

To be successful at this, you are going to have to develop a personal discipline to slow down, take each step one by one until you understand fully what is necessary to do the task and consistently apply the lessons from earlier efforts. There just are not any shortcuts to this. Always remember that the time you save by shortcuts is an illusion. By the time you fix all the missteps, especially with the time lag of forum help, you could have taken a little longer to do it right the first time and be successful in a shorter time. It is suprising how many novice programmers do not appreciate this fact.

EDIT: re: stopwatch - you need to run the code a few times through to get the period count.
 

Thread Starter

Djsarakar

Joined Jul 26, 2020
489
You copied code from the internet to do your labs and now find that you didn't learn much from your labs.
sorry I don't agree with this point. I wrote the code myself looking at the datasheet. You are correctTMR0IF and the timer value was in the wrong place in the interrupt routine
C:
#define _XTAL_FREQ 8000000
#include <xc.h>
// PIC18F45K80 Configuration Bit Settings
// 'C' source line config statements
// CONFIG1L
#pragma config RETEN = OFF      // VREG Sleep Enable bit (Ultra low-power regulator is Disabled (Controlled by REGSLP bit))
#pragma config INTOSCSEL = HIGH // LF-INTOSC Low-power Enable bit (LF-INTOSC in High-power mode during Sleep)
#pragma config SOSCSEL = HIGH   // SOSC Power Selection and mode Configuration bits (High Power SOSC circuit selected)
#pragma config XINST = OFF       // Extended Instruction Set (Enabled)
// CONFIG1H
#pragma config FOSC = INTIO2    // Oscillator (Internal RC oscillator)
#pragma config PLLCFG = OFF     // PLL x4 Enable bit (Disabled)
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor (Disabled)
#pragma config IESO = OFF       // Internal External Oscillator Switch Over Mode (Disabled)
// CONFIG2L
#pragma config PWRTEN = OFF     // Power Up Timer (Disabled)
#pragma config BOREN = SBORDIS  // Brown Out Detect (Enabled in hardware, SBOREN disabled)
#pragma config BORV = 3         // Brown-out Reset Voltage bits (1.8V)
#pragma config BORPWR = ZPBORMV // BORMV Power level (ZPBORMV instead of BORMV is selected)
// CONFIG2H
#pragma config WDTEN = OFF      // Watchdog Timer (WDT disabled in hardware; SWDTEN bit disabled)
#pragma config WDTPS = 1048576  // Watchdog Postscaler (1:1048576)
// CONFIG3H
#pragma config CANMX = PORTB    // ECAN Mux bit (ECAN TX and RX pins are located on RB2 and RB3, respectively)
#pragma config MSSPMSK = MSK7   // MSSP address masking (7 Bit address masking mode)
#pragma config MCLRE = ON       // Master Clear Enable (MCLR Enabled, RE3 Disabled)
// CONFIG4L
#pragma config STVREN = ON      // Stack Overflow Reset (Enabled)
#pragma config BBSIZ = BB2K     // Boot Block Size (2K word Boot Block size)
// CONFIG5L
#pragma config CP0 = OFF        // Code Protect 00800-01FFF (Disabled)
#pragma config CP1 = OFF        // Code Protect 02000-03FFF (Disabled)
#pragma config CP2 = OFF        // Code Protect 04000-05FFF (Disabled)
#pragma config CP3 = OFF        // Code Protect 06000-07FFF (Disabled)
// CONFIG5H
#pragma config CPB = OFF        // Code Protect Boot (Disabled)
#pragma config CPD = OFF        // Data EE Read Protect (Disabled)
// CONFIG6L
#pragma config WRT0 = OFF       // Table Write Protect 00800-01FFF (Disabled)
#pragma config WRT1 = OFF       // Table Write Protect 02000-03FFF (Disabled)
#pragma config WRT2 = OFF       // Table Write Protect 04000-05FFF (Disabled)
#pragma config WRT3 = OFF       // Table Write Protect 06000-07FFF (Disabled)
// CONFIG6H
#pragma config WRTC = OFF       // Config. Write Protect (Disabled)
#pragma config WRTB = OFF       // Table Write Protect Boot (Disabled)
#pragma config WRTD = OFF       // Data EE Write Protect (Disabled)
// CONFIG7L
#pragma config EBTR0 = OFF      // Table Read Protect 00800-01FFF (Disabled)
#pragma config EBTR1 = OFF      // Table Read Protect 02000-03FFF (Disabled)
#pragma config EBTR2 = OFF      // Table Read Protect 04000-05FFF (Disabled)
#pragma config EBTR3 = OFF      // Table Read Protect 06000-07FFF (Disabled)
// CONFIG7H
#pragma config EBTRB = OFF      // Table Read Protect Boot (Disabled)


#define Port_Pin           LATBbits.LATB0


volatile int Count = 0;

void Port_pins_Initialized (void);
void Timer0_Initialized (void);
void __interrupt(high_priority) tcInt(void);


void main(void)
{
  
    Timer0_Initialized ();
    Port_pins_Initialized ();
 
    while (1)
    {
    }
}


void Port_pins_Initialized (void)
{
    LATA = LATB = LATC = LATD = LATE =  0;

    TRISA = 0b0000000;// all are output, Unused
    TRISB = 0b0000000;// B0 To LED1, B1 To LED2, B2 To LED3 and B3 To LED4
    TRISC = 0b0000000;// all are output, Unused
    TRISD = 0b0000000;//  All are output, Unused
    TRISE = 0b0000000;// All are output, Unused
  
    ANCON0 = 0; // digital port
    ANCON1 = 0; // digital port
    CM1CON = 0; // Comparator off
    CM2CON = 0; // Comparator off
    ADCON0 = 0; // A/D conversion Disabled
}
    
void Timer0_Initialized (void)
{
     TMR0L = 248;    //Timer0 Register Low Byte   
  
    //T1CON: TIMER1 CONTROL REGISTER
     TMR0ON = 1; //Timer0 On
     T08BIT = 1; // Timer0 is configured as an 8-bit timer/counter0
     T0CS = 0;   // Internal instruction cycle clock (CLKO)
     T0SE = 1;    //Increments on high-to-low transition on T0CKI pin0
     PSA = 0; //Timer0 prescaler is assigned; Timer0 clock input comes from prescaler output   
     //1:8 Prescale value
     T0PS2 = 1; 
     T0PS1 = 1;
     T0PS0 = 1; 

     //INTCON: INTERRUPT CONTROL
    
        PEIE = 0;   //Disables all peripheral interrupts
     TMR0IE = 1; //Enables the TMR0 overflow interrupt
     INT0IE = 0; //Disables the INT0 external interrupt
     RBIE = 0; //Disables the RB port change interrupt
     TMR0IF = 0;// cleared timer overflow flag
     INT0IF = 0; // disabled external interrupt
     RBIF = 0; //disabled Port Change Interrupt Flag bit
     GIE = 1;    // Enable Global Interrupt Enable bit
    
    
     PMD1 = 0b00000000;
}

void __interrupt(high_priority) tcInt(void)
{
  if (TMR0IF == 1) // Timer0 overflow interrupt flag bit
  { 
      Port_Pin  =~ Port_Pin;
      TMR0L = 248;    //Timer0 Register Low Byte     
      TMR0IF = 0;
  }

    
  }
Simulator result
1601565398630.png
 

JohnInTX

Joined Jun 26, 2012
4,787
You copied code from the internet to do your labs and now find that you didn't learn much from your labs.
sorry I don't agree with this point.
I was referring to your comment here:
https://forum.allaboutcircuits.com/...t-turning-off-8051-timers.172425/post-1546386
.. and you are not the first person to do that. I'm not trying to scold you, just identify the things that are holding you back.

But moving along,
The interrupt routine is better. The problem before was that you did not qualify the resetting of the timer with the interrupt flag. That's fixed.
Three improvements to consider:
1) Reload the timer first to minimize the lost counts
2) ADD the count to the timer rather than just load it. That way any accumulated counts in the timer are not lost.
3) Consider a smaller prescaler value and more counts in the timer. The prescaler is cleared whenever you write to TMR0L so it is better to have as few counts in the prescaler as possible.
 
Last edited:

Thread Starter

Djsarakar

Joined Jul 26, 2020
489
Yes. It looks good.
I am comfortable with timer and I can simulate code on simulator but still I have to learn a lot in debugging

For example I have written code When I am trying to debug code (breakpoint 107 __delay_ms(40); // wait) I never get the line

How to start debugging code step by step to inspect problem ?

C:
#define _XTAL_FREQ 8000000
#include <xc.h>
// PIC18F45K80 Configuration Bit Settings
// 'C' source line config statements
// CONFIG1L
#pragma config RETEN = OFF      // VREG Sleep Enable bit (Ultra low-power regulator is Disabled (Controlled by REGSLP bit))
#pragma config INTOSCSEL = HIGH // LF-INTOSC Low-power Enable bit (LF-INTOSC in High-power mode during Sleep)
#pragma config SOSCSEL = HIGH   // SOSC Power Selection and mode Configuration bits (High Power SOSC circuit selected)
#pragma config XINST = OFF       // Extended Instruction Set (Enabled)
// CONFIG1H
#pragma config FOSC = INTIO2    // Oscillator (Internal RC oscillator)
#pragma config PLLCFG = OFF     // PLL x4 Enable bit (Disabled)
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor (Disabled)
#pragma config IESO = OFF       // Internal External Oscillator Switch Over Mode (Disabled)
// CONFIG2L
#pragma config PWRTEN = OFF     // Power Up Timer (Disabled)
#pragma config BOREN = SBORDIS  // Brown Out Detect (Enabled in hardware, SBOREN disabled)
#pragma config BORV = 3         // Brown-out Reset Voltage bits (1.8V)
#pragma config BORPWR = ZPBORMV // BORMV Power level (ZPBORMV instead of BORMV is selected)
// CONFIG2H
#pragma config WDTEN = OFF      // Watchdog Timer (WDT disabled in hardware; SWDTEN bit disabled)
#pragma config WDTPS = 1048576  // Watchdog Postscaler (1:1048576)
// CONFIG3H
#pragma config CANMX = PORTB    // ECAN Mux bit (ECAN TX and RX pins are located on RB2 and RB3, respectively)
#pragma config MSSPMSK = MSK7   // MSSP address masking (7 Bit address masking mode)
#pragma config MCLRE = ON       // Master Clear Enable (MCLR Enabled, RE3 Disabled)
// CONFIG4L
#pragma config STVREN = ON      // Stack Overflow Reset (Enabled)
#pragma config BBSIZ = BB2K     // Boot Block Size (2K word Boot Block size)
// CONFIG5L
#pragma config CP0 = OFF        // Code Protect 00800-01FFF (Disabled)
#pragma config CP1 = OFF        // Code Protect 02000-03FFF (Disabled)
#pragma config CP2 = OFF        // Code Protect 04000-05FFF (Disabled)
#pragma config CP3 = OFF        // Code Protect 06000-07FFF (Disabled)
// CONFIG5H
#pragma config CPB = OFF        // Code Protect Boot (Disabled)
#pragma config CPD = OFF        // Data EE Read Protect (Disabled)
// CONFIG6L
#pragma config WRT0 = OFF       // Table Write Protect 00800-01FFF (Disabled)
#pragma config WRT1 = OFF       // Table Write Protect 02000-03FFF (Disabled)
#pragma config WRT2 = OFF       // Table Write Protect 04000-05FFF (Disabled)
#pragma config WRT3 = OFF       // Table Write Protect 06000-07FFF (Disabled)
// CONFIG6H
#pragma config WRTC = OFF       // Config. Write Protect (Disabled)
#pragma config WRTB = OFF       // Table Write Protect Boot (Disabled)
#pragma config WRTD = OFF       // Data EE Write Protect (Disabled)
// CONFIG7L
#pragma config EBTR0 = OFF      // Table Read Protect 00800-01FFF (Disabled)
#pragma config EBTR1 = OFF      // Table Read Protect 02000-03FFF (Disabled)
#pragma config EBTR2 = OFF      // Table Read Protect 04000-05FFF (Disabled)
#pragma config EBTR3 = OFF      // Table Read Protect 06000-07FFF (Disabled)
// CONFIG7H
#pragma config EBTRB = OFF      // Table Read Protect Boot (Disabled)

void Port_pins_Initialized (void);
void External_Interrupt_setUp (void);

void main(void)
{
  Port_pins_Initialized ();
  External_Interrupt_setUp();
 
    while (1)
    {
    }
}


void Port_pins_Initialized (void)
{
    LATA = LATB = LATC = LATD = LATE =  0;

    TRISA = 0b0000000;// all are output, Unused
    TRISB = 0b0000001;// B0 connected to switch button
    TRISC = 0b0000000;// LED to C2
    TRISD = 0b0000000;//  All are output, Unused
    TRISE = 0b0000000;// All are output, Unused

    ANCON0 = 0; // digital port
    ANCON1 = 0; // digital port
    CM1CON = 0; // Comparator off
    CM2CON = 0; // Comparator off
    ADCON0 = 0; // A/D conversion Disabled
}
void External_Interrupt_setUp ()
{
    INTCON = 0b10010000; //INTERRUPT CONTROL REGISTER
    //Global interrupt enable bit = 1
    //Disables all peripheral interrupts = 0
    //Disables the TMR0 overflow interrupt = 0
    //Enables the INT0 external interrupt = 1
    //Disables the RB port change interrupt = 0
    //TMR0 register has not overflowed = 0
    //clear The INT0 external interrupt Flag = 0,
    // None of the RB<7:4> pins have changed state = 0
  
    INTCON2=0b00000000;  /* Set Interrupt detection on falling Edge*/
}

void __interrupt() tcInt(void)
{
  
    if(INT0IF == 1)
    {
           if (PORTBbits.RB0 == 1)   // check switch if pressed
           {
             __delay_ms(40); // wait
         
             if (PORTBbits.RB0 == 1)   // check switch if pressed
             {
                 LATC2 =~  LATC2;   // LED ON
                __delay_ms(500); // wait
             }
           }
      INT0IF = 0; // clear flag
    }
  
    }
 
Last edited:

JohnInTX

Joined Jun 26, 2012
4,787
Well.. your first problem is trying to debounce a switch with blocking delays inside an interrupt routine. Others may disagree but switches are slow things and interrupts are designed to handle fast things. Interrupting a PIC then delaying 40ms or 500ms is not a good use of the single level interrupt mechanism you have implemented.

Look: Just write a simple function that returns TRUE if the switch is pressed and debounced and FALSE if it isn't. Call that function whenever you want to know what the switch is. I never do low level IO within the code flow. I always use some sort of independent function.
ALso: a TACT switch has a bounce time around 5ms tops so you don't need 40. All that does is slow your system down.

But given all of that, you never reach line 107 because you have a fundamental logic error between the interrupt edge and the switch level you are testing.
Answer this. If INT0 is triggered on a falling edge 1->0, what is the value of RB0 when you enter the interrupt routine? Is it really 1?

You can test this stuff in the simulator by opening Window->Simulator->Stimulus. Add RB0 to the rows, select Set Low as the Action then click Fire. The pin will be set low and the code will enter the interrupt routine. You can follow the value of the pin by opening Window->Simulator->IOpin. Enter RB0 in the row and it will show you the value.

Keep in mind that on your development board, pressing a button puts a '0' on the pin.

Simple debouncer:
#define TRUE 1
#define FALSE 0

//----------------- DEBOUNCE BUTTON  ----------------------
// Returns TRUE if button is closed for at least 5ms
// Returns FALSE otherwise
// Expects button on RB0 and active LOW

__bit ButtonInQ(void)
{
    if (PORTBbits.RB0 == 1) // if button not pressed, return FALSE
            return FALSE;
    else{
        __delay_ms(5);      // else, button pressed, debounce delay
        if(PORTBbits.RB0 == 0) // after delay, if button is still pressed..
            return TRUE;  // return TRUE
        else
            return FALSE;  // else return FALSE
    } // if-else       
}

void main(void)
{
  Port_pins_Initialized ();
  External_Interrupt_setUp();

    while (1){
           if(ButtonInQ()) { // if button is pressed and debounced
                LATC2 =~  LATC2;   // LED TOGGLE
                while(ButtonInQ());  //wait for button release
           }
    } // while
}
 
Last edited:

Thread Starter

Djsarakar

Joined Jul 26, 2020
489
But given all of that, you never reach line 107 because you have a fundamental logic error between the interrupt edge and the switch level you are testing.
Answer this. If INT0 is triggered on a falling edge 1->0, what is the value of RB0 when you enter the interrupt routine? Is it really 1?
Rising edge: signal transition from logic Low to loigic High.
Falling edge: signal transition from logic High to logic Low

If INT0 is triggered on a falling edge High-> Low, The pin RB0 should be LOW

Program for simulator : Pin LATC2 should be toggle when RB0 interrupt occur (The pin RB0 should be LOW )
C:
#define _XTAL_FREQ 8000000
#include <xc.h>
// PIC18F45K80 Configuration Bit Settings
// 'C' source line config statements
// CONFIG1L
#pragma config RETEN = OFF      // VREG Sleep Enable bit (Ultra low-power regulator is Disabled (Controlled by REGSLP bit))
#pragma config INTOSCSEL = HIGH // LF-INTOSC Low-power Enable bit (LF-INTOSC in High-power mode during Sleep)
#pragma config SOSCSEL = HIGH   // SOSC Power Selection and mode Configuration bits (High Power SOSC circuit selected)
#pragma config XINST = OFF       // Extended Instruction Set (Enabled)
// CONFIG1H
#pragma config FOSC = INTIO2    // Oscillator (Internal RC oscillator)
#pragma config PLLCFG = OFF     // PLL x4 Enable bit (Disabled)
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor (Disabled)
#pragma config IESO = OFF       // Internal External Oscillator Switch Over Mode (Disabled)
// CONFIG2L
#pragma config PWRTEN = OFF     // Power Up Timer (Disabled)
#pragma config BOREN = SBORDIS  // Brown Out Detect (Enabled in hardware, SBOREN disabled)
#pragma config BORV = 3         // Brown-out Reset Voltage bits (1.8V)
#pragma config BORPWR = ZPBORMV // BORMV Power level (ZPBORMV instead of BORMV is selected)
// CONFIG2H
#pragma config WDTEN = OFF      // Watchdog Timer (WDT disabled in hardware; SWDTEN bit disabled)
#pragma config WDTPS = 1048576  // Watchdog Postscaler (1:1048576)
// CONFIG3H
#pragma config CANMX = PORTB    // ECAN Mux bit (ECAN TX and RX pins are located on RB2 and RB3, respectively)
#pragma config MSSPMSK = MSK7   // MSSP address masking (7 Bit address masking mode)
#pragma config MCLRE = ON       // Master Clear Enable (MCLR Enabled, RE3 Disabled)
// CONFIG4L
#pragma config STVREN = ON      // Stack Overflow Reset (Enabled)
#pragma config BBSIZ = BB2K     // Boot Block Size (2K word Boot Block size)
// CONFIG5L
#pragma config CP0 = OFF        // Code Protect 00800-01FFF (Disabled)
#pragma config CP1 = OFF        // Code Protect 02000-03FFF (Disabled)
#pragma config CP2 = OFF        // Code Protect 04000-05FFF (Disabled)
#pragma config CP3 = OFF        // Code Protect 06000-07FFF (Disabled)
// CONFIG5H
#pragma config CPB = OFF        // Code Protect Boot (Disabled)
#pragma config CPD = OFF        // Data EE Read Protect (Disabled)
// CONFIG6L
#pragma config WRT0 = OFF       // Table Write Protect 00800-01FFF (Disabled)
#pragma config WRT1 = OFF       // Table Write Protect 02000-03FFF (Disabled)
#pragma config WRT2 = OFF       // Table Write Protect 04000-05FFF (Disabled)
#pragma config WRT3 = OFF       // Table Write Protect 06000-07FFF (Disabled)
// CONFIG6H
#pragma config WRTC = OFF       // Config. Write Protect (Disabled)
#pragma config WRTB = OFF       // Table Write Protect Boot (Disabled)
#pragma config WRTD = OFF       // Data EE Write Protect (Disabled)
// CONFIG7L
#pragma config EBTR0 = OFF      // Table Read Protect 00800-01FFF (Disabled)
#pragma config EBTR1 = OFF      // Table Read Protect 02000-03FFF (Disabled)
#pragma config EBTR2 = OFF      // Table Read Protect 04000-05FFF (Disabled)
#pragma config EBTR3 = OFF      // Table Read Protect 06000-07FFF (Disabled)
// CONFIG7H
#pragma config EBTRB = OFF      // Table Read Protect Boot (Disabled)


void __interrupt() tcInt(void)
{
  
    if(INT0IF == 1)
    { 
        LATC2 =~  LATC2;  
        INT0IF = 0; // clear flag
   
     }
     
}

void main(void)
{
  LATA = LATB = LATC = LATD = LATE =  0;

    TRISA = 0b0000000;// all are output, Unused
    TRISB = 0b0000001;// B0 connected to switch button
    TRISC = 0b0000000;// 
    TRISD = 0b0000000;//  All are output, Unused
    TRISE = 0b0000000;// All are output, Unused

    ANCON0 = 0; // digital port
    ANCON1 = 0; // digital port
    CM1CON = 0; // Comparator off
    CM2CON = 0; // Comparator off
    ADCON0 = 0; // A/D conversion Disabled
    
    //INTCON2: INTERRUPT CONTROL REGISTER 2 
    INTEDG0 = 1;    // Select Interrupt on rising edge 
    
    //INTERRUPT CONTROL REGISTER
    
    RBIF = 0; //clear  Port Change Interrupt Flag bit
    INT0IF = 0; // clear INT0 External Interrupt Flag bit 
    TMR0IF = 0; // clear  TMR0 Overflow Interrupt Flag bit 
    RBIE = 0; // Disable  Port Change Interrupt Enable bit
    INT0IE = 1; //Enable  INT0 External Interrupt Enable bit 
    TMR0IE =0; // Disable TMR0 Overflow Interrupt Enable bit 
    PEIE = 0; // Disable  Peripheral Interrupt Enable bit
    GIE = 1; // Enable  Global Interrupt Enable bit
     
    while (1)
    {
    }
    
}
You can test this stuff in the simulator by opening Window->Simulator->Stimulus. Add RB0 to the rows, select Set Low as the Action then click Fire. The pin will be set low and the code will enter the interrupt routine.
I did as you said but I never entered into interrupt routine

1601635730206.png

You can follow the value of the pin by opening Window->Simulator->IOpin. Enter RB0 in the row and it will show you the value.
1601635914242.png
 

JohnInTX

Joined Jun 26, 2012
4,787
Line 85.

I am sorry but I have to ask, did you think to try other things before posting? Part of good debugging is when something doesn't work the first time is to poke around and see if something else DOES work. That process can inform your thinking and suggest ways proceed.
 

Thread Starter

Djsarakar

Joined Jul 26, 2020
489
I am sorry but I have to ask, did you think to try other things before posting? Part of good debugging is when something doesn't work the first time is to poke around and see if something else DOES work. That process can inform your thinking and suggest ways proceed.
I have used polling method instead of interrupt and code work fine for me. When I press button LED toggle at each press
C:
// PIC18F45K80 Configuration Bit Settings
// 'C' source line config statements
// CONFIG1L
#pragma config RETEN = OFF      // VREG Sleep Enable bit (Ultra low-power regulator is Disabled (Controlled by REGSLP bit))
#pragma config INTOSCSEL = HIGH // LF-INTOSC Low-power Enable bit (LF-INTOSC in High-power mode during Sleep)
#pragma config SOSCSEL = HIGH   // SOSC Power Selection and mode Configuration bits (High Power SOSC circuit selected)
#pragma config XINST = OFF      // Extended Instruction Set (Disabled)
// CONFIG1H
#pragma config FOSC = INTIO2    // Oscillator (Internal RC oscillator)
#pragma config PLLCFG = OFF     // PLL x4 Enable bit (Disabled)
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor (Disabled)
#pragma config IESO = OFF       // Internal External Oscillator Switch Over Mode (Disabled)
// CONFIG2L
#pragma config PWRTEN = OFF     // Power Up Timer (Disabled)
#pragma config BOREN = OFF      // Brown Out Detect (Disabled in hardware, SBOREN disabled)
#pragma config BORV = 3         // Brown-out Reset Voltage bits (1.8V)
#pragma config BORPWR = ZPBORMV // BORMV Power level (ZPBORMV instead of BORMV is selected)
// CONFIG2H
#pragma config WDTEN = OFF      // Watchdog Timer (WDT disabled in hardware; SWDTEN bit disabled)
#pragma config WDTPS = 1048576  // Watchdog Postscaler (1:1048576)
// CONFIG3H
#pragma config CANMX = PORTB    // ECAN Mux bit (ECAN TX and RX pins are located on RB2 and RB3, respectively)
#pragma config MSSPMSK = MSK7   // MSSP address masking (7 Bit address masking mode)
#pragma config MCLRE = ON       // Master Clear Enable (MCLR Enabled, RE3 Disabled)
// CONFIG4L
#pragma config STVREN = ON      // Stack Overflow Reset (Enabled)
#pragma config BBSIZ = BB2K     // Boot Block Size (2K word Boot Block size)
// CONFIG5L
#pragma config CP0 = OFF        // Code Protect 00800-01FFF (Disabled)
#pragma config CP1 = OFF        // Code Protect 02000-03FFF (Disabled)
#pragma config CP2 = OFF        // Code Protect 04000-05FFF (Disabled)
#pragma config CP3 = OFF        // Code Protect 06000-07FFF (Disabled)
// CONFIG5H
#pragma config CPB = OFF        // Code Protect Boot (Disabled)
#pragma config CPD = OFF        // Data EE Read Protect (Disabled)
// CONFIG6L
#pragma config WRT0 = OFF       // Table Write Protect 00800-01FFF (Disabled)
#pragma config WRT1 = OFF       // Table Write Protect 02000-03FFF (Disabled)
#pragma config WRT2 = OFF       // Table Write Protect 04000-05FFF (Disabled)
#pragma config WRT3 = OFF       // Table Write Protect 06000-07FFF (Disabled)
// CONFIG6H
#pragma config WRTC = OFF       // Config. Write Protect (Disabled)
#pragma config WRTB = OFF       // Table Write Protect Boot (Disabled)
#pragma config WRTD = OFF       // Data EE Write Protect (Disabled)
// CONFIG7L
#pragma config EBTR0 = OFF      // Table Read Protect 00800-01FFF (Disabled)
#pragma config EBTR1 = OFF      // Table Read Protect 02000-03FFF (Disabled)
#pragma config EBTR2 = OFF      // Table Read Protect 04000-05FFF (Disabled)
#pragma config EBTR3 = OFF      // Table Read Protect 06000-07FFF (Disabled)
// CONFIG7H
#pragma config EBTRB = OFF      // Table Read Protect Boot (Disabled)
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
#include <xc.h>
#define _XTAL_FREQ 8000000

#define TRUE 1
#define FALSE 0

__bit ButtonInQ(void)
{
    if (PORTBbits.RB0 == 1) // if button not pressed, return FALSE
            return FALSE;
    else{
        __delay_ms(5);      // else, button pressed, debounce delay
        if(PORTBbits.RB0 == 0) // after delay, if button is still pressed..
            return TRUE;  // return TRUE
        else
            return FALSE;  // else return FALSE
    }     
}


void main(void)
{
  //  INTCON = 0;
  
    LATA =  0;
    LATB =  0;
    LATC =  0;
    LATD =  0;
    LATE =  0;

    TRISA = 0b0000000;//
    TRISB = 0b0000001;// button connected to External interrupt pin as an input.
    TRISC = 0b0000000;// RC2 LED
    TRISD = 0b0000000;// All are output, Unused
    TRISE = 0b0000000;// All are output, Unused
  
    ANCON0 = 0; // digital port
    ANCON1 = 0; // digital port
    CM1CON = 0; // Comparator off
    CM2CON = 0; // Comparator off
    ADCON0 = 0; // A/D conversion Disabled
  
    INTCONbits.INT0IF   = 0;    // Clear INT0 */
    INTCONbits.INT0IE   = 1;    //Enable INT0 interrupt
  
    while (1)
    {
        if(ButtonInQ())
        {
          if(INTCONbits.INT0IF = 1  )
          {     
             LATC2 =~  LATC2;   // LED TOGGLE
                while(ButtonInQ());  //wait for button release
            INTCONbits.INT0IF = 0;
         //   INTCONbits.INT0IE = 1;
        }
        }
    }
}
 
Last edited:

JohnInTX

Joined Jun 26, 2012
4,787
*sigh*
DId you even try to debug #120? What did you find out?

#122 compiles with warnings. Never run code with warnings. Fix the warnings first, always.

You are missing the point of the ButtonInQ routine.

Why is the external interrupt enable bit set?
Why are you polling INTOIF at all?
 
Last edited:

Thread Starter

Djsarakar

Joined Jul 26, 2020
489
*sigh*
DId you even try to debug #120? What did you find out?
Yes I have attached two screenshot,
#122 compiles with warnings. Never run code with warnings. Fix the warnings first, always.
Why is the external interrupt enable bit set?
if(INTCONbits.INT0IF == 1 )
Code:
// PIC18F45K80 Configuration Bit Settings
// 'C' source line config statements
// CONFIG1L
#pragma config RETEN = OFF      // VREG Sleep Enable bit (Ultra low-power regulator is Disabled (Controlled by REGSLP bit))
#pragma config INTOSCSEL = HIGH // LF-INTOSC Low-power Enable bit (LF-INTOSC in High-power mode during Sleep)
#pragma config SOSCSEL = HIGH   // SOSC Power Selection and mode Configuration bits (High Power SOSC circuit selected)
#pragma config XINST = OFF      // Extended Instruction Set (Disabled)
// CONFIG1H
#pragma config FOSC = INTIO2    // Oscillator (Internal RC oscillator)
#pragma config PLLCFG = OFF     // PLL x4 Enable bit (Disabled)
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor (Disabled)
#pragma config IESO = OFF       // Internal External Oscillator Switch Over Mode (Disabled)
// CONFIG2L
#pragma config PWRTEN = OFF     // Power Up Timer (Disabled)
#pragma config BOREN = OFF      // Brown Out Detect (Disabled in hardware, SBOREN disabled)
#pragma config BORV = 3         // Brown-out Reset Voltage bits (1.8V)
#pragma config BORPWR = ZPBORMV // BORMV Power level (ZPBORMV instead of BORMV is selected)
// CONFIG2H
#pragma config WDTEN = OFF      // Watchdog Timer (WDT disabled in hardware; SWDTEN bit disabled)
#pragma config WDTPS = 1048576  // Watchdog Postscaler (1:1048576)
// CONFIG3H
#pragma config CANMX = PORTB    // ECAN Mux bit (ECAN TX and RX pins are located on RB2 and RB3, respectively)
#pragma config MSSPMSK = MSK7   // MSSP address masking (7 Bit address masking mode)
#pragma config MCLRE = ON       // Master Clear Enable (MCLR Enabled, RE3 Disabled)
// CONFIG4L
#pragma config STVREN = ON      // Stack Overflow Reset (Enabled)
#pragma config BBSIZ = BB2K     // Boot Block Size (2K word Boot Block size)
// CONFIG5L
#pragma config CP0 = OFF        // Code Protect 00800-01FFF (Disabled)
#pragma config CP1 = OFF        // Code Protect 02000-03FFF (Disabled)
#pragma config CP2 = OFF        // Code Protect 04000-05FFF (Disabled)
#pragma config CP3 = OFF        // Code Protect 06000-07FFF (Disabled)
// CONFIG5H
#pragma config CPB = OFF        // Code Protect Boot (Disabled)
#pragma config CPD = OFF        // Data EE Read Protect (Disabled)
// CONFIG6L
#pragma config WRT0 = OFF       // Table Write Protect 00800-01FFF (Disabled)
#pragma config WRT1 = OFF       // Table Write Protect 02000-03FFF (Disabled)
#pragma config WRT2 = OFF       // Table Write Protect 04000-05FFF (Disabled)
#pragma config WRT3 = OFF       // Table Write Protect 06000-07FFF (Disabled)
// CONFIG6H
#pragma config WRTC = OFF       // Config. Write Protect (Disabled)
#pragma config WRTB = OFF       // Table Write Protect Boot (Disabled)
#pragma config WRTD = OFF       // Data EE Write Protect (Disabled)
// CONFIG7L
#pragma config EBTR0 = OFF      // Table Read Protect 00800-01FFF (Disabled)
#pragma config EBTR1 = OFF      // Table Read Protect 02000-03FFF (Disabled)
#pragma config EBTR2 = OFF      // Table Read Protect 04000-05FFF (Disabled)
#pragma config EBTR3 = OFF      // Table Read Protect 06000-07FFF (Disabled)
// CONFIG7H
#pragma config EBTRB = OFF      // Table Read Protect Boot (Disabled)
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
#include <xc.h>
#define _XTAL_FREQ 8000000

#define TRUE 1
#define FALSE 0

__bit ButtonInQ(void)
{
    if (PORTBbits.RB0 == 1) // if button not pressed, return FALSE
            return FALSE;
    else{
        __delay_ms(5);      // else, button pressed, debounce delay
        if(PORTBbits.RB0 == 0) // after delay, if button is still pressed..
            return TRUE;  // return TRUE
        else
            return FALSE;  // else return FALSE
    }    
}


void main(void)
{
  //  INTCON = 0;

    LATA =  0;
    LATB =  0;
    LATC =  0;
    LATD =  0;
    LATE =  0;

    TRISA = 0b0000000;//
    TRISB = 0b0000001;// button connected to External interrupt pin as an input.
    TRISC = 0b0000000;// RC2 LED
    TRISD = 0b0000000;// All are output, Unused
    TRISE = 0b0000000;// All are output, Unused

    ANCON0 = 0; // digital port
    ANCON1 = 0; // digital port
    CM1CON = 0; // Comparator off
    CM2CON = 0; // Comparator off
    ADCON0 = 0; // A/D conversion Disabled

    INTCONbits.INT0IF   = 0;    // Clear INT0 */
   
    while (1)
    {
        if(ButtonInQ())
        {
          if(INTCONbits.INT0IF == 1  )
          {    
             LATC2 =~  LATC2;   // LED TOGGLE
                while(ButtonInQ());  //wait for button release
            INTCONbits.INT0IF = 0;
         //   INTCONbits.INT0IE = 1;
        }
        }
    }
}

Why are you polling INTOIF at all?
generally if interrupt code is not working then we test polling method to check flag if flag is working then there may problem with interrupt setting. That's why I thought I should try interrupt first
 

Thread Starter

Djsarakar

Joined Jul 26, 2020
489
Hi @JohnInTX

I haven't solved the problem yet And here it may be because I do not understand how the button denounce on the external interrupt. I am making one flow chart

Push button is connected to external interrupt pin so when button pressed LED should be toggle.

I have tried to make one flow chart that show the process of LED toggle by push button on the external interrupt.

I know my flow chart is incomplete because I don't understand how to fix the button denounce issue

I have attached document. Sorry if my flowchart is not good, I have only tried to explained the process through block
 

Attachments

trebla

Joined Jun 29, 2019
599
For button debouncing you need add some period of time during external interrupt can not set flag. For example do not clear flag right after LED toggle but add small delay after it and check in the interrupt routine is the flag zero before setting it again. Or use the sample functions from your other thread for non-blocking debounce. Currently your routine has only two states which are more or less the same as button states and therefore it responds immediately to all the noise coming from button.
 

Thread Starter

Djsarakar

Joined Jul 26, 2020
489
I done one experiment to check if my interrupt code is working. I have used sensor instead of push button so code works fine for sensor

When sensor detect the object, LED toggles at every interrupt
C:
#define _XTAL_FREQ 8000000
#include <xc.h>
// PIC18F45K80 Configuration Bit Settings
// 'C' source line config statements
// CONFIG1L
#pragma config RETEN = OFF      // VREG Sleep Enable bit (Ultra low-power regulator is Disabled (Controlled by REGSLP bit))
#pragma config INTOSCSEL = HIGH // LF-INTOSC Low-power Enable bit (LF-INTOSC in High-power mode during Sleep)
#pragma config SOSCSEL = HIGH   // SOSC Power Selection and mode Configuration bits (High Power SOSC circuit selected)
#pragma config XINST = OFF       // Extended Instruction Set (Enabled)
// CONFIG1H
#pragma config FOSC = INTIO2    // Oscillator (Internal RC oscillator)
#pragma config PLLCFG = OFF     // PLL x4 Enable bit (Disabled)
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor (Disabled)
#pragma config IESO = OFF       // Internal External Oscillator Switch Over Mode (Disabled)
// CONFIG2L
#pragma config PWRTEN = OFF     // Power Up Timer (Disabled)
#pragma config BOREN = SBORDIS  // Brown Out Detect (Enabled in hardware, SBOREN disabled)
#pragma config BORV = 3         // Brown-out Reset Voltage bits (1.8V)
#pragma config BORPWR = ZPBORMV // BORMV Power level (ZPBORMV instead of BORMV is selected)
// CONFIG2H
#pragma config WDTEN = OFF      // Watchdog Timer (WDT disabled in hardware; SWDTEN bit disabled)
#pragma config WDTPS = 1048576  // Watchdog Postscaler (1:1048576)
// CONFIG3H
#pragma config CANMX = PORTB    // ECAN Mux bit (ECAN TX and RX pins are located on RB2 and RB3, respectively)
#pragma config MSSPMSK = MSK7   // MSSP address masking (7 Bit address masking mode)
#pragma config MCLRE = ON       // Master Clear Enable (MCLR Enabled, RE3 Disabled)
// CONFIG4L
#pragma config STVREN = ON      // Stack Overflow Reset (Enabled)
#pragma config BBSIZ = BB2K     // Boot Block Size (2K word Boot Block size)
// CONFIG5L
#pragma config CP0 = OFF        // Code Protect 00800-01FFF (Disabled)
#pragma config CP1 = OFF        // Code Protect 02000-03FFF (Disabled)
#pragma config CP2 = OFF        // Code Protect 04000-05FFF (Disabled)
#pragma config CP3 = OFF        // Code Protect 06000-07FFF (Disabled)
// CONFIG5H
#pragma config CPB = OFF        // Code Protect Boot (Disabled)
#pragma config CPD = OFF        // Data EE Read Protect (Disabled)
// CONFIG6L
#pragma config WRT0 = OFF       // Table Write Protect 00800-01FFF (Disabled)
#pragma config WRT1 = OFF       // Table Write Protect 02000-03FFF (Disabled)
#pragma config WRT2 = OFF       // Table Write Protect 04000-05FFF (Disabled)
#pragma config WRT3 = OFF       // Table Write Protect 06000-07FFF (Disabled)
// CONFIG6H
#pragma config WRTC = OFF       // Config. Write Protect (Disabled)
#pragma config WRTB = OFF       // Table Write Protect Boot (Disabled)
#pragma config WRTD = OFF       // Data EE Write Protect (Disabled)
// CONFIG7L
#pragma config EBTR0 = OFF      // Table Read Protect 00800-01FFF (Disabled)
#pragma config EBTR1 = OFF      // Table Read Protect 02000-03FFF (Disabled)
#pragma config EBTR2 = OFF      // Table Read Protect 04000-05FFF (Disabled)
#pragma config EBTR3 = OFF      // Table Read Protect 06000-07FFF (Disabled)
// CONFIG7H
#pragma config EBTRB = OFF      // Table Read Protect Boot (Disabled)


void __interrupt() tcInt(void)
{

    if(INT0IF == 1)
    {
        LATC2 =~  LATC2;  // Interrupt detected the LED will toggle.
     
        __delay_ms(500); // wait 500ms
     
        INT0IF = 0; // clear flag

     }
 
}

void main(void)
{
  LATA = LATB = LATC = LATD = LATE =  0;

    TRISA = 0b0000000;// all are output, Unused
    TRISB = 0b0000001;// B0 connected to sensor
    TRISC = 0b0000000;// RC2 LED
    TRISD = 0b0000000;//  All are output, Unused
    TRISE = 0b0000000;// All are output, Unused

    ANCON0 = 0; // digital port
    ANCON1 = 0; // digital port
    CM1CON = 0; // Comparator off
    CM2CON = 0; // Comparator off
    ADCON0 = 0; // A/D conversion Disabled
 
    //INTCON2: INTERRUPT CONTROL REGISTER 2
    INTEDG0 = 0;    // Select Interrupt on falling edge
 
    //INTERRUPT CONTROL REGISTER
 
    RBIF = 0; //clear  Port Change Interrupt Flag bit
    INT0IF = 0; // clear INT0 External Interrupt Flag bit
    TMR0IF = 0; // clear  TMR0 Overflow Interrupt Flag bit
    RBIE = 0; // Disable  Port Change Interrupt Enable bit
    INT0IE = 1; //Enable  INT0 External Interrupt Enable bit
    TMR0IE =0; // Disable TMR0 Overflow Interrupt Enable bit
    PEIE = 0; // Disable  Peripheral Interrupt Enable bit
    GIE = 1; // Enable  Global Interrupt Enable bit
 
    while (1)
    {
    }
 
}
sensor link https://tkkrlab.nl/wiki/Arduino_KY-033_Hunt_sensor_module

I'm having trouble doing the same thing with the switch button. I will try to figure out the problem
 
Last edited:

Thread Starter

Djsarakar

Joined Jul 26, 2020
489
We have already worked with timer interrupt. I can set interrupt for 1ms. So I want to use timer interrupt for switch debouncing. Interrupt will activates at every 1ms. Count up when switch is press and count down when switch is not press. So when counts is equal to 50 . It means switch is press

We should count down when switch is not press, then I dot know What happen how we finish switch release time?

IMG_20201005_195217.jpg
 

trebla

Joined Jun 29, 2019
599
If button is pressed then your routine will flash LED for every 50 ms because it is not aware if it is first time the button press is detected or button is hold down for long time. Same is about delay if button is not pressed - even if button is not touched for days, we insert some delay.
Better react to button press status if button is pressed for first time and if it is released for first time. For this you must add a status variable (some small integer value from 0 to 255) for remembering previous checks.
So in your timer interrupt routine you check first this status variable and if it is for example zero (means that button is not pressed previously), only then check if button pressed. If it is not then exit interrupt routine and leave status variable unchanged. Otherwise change status to 1, toggle LED, reload counter for 50ms and exit interrupt routine.
Next time the timer interrupt occurs is 1ms passed. Then you look again to status and if it is 1 then decrement counter value by one and exit interrupt routine. And so on with all process, i described it in your other thread already. Make plan which numbers to use in status variable and when to change it. Example:
#define IDLE 0
#define PRESS_DETECTED 1
#define PRESS_DEBOUNCED 2
#define RELEASE_DETECTED 3
 
Top