Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[PIC] [MikroC] 16F1782 interrupt not working

Status
Not open for further replies.

Rtk89

Newbie level 6
Joined
Nov 15, 2013
Messages
12
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
85
Hi every one,

I would like to write a code to PIC16F1782 PIC which put a 8bit number on PORTB. I am working in MikroC
The numbers are stored in an array. There are two button are used for choose the actual value of the array.
I would like to use interrupts to handle the buttons, but still not working in spite of that i spent a lot of hours to solve it.
My code:

Code:
int select[9] = {0x00, 0xFE, 0xFD, 0xFB, 0xF7, 0xEF, 0xDF, 0xBF, 0x7F};
int cnt = 1;
int flag = 0;

void Interrupt() {

  if (INTF_bit){
  INTE_bit = 0;
  
    if (Button(&PORTA, 0, 1, 1))  // Button pressed on PortA.0
     cnt ++;
     if (cnt >= 9){
          cnt = 1;}
     INTF_bit = 0;        // CLear INTF flag
     flag = 1;
     }
   
    if (Button(&PORTA, 1, 1, 1))  { // Button pressed on PortA.1
    cnt --;
    if (cnt < 1){
        cnt = 8;}
    INTF_bit = 0;         // Clear INTF flag
    flag = 1;
   }
   }



void main() {

ANSELA = 0;
ANSELB = 0;
TRISA = 0xff;  //PORTA.0, PORTA.1 is input
TRISB = 0;  //PORTB is output
TRISC = 0;
PORTB = 0xFF;

GIE_bit = 1;
PEIE_bit = 0;
INTE_bit = 1;
INTEDG_bit = 1;

do{

if(flag==1){          // Interrupt
LATB = select[cnt];
flag = 0;             //Reset flag
INTE_bit = 1;         //Re-enable External interrupt
}

}while(1);

}
 

Button should be on RB0/INT pin.


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void Interrupt() {
 
  if (INTF_bit){
  
  
     cnt ++;
     if (cnt >= 9){
          cnt = 1;}
      
     flag = 1;
     }
   
   INTF_bit = 0; 
   }
}

 

Be careful using interrupts for button presses because of debounce issues.
(If you don't know what debounce is, then Google it.)
As you generally want response times in the 10's or perhaps 100's of mSec, by far the best way to debounce in software is to set up a timer with a (say) 1mSec timeout and to sample the input pin(s). When you get a pin with the same value for (say) 10 samples then it could be considered to be debounced and you can then process the 'new' value.
Susan
 
  • Like
Reactions: Rtk89

    Rtk89

    Points: 2
    Helpful Answer Positive Rating
Thank you for the answers.

milan.rajik: Can I handle more buttons with INT?

Aussie Susan: I know about debouncing, but your answer is very helpful. The Button(); library of the MikroC is contains debouncing routines, but I don't know that It can be use as part of ISR?!

Maybe there is a better way to handle buttons with polling?

Best regards,
Rtk
 

Maybe there is a better way to handle buttons with polling?

I think simply moving your ISR code into your main infinite loop should work for polling the buttons (without the INTF interrupt-related statements of course).

EDIT:

Save the value of the current state of your button and compare that with the state of the button on the next loop. If the old state and new state of the button are different, it means the button was pressed. This way, your code will only respond to high-to-low or low-to-high transitions.

the sample code from mikroC is a good example:

Code:
if (Button(&PORTB, 0, 1, 1)) {               // Detect logical one
      oldstate = 1;                              // Update flag
    }
    if (oldstate && Button(&PORTB, 0, 1, 0)) {   // Detect one-to-zero transition
      PORTC = ~PORTC;                            // Invert PORTC
      oldstate = 0;                              // Update flag
    }
 
Last edited:
  • Like
Reactions: Rtk89

    Rtk89

    Points: 2
    Helpful Answer Positive Rating
Code:
[B]volatile char[/B] select[9] = {0x00, 0xFE, 0xFD, 0xFB, 0xF7, 0xEF, 0xDF, 0xBF, 0x7F};
[B]volatile char[/B] cnt = 1;
[B]volatile char[/B] flag = 0;
 
  • Like
Reactions: ernpao

    ernpao

    Points: 2
    Helpful Answer Positive Rating
In PORTB you can use 5 pins with interrupts which are RB0, RB4-RB7. When you use RB4-RB7 use RBIF and in ISR test like


Code C - [expand]
1
2
3
if((RBIF) && (PORTB.F4)) {
 
}



The example I showed is for one button.
 

Thank you for a lot of helps.

ernpao: I changed my code according your post, and it's work fine. I already used this way to handle buttons in the past, but I thought that it is a better to use interrupts for buttons.

Easyrider83:You're right, I changed this too.

milan.rajik:I am not sure that it can be use in this type of PICs.

Next question:
It is possible to save the current value of the modifiers, and contiune with this value at the next starting?

Best regards,
Rtk
 

I think your pic has EEPROM. You can probably save the value of cnt variable in EEPROM and load the value from EEPROM at the beginning of your code. EEPROM does have a limited number of read/write cycles, so be careful how you design when to save the values. What you basically need is non-volatile memory.
 

@ernpao - that should be erase/write (not read/write) cycles. It may sound pedantic, but there are no limits on reading the EEPROM cells.
Also remember that this limit applies to each cell so you should try to spread out the usage of the EEPROM if possible.
However, you are certainly correct that the data EEPROM usage needs to be carefully designed - the data sheet shows 100K E/W cycles (minimum).
Susan
 
  • Like
Reactions: ernpao

    ernpao

    Points: 2
    Helpful Answer Positive Rating
Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top