|
|
View previous topic :: View next topic |
Author |
Message |
Bill_Smith
Joined: 06 Feb 2004 Posts: 26 Location: Curitiba, Brazil
|
PIC16F688 Interrupt-On-Change |
Posted: Thu Mar 03, 2005 1:51 pm |
|
|
Recently I needed to port a simple CCS C program that was running on a PIC16F88 to its cousin the PIC16F688. The original code used PORT B�s interrupt-on-change mechanism to capture when a switch was activated. As expected, each time the switch was activated (ON = 5V) I received an interrupt via (INT_RB) which I debounced, read the port to determine if the switch was HIGH or LOW, and then set a FLAG. The code worked fine and all was well.
After porting the code to the PIC16F688 I either recieve no interrupts at all when using enable_interrupt(INT_RA), or constant interrupts, indepentent of whether the switch is activated, when using enable_interrupt(INT_RA1). Apparently there are some differences in the way interrupt-on-change works on this part.
Does anyone have any experience with the PIC16F688, specifically using PORT A�s interrupt-on-change function? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Mar 03, 2005 2:08 pm |
|
|
Did you:
1. Disable the comparators ?
2. Configure Port A pins as digital ?
3. Enable the appropriate pins for Interrupt-on-Change by
writing to the IOCA register ?
4. Read Port A, to clear the mis-match condition before exiting
from the ISR ?
If you still can't make it work, then post a small but complete test
program. Be sure to show all #fuses, #use delay(), etc., statements. |
|
|
Bill_Smith
Joined: 06 Feb 2004 Posts: 26 Location: Curitiba, Brazil
|
|
Posted: Thu Mar 03, 2005 4:36 pm |
|
|
Thank you once again PCM Programmer. You were correct in determining that I had not setup PORT A properly.
As a treat for all the newbies, I am listing a version of the program which shows how to implement interrupt-on-change for the PIC16F688.
Code: |
#include <16F688.h>
#use delay(clock=4000000)
#fuses NOWDT,INTRC_IO,NOMCLR,NOPROTECT,BROWNOUT,NOCPD
#zero_ram
// Inputs
#define Switch_ON input(PIN_A2) // SIGNAL INPUT
#define Switch_OFF !input(PIN_A2)
// Outputs
#define LED_On output_low(PIN_C4) // INDICATOR OUTPUT
#define LED_Off output_high(PIN_C4)
#define FREQLOW 331 // 90 Pulses Per Minute (PPM)
#define FREQHIGH 161 // 180 Pulses Per Minute (PPM)
int8 STATE=0x00; //|--XX--|--XX--|--XX--|--XX--|--XX--|--XX--|--XX--| SW1 |
void Flash(void);
#int_TIMER0
void TIMER0_isr(void)
{
set_timer0(34250); // Delay ~13ms @ 4MHz
if(Switch_ON)
bit_set(STATE,0);
else
bit_clear(STATE,0);
disable_interrupts(INT_TIMER0); // Stop Timer 0
}
#int_RA
RA_isr(void)
{
enable_interrupts(INT_TIMER0); // Start Timer 0
}
void main(void)
{
setup_oscillator(OSC_4MHZ,0);
setup_adc_ports(NO_ANALOGS); // Make PORT A Inputs Digital
setup_adc(ADC_OFF); // Turn OFF ADC
setup_comparator(NC_NC_NC_NC); // Disconnect Comparators
set_tris_a(0b00110100); // |--XX--|--XX--|TRISA5|TRISA4|TRISA3|TRISA2|TRISA1|TRISA0|
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256);
enable_interrupts(INT_RA2); // Enable Interrupt-On-Change
enable_interrupts(GLOBAL);
sleep(); // Wait for the switch to close
while(1)
{
switch(STATE) // To add more switches, add more cases
{
case 0x00: // Switch is OFF
sleep(); // Go back to sleep
break;
case 0x01: // Switch is ON
Flash(); // Do something
break;
default: // Who cares
sleep(); // Go back to sleep
break;
}
}
}
void Flash(void)
{
LED_On;
delay_ms(FREQLOW);
LED_Off;
delay_ms(FREQLOW);
}
|
Have fun.
Bill |
|
|
gg Guest
|
|
Posted: Mon Sep 03, 2007 12:17 am |
|
|
I just found the problem. Make sure to disable comparators. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|