|
|
View previous topic :: View next topic |
Author |
Message |
Rex K
Joined: 18 Jun 2015 Posts: 2
|
16F1783 IOC Interrupt Initialization Problems |
Posted: Thu Jun 25, 2015 6:30 pm |
|
|
I am working on a module to read quadratic 4x rotary encoder. I have a problem with the interrupt initialization. I am using two pins that trigger interrupts on both the rising and falling edges. I ran the program in debug with a watch on INTCON, IOCAN, & IOCAP and a breakpoint at 'while' line.
CCS PCM 5.046 compiler, MPLABxIDE 2.35 PICKit3
Code: |
/*
* File: EncoderMain.c
* Author: Rex Klopfenstein
* Quadrature 4X Decoder
* Encoder Phase A - Pin A0
* Phase B - Pin A1
* Phase Z - Pin A2
* Created on June 19, 2015, 9:04 PM
*/
#include <16F1783.h>
#include <stdio.h>
#include <stdlib.h>
#fuses NOPROTECT,INTRC_IO,MCLR,NOLVP,PUT,NOBROWNOUT
#fuses NOWRT,NOCPD,NOCLKOUT,
#use delay(clock=16000000)
#use fast_io(A)
#byte IOCAF = 0x393 //Map IOC Flag-A Registers
#bit IOCAF0 = IOCAF.0
#bit IOCAF1 = IOCAF.1
#bit IOCAF2 = IOCAF.2
#define clear_IOC_F0() IOCAF0=0
#define clear_IOC_F1() IOCAF1=0
#define clear_IOC_F2() IOCAF2=0
/*
*
*/
unsigned int16 EncoderCnts; //Raw Encoder Counts (0-3999 Cnts)
const signed int8 LookUpTable[]={0,-1,1,0,1,0,0,-1,-1,0,0,1,0,1,-1,0};
unsigned int8 PortData;
unsigned int8 temp;
/* IOC Interrupt Handler*/
#INT_IOC
void EncoderUpdate_ISR()
{
if(interrupt_active(INT_IOC_A0))
{
clear_IOC_F0(); // Clear IOC Flag
set_tris_a(0x03);
PortData=PortData<<2; // Process Next Encoder "tick"
PortData=PortData|((input_a()&0x0C)>>2);
EncoderCnts=EncoderCnts+LookUpTable[PortData&0x0F];
}
if(interrupt_active(INT_IOC_A1))
{
clear_IOC_F1(); // Clear IOC Flag
set_tris_a(0x03);
PortData=PortData<<2; // Process Next Encoder "tick"
PortData=PortData|((input_a()&0x0C)>>2);
EncoderCnts=EncoderCnts+LookUpTable[PortData&0x0F];
}
if(interrupt_active(INT_IOC_A2))
{
clear_IOC_F2(); // clear IOC Flag
set_tris_a(0x03);
// Future process
}
}
void main(void)
{
PortData=0;
EncoderCnts=0;
setup_adc_ports(NO_ANALOGS);
enable_interrupts(INT_IOC_A0_L2H); // Enable Interrupts
enable_interrupts(INT_IOC_A0_H2L);
enable_interrupts(INT_IOC_A1_L2H);
enable_interrupts(INT_IOC_A1_H2L);
enable_interrupts(GLOBAL);
while(1) // Kill Time
{
// temp=temp+1;
}
} |
I believe that INTCON(0xCA) & IOCAN(0x03) configure O.K. IOCAP seems to not change from 0x00, it should be 0x03.
The other question I have deals with I/O Port initialization. In data sheet for 16F1783, there is a sample asm code to initialize PORTA (pg 117). It clears PORTA, clears LATA, clears ANSELA, and then set TRISA. How does this sequence relate to ccs fast_io()?
Rex Klopfenstein
Bowling Green, OH |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Jun 25, 2015 6:45 pm |
|
|
Rex K wrote: |
I believe that INTCON(0xCA) & IOCAN(0x03) configure O.K. IOCAP
seems to not change from 0x00, it should be 0x03 |
Your interrupt enable statements are wrong. Your 2nd line in each set will
cancel out the first line. To get both edges enabled, you need to do it
as shown below:
Code: | void main(void)
{
PortData=0;
EncoderCnts=0;
setup_adc_ports(NO_ANALOGS);
// enable_interrupts(INT_IOC_A0_L2H);
// enable_interrupts(INT_IOC_A0_H2L);
enable_interrupts(INT_IOC_A0); // *** Add this line
// enable_interrupts(INT_IOC_A1_L2H);
// enable_interrupts(INT_IOC_A1_H2L);
enable_interrupts(INT_IOC_A1); // *** Add this line
enable_interrupts(GLOBAL);
while(1) // Kill Time
{
// temp=temp+1;
}
} |
Rex K wrote: |
It clears PORTA, clears LATA, clears ANSELA, and then set TRISA. How
does this sequence relate to ccs fast_io()?
|
Look at the .LST file. The compiler inserts start-up code to clear ANSELA:
Quote: |
.................... void main(void)
008D: MOVLW @7A
008E: MOVLB 01
008F: MOVWF OSCCON
0090: MOVLB 03
0091: CLRF ANSELA
0092: CLRF ANSELB
0093: MOVLB 02
0094: CLRF CM1CON1
0095: CLRF CM1CON0 |
If you put an output_a(0) statement at the start of main(), it will clear LATA:
Code: | .................... output_a(0);
0096: CLRF LATA
|
Your set_tris_a() statement will load the TRISA register:
Code: | .................... set_tris_a(0x03);
0097: MOVLW 03
0098: MOVLB 01
0099: MOVWF TRISA |
No CCS function writes to PortA. But the 16F1783 data sheet says:
Quote: | A write operation to the LATx register has the same
effect as a write to the corresponding PORTx register. |
|
|
|
|
|
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
|