|
|
View previous topic :: View next topic |
Author |
Message |
nurquhar
Joined: 05 Aug 2006 Posts: 149 Location: Redditch, UK
|
12F1822, Interrupt on change, clear IOCAF ? |
Posted: Sun Jul 17, 2011 6:40 am |
|
|
CCS PCM C Compiler, Version 4.122, 61227 17-Jul-11 13:24
I just tested the use of the interrupt on change feature of 12F1822. Although the following test program seems to work and detects a High to Low transiftion of PIN_A5 I had to clear the flag myself in IOCAF reg in the interrupt to stop it immediatly re-firing. I am quite happy to do this but I wondered if a CCS function should be able to do this ? The enable_interrupts() is able to setup IOCAN & IOCAP so why is there not a correspending function to be used in the isr().
Unless of course I have missed something in the documentation
Code: | #include <12F1822.h>
#device adc=8
//////// Program memory: 2048x14 Data RAM: 112 Stack: 16
//////// I/O: 12 Analog Pins: 8
//////// Data EEPROM: 256
//////// C Scratch area: 20 ID Location: 8000
//////// Fuses: LP,XT,HS,RC,INTRC_IO,ECL,ECM,ECH,NOWDT,WDT_SW,WDT_NOSL,WDT
//////// Fuses: PUT,NOPUT,NOMCLR,MCLR,PROTECT,NOPROTECT,CPD,NOCPD,NOBROWNOUT
//////// Fuses: BROWNOUT_SW,BROWNOUT_NOSL,BROWNOUT,CLKOUT,NOCLKOUT,NOIESO
//////// Fuses: IESO,NOFCMEN,FCMEN,WRT,WRT_EECON400,WRT_EECON200,NOWRT
//////// Fuses: PLL_SW,PLL,NOSTVREN,STVREN,BORV25,BORV19,DEBUG,NODEBUG,NOLVP
//////// Fuses: LVP
////////
#FUSES NOWDT //No Watch Dog Timer
#FUSES INTRC_IO //Internal RC Osc, no CLKOUT
#FUSES NOCPD //No EE protection
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOMCLR //Master Clear pin enabled
//#FUSES MCLR //Master Clear pin enabled
#FUSES PUT //Power Up Timer
#FUSES BROWNOUT //Reset when brownout detected
#FUSES NOIESO //Internal External Switch Over mode disabled
//#FUSES IESO //Internal External Switch Over mode enabled
#FUSES NOFCMEN //Fail-safe clock monitor enabled
//#FUSES NODEBUG //No Debug mode for ICD
#FUSES DEBUG //Debug mode for ICD
//#FUSES WDT_NOSL
#FUSES NOWRT //Program Memory Write Protected
//#FUSES PLL // PLL Enabled
#FUSES PLL_SW // PLL under software control, disabled
#FUSES STVREN //Stack full/underflow will cause reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES BORV25 //Brownout reset at 2.5V
#FUSES NOCLKOUT //Output clock on OSC2
#use delay (clock=32000000)
#use fast_io(A)
// Uart TX = C4 (RXD Yellow), RX = C5 (TXD Orange)
//#use rs232(UART1, baud=0,parity=N,bits=8,stop=1, errors)
#byte APFCON = getenv("SFR:APFCON")
#bit RXDTSEL = getenv("bit:RXDTSEL")
#bit TXCKSEL = getenv("bit:TXCKSEL")
#byte IOCAP = getenv("SFR:IOCAP")
#byte IOCAN = getenv("SFR:IOCAN")
#byte IOCAF = getenv("SFR:IOCAF")
// RTS Monitor Input
#define RTS PIN_A2
#define UART_TX PIN_A4
#define UART_RX PIN_A5
// Tris Reg A --543210 - 0=O/P 1==I/P
#define TRIS_A 0b00101100
#define IOCA 0xb0100100
#include <stdlib.h>
#int_ra
void ra_isr()
{
// Mask out the A5 flag
IOCAF &= ~0x20 ;
// Toggle pin to see interrupt on scope
output_low(PIN_A4) ;
delay_us(25) ;
output_high(PIN_A4) ;
}
void main()
{
// Switch to internal 32Mhz Osc, ie 4xPLL x 8Mhz = 32Mhz
setup_oscillator(OSC_8MHZ | OSC_NORMAL | OSC_PLL_ON);
// Turn stuff off
setup_adc_ports(NO_ANALOGS|VSS_VDD);
setup_adc(ADC_OFF);
setup_dac(DAC_OFF);
setup_spi(SPI_SS_DISABLED);
setup_timer_0(T0_internal);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_ccp1(CCP_OFF);
setup_comparator(NC_NC);
// Set port directions for fast I/O
set_tris_a(TRIS_A) ;
// Set pullups RA5(PC_RX)
port_a_pullups(0x20) ;
output_high(PIN_A4) ;
// There is only one "INT_RA" interrupt. Clear it.
clear_interrupt(INT_RA);
// Enable the ints
enable_interrupts(INT_RA5_H2L) ;
enable_interrupts(GLOBAL) ;
while(1) ;
}
|
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Sun Jul 17, 2011 9:38 am |
|
|
The clear_interrupt instruction, accepts the bit fields like the enable instruction. So:
clear_interrupt(INT_RA5);
is meant to clear the required bit.
You need to test with your compiler version though. When I tried this a couple of versions ago, it was clearing the correct bit number, but in address 396, not 393.
It also uses the bit clear instruction, which does potentially mean that if a second edge arrived at the same moment, the value would not clear.
Best Wishes |
|
|
jumanji
Joined: 09 Jun 2011 Posts: 13
|
|
Posted: Fri Nov 18, 2011 5:53 pm |
|
|
I am seeing the same thing.
Code: | clear_interrupt(INT_RA0); |
has no effect - you have to use what nurquhar does to clear it. I tried to define that specific bit (using the #bit directive) and set it to zero and that did not work either. |
|
|
dyeatman
Joined: 06 Sep 2003 Posts: 1934 Location: Norman, OK
|
|
Posted: Fri Nov 18, 2011 5:58 pm |
|
|
In the past, to clear an interrupt you read the pin... That's what i do. _________________ Google and Forum Search are some of your best tools!!!! |
|
|
jumanji
Joined: 09 Jun 2011 Posts: 13
|
|
Posted: Fri Nov 18, 2011 6:08 pm |
|
|
I am reading the pin using a "if (input_state(PIN_A0)" command - that counts doesn't it?
The wierd thing is that I am using code that was originally written for a 12F615. As I was working with the simulator and trying to understand why I was stuck in the interrupt routine, I switched back to the 615 device and noticed that the interrupt in the INTCON register was cleared by itself when I exited the isr. So word to the wise - if you are moving from a 12F615 device to the 12F1822 beware there are changes with how the IOC works. |
|
|
dyeatman
Joined: 06 Sep 2003 Posts: 1934 Location: Norman, OK
|
|
Posted: Sat Nov 19, 2011 7:13 am |
|
|
Is it INSIDE the ISR?
You jump into an existing thread and ask an "open ended" question
on code that we haven't seen and expect us to "know" you have that
statement in your code and where? Mind readers we are not....
The other problem is that you are using a simulator.... _________________ Google and Forum Search are some of your best tools!!!! |
|
|
|
|
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
|