CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

16F1783 IOC Interrupt Initialization Problems

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Rex K



Joined: 18 Jun 2015
Posts: 2

View user's profile Send private message

16F1783 IOC Interrupt Initialization Problems
PostPosted: Thu Jun 25, 2015 6:30 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Jun 25, 2015 6:45 pm     Reply with quote

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.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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