PIC16F1508 Interrupt on change - Page 1
Forum section: electronics / general

author: tox3
author_rank: Contributor
timestamp: April 27, 2015, 07:06:28 pm
content: Hello i have problem with PIC16F1508 interrupt on change. I have button connected to RB6. Pin is pulled high, before pressing button. I am using microC compiler. When i press button pic seems to freeze.There is my code for setup and interruptsvoid interrupt(){if(INTCON.TMR0IF = 1){if(counter == 9){switch(n) {case 0:ledOn(1);break;case 1:ledOn(2);break;}}if(counter < 9){ledOn(counter);}switch(n) {case 0: PORTC = 0; PORTB.B4=0; PORTB.B5=1; dig2seg(d1);break;case 1: PORTC = 0; PORTB.B4=1; PORTB.B5=0; dig2seg(d10);break;}n++;if(n >= 2) n = 0;TMR0 = 0;INTCON.T0IF = 0;}else if(INTCON.IOCIF == 1){if(IOCBF.IOCBF6){if(done == 0){sum += counter;done = 1;}IOCBF.IOCBF6 = 0;INTCON.IOCIF = 0;}}}void config() {OPTION_REG = 0b10000000; // disable all WPUPORTA = 0;PORTB = 0;PORTC = 0;ANSELA = 0;ANSELB = 0;ANSELC = 0;WPUA = 0;WPUB = 0;TRISA = 0x00;TRISB = 0x40; // RB6 inputTRISC = 0x00;IOCBN = 0x40;INTCON = 0xA8; // GIE + TMR0IE + IOCIETMR0 = 0;}

author: mikerj
author_rank: Super Contributor
timestamp: April 27, 2015, 08:16:39 pm
content: You have to remove the port mismatch condition by reading PortB. Because you haven't done this, the PIC is spending all it's time in the interrupt handler.Also the 'if else' construct within the interrupt handler looks wrong to me. Normally you want to check for all interrupt flags whilst you are in the ISR.

author: Bruce Abbott
author_rank: Frequent Contributor
timestamp: April 27, 2015, 08:44:41 pm
content: In the statement "if(INTCON.TMR0IF = 1)", '=' should be '=='. Your code is setting TMR0IF to 1 before testing it, so the result is always true.This isn't a problem when a timer interrupt occurs, because then the timer int flag is set anyway. However itisa problem when a pin change int is received, since the interrupt handler tries to process a timer int instead. As a result the pin change int never gets serviced and its flag never gets reset, causing the interrupt handler to be reentered continuously and leaving no processor time left to do anything else!

author: tox3
author_rank: Contributor
timestamp: April 27, 2015, 08:55:07 pm
content: Thanks as always simple mistakes

author: android
author_rank: Regular Contributor
timestamp: April 27, 2015, 09:06:35 pm
content: I always codeCode:if (INTCON.TMR0IF)where possible...to avoid unintentional assignment. It is such a common typo that I'm surprised that there isn't a compiler warning for if statements containing assignments (which is bad coding style anyway IMHO).

author: SL4P
author_rank: Super Contributor
timestamp: April 28, 2015, 12:11:38 am
content: Just to simplify your code - I'd change the code surrounding 'n' to a single bit value, and simply toggle it true/false.Then your test becomes if (n) ...Where do the LEDs get turned off ?

author: tox3
author_rank: Contributor
timestamp: April 28, 2015, 12:24:36 am
content: Good suggestion. When LED turns on previous LED turns off

author: mikerj
author_rank: Super Contributor
timestamp: April 28, 2015, 07:07:34 am
content: Quote from: android on April 27, 2015, 09:06:35 pmEvery C compiler I've used has warned about this.The other issue to consider when writing an interrupt handler for the 8 bit PICs is whether you ever intentionally disable any of the handled interrupts. If you do then you should also test the enable bit in the interrupt handler:Code:if (INTCON.TMR0IF && INTCON.TMR0IE)If you don't do this you can find the interrupt is being handled even though it's disabled.

author: matseng
author_rank: Frequent Contributor
timestamp: April 28, 2015, 07:21:18 am
content: Quote from: mikerj on April 28, 2015, 07:07:34 amBy default gcc doesn't say anything for assignments in conditions unless some of the warning flags are enabled.At least not in gcc version 4.8.2 under Centos. It happily compilesCode:void main(void) {int a=1;if (a=2) a=3;}regardless of optimizations level as long as no warnings is explicitly enabled.

author: android
author_rank: Regular Contributor
timestamp: April 28, 2015, 10:58:37 am
content: QuoteYou are quite right. I was thinking of the general case...if I had a choice between codingCode:if (a == 1)andCode:if (a)then I would choose the latter (for Boolean variables at least) to minimise the chances of accidentally omitting the second "=". I'd even be a bit more verbose and codeCode:if (volumeUpButtonPressed)but that's just me.