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

Problem with external interrupt on 16F876A

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



Joined: 06 Mar 2010
Posts: 3

View user's profile Send private message

Problem with external interrupt on 16F876A
PostPosted: Thu May 13, 2010 10:33 am     Reply with quote

Hi,

I've got a problem concerning external interrupts.
I am using the code posted somewhere else in this forum for reading the scancodes from a ps/2 keyboard, this works by triggering an interrupt with the falling edge of the ps/2 clock signal.

The code works just fine, but if I add a delay_ms within my main loop (which does nothing but check whether there are characters in the output buffer and sends them with printf via RS232), the interrupt seems to be blocked.
Why is the delay not interrupted by the interrupt and the received char is sent when delay has finished?

Thanks,

Thomas


here my main.c:
Code:

#include "main.h"

//D0 - Clock
//D1 - Data


// Clock must be the interrupt pin
#define CLOCK PIN_B0
#define DATA  PIN_B1

unsigned char bData[16];
unsigned char idx=0;
unsigned char tmp=0;

unsigned char readByte();
unsigned char processByte();
void printKey();
byte keyhit();
unsigned char translate(unsigned char scancode);




volatile byte shiftSet = 0;

volatile byte kbBuffer[16];
volatile byte kbPos = 0;
volatile byte kbSize = 0;
volatile byte capsSet = 0;
volatile byte extFlag = 0;
volatile byte relFlag = 0;
volatile byte key=0;


void sendByte(byte b)
{
// not used in my application
}



void main()
{

   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_CLOCK_DIV_2);
   setup_spi(SPI_SS_DISABLED);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_128);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);

      int i=0;
     int32 cntr = 0;
    unsigned char k=0;
    printf("READY >");

    set_tris_b(0b11111011);
    input(CLOCK);
   input(DATA);

    delay_ms(100);
   printf("Ready!\n");

    ext_int_edge(H_to_L);
    enable_interrupts(INT_EXT);
    enable_interrupts(GLOBAL);
   
    while(1)
    {

   
    printKey();
       // doesn't work anymore if comment slashes in front of one of
       // the following lines is removed
   //for(i=0 ; i < 10000 ; i++);
   //delay_ms(100);   

       
    }
}




void printKey()
{
    unsigned char k = 0;
      if (kbSize > 0)
          {
         disable_interrupts(GLOBAL);
         k = kbBuffer[(kbPos - kbSize)&0x0F];
          kbSize--;
          printf ("%c", k);
         enable_interrupts(GLOBAL);
         }
}

#int_ext
void kbInterrupt()
{
   //disable_interrupts(INT_EXT);
    volatile byte k=0;
    k = processByte();

    if(k != 0)
    {
        kbBuffer[kbPos] = k;
        kbPos = ++kbPos & 0x0F;
        kbSize++;
    }
   //enable_interrupts(INT_EXT);
    return;
}

unsigned char readByte()
{
    int i=0, t=0;
    idx=0;
    tmp=0;

    i=0;
    goto dataread;
   // while(INPUT(CLOCK) != 0);   // Wait for a keypress
            t=0;
       while(INPUT(CLOCK) != 0 && t<255)   // Wait for clock, time out if needed
       {
           delay_us(1);
           t++;
       }
    for(i=0; i<11; i++)
    {
        t=0;
        while(INPUT(CLOCK) != 0 && t<255)   // Wait for clock, time out if needed
        {
            delay_us(1);
            t++;
        }
        dataread:

        bData[idx]=INPUT(DATA);
        idx++;
        if(idx==9)
        {
            for(idx=1; idx<9; idx++)
                if(bData[idx]!=0)
                    tmp|=(1<<(idx-1));

            return tmp;
            idx=0;
            tmp=0;
        }
     //   while(INPUT(CLOCK) == 0);
        t=0;
        while(INPUT(CLOCK) == 0 && t<255)   // Wait for clock, time out if needed
        {
            delay_us(1);
            t++;
        }

    }
}

static const unsigned char scantableAZ[]={
0x1C, 0x32, 0x21, 0x23, 0x24, 0x2B, 0x34, 0x33, 0x43, 0x3B, 0x42, 0x4B, 0x3A, // A-Z
0x31, 0x44, 0x4D, 0x15, 0x2D, 0x1B, 0x2C, 0x3C, 0x2A, 0x1D, 0x22, 0x35, 0x1A};


// Normal numeric scancodes, starting with ',' .
static const unsigned char scantable09n[]=
{
0x41, 0x4E, 0x49, 0x4A, // , - . /
0x45, 0x16, 0x1E, 0x26, 0x25, 0x2E, 0x36, 0x3D, 0x3E, 0x46,     //Digits 0-9
0x00, 0x4C, 0x00, 0x55 // 0 ; 0 =
};

// Shift scancodes, starting at '!'
static const unsigned char scantable09s[]=
{
    0x16, 0x52, 0x26, 0x25, 0x2E, 0x3D, 0x00, 0x46, 0x45, 0x3E, 0x55
};

// Normal misc. scancode map. Scancode, ASCII value
static const unsigned char scanmapn[]=
{0x54, '[', 0x5B, ']', 0x0E, '`', 0x5D, '\\', 0x52, '\''};

// Shifted misc. scancode map. Scancode, ASCII value
static const unsigned char scanmaps[]=
{0x1E, '@', 0x36, '^', 0x4E, '_', 0x54, '{', 0x5B, '}', 0x5D, '|',
0x4C, ':', 0x41, '<', 0x49, '>', 0x4A, '?', 0x0E, '~'};


// Scancode map independent of Shift
static const unsigned char scanmapx[]=
{0x29, ' ', 0x5A, '\r', 0x0D, '\t', 0x76, 27, 0x66, 0x08};

// Extended scancode map
static const unsigned char scanmape[]=
{
0x71, 0x7F
};

unsigned char translate(unsigned char scancode)
{
    int i=0;
   /*
   disable_interrupts(global);
   putc(scancode); //################################################################
   clear_interrupt(INT_EXT);
   enable_interrupts(global);
   */
    if(extFlag == 0)
    {
        for(i=0; i<10; i+=2)
            if(scanmapx[i] == scancode)
                return scanmapx[i+1];

        for(i=0; i<26; i++)
            if(scantableAZ[i] == scancode)
                if(shiftSet ^ capsSet)
                    return i+65;
                else
                    return i+65 + 32;

        if(shiftSet)
        {
            for(i=0; i<11; i++)
                if(scantable09s[i] == scancode)
                    return i+'!';

            for(i=0; i<22; i+=2)
                if(scanmaps[i] == scancode)
                    return scanmaps[i+1];
        } else
        {
            for(i=0; i<18; i++)
                if(scantable09n[i] == scancode)
                    return i+',';

            for(i=0; i<10; i+=2)
                if(scanmapn[i] == scancode)
                    return scanmapn[i+1];
        }
    } else      // Extended keys
    {
        for(i=0; i<2; i+=2)
            if(scanmape[i] == scancode)
                return scanmape[i+1];
    }
    //return '?';
   return 0x00;
}

unsigned char processByte()
{
    unsigned char i, j;
    i = readByte();

    if(i == 0xF0)       //A key is being released
    {
        relFlag = 1;
        return 0;
    }

    if(i == 0xE0)       // Extended key operation
    {
        extFlag = 1;
        relFlag = 0;    //0xE0 always first in sequence, OK to clear this
        return 0;
    }

    if(relFlag == 0)    // Pressing a key
    {
        if(extFlag == 0)    // Non-extended key pressed
        {
            if(i == 0x12 || i == 0x59)
            {
                shiftSet = 1;
                return 0;
            }

            if(i == 0x58)
            {
                sendByte(0xED);
                if(capsSet == 0)
                {
                    capsSet = 1;
                    sendByte(0x04);
                } else
                {
                    capsSet = 0;
                    sendByte(0x00);
                }
                return 0;
            }


        }
        j = translate(i);
        extFlag = 0;
        return j;
    }

    if(relFlag == 1)    //Releasing a key
    {
        relFlag = 0;    //If a flag was set but not handled, we wouldn't have gotten here
        extFlag = 0;    //OK to clear this here

        if(extFlag == 0)   // Releasing a nonextended key
        {
            if(i == 0x12 || i == 0x59)
            {
                shiftSet = 0;
                return 0;
            }

        }
//        } else              // Releasing an extended key
//        {
//            return 0;
//        }

//        return 0;
    }
    return 0;
}


and main.h:
Code:

#include <16F876A.h>
#device adc=8

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES HS                       //High speed Osc (> 4mhz)
#FUSES PUT                      //Powe#FUSES NOPROTECT                //Code not protected from reading
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES BROWNOUT                 //Reset when brownout detected
//#FUSES LVP                      //Low Voltage Programming on B3(PIC16) or B5(PIC18)
#FUSES NOCPD                    //No EE protection
#FUSES NOWRT                    //Program memory not write protected

//#use delay(clock=11059200)
#use delay(clock=21855000)
#use rs232(baud=9600,parity=N,xmit=PIN_B2,rcv=PIN_B3,bits=8)
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu May 13, 2010 11:40 am     Reply with quote

Quote:

Why is the delay not interrupted by the interrupt and the received char is
sent when delay has finished?

It's because you are using CCS delay routines in both your isr and your
main code. Only one instance of the delay routines has been invoked
by the #use delay() line. The delay routines are not re-entrant.
The compiler notices that you are doing this and disables interrupts
around the calls to the delay routines in your main code. This protects
against a crash caused by calling non-reentrant routines during an
interrupt. CCS will issue a warning about this during compilation, if
you have compiler warnings enabled.

One way to fix it would be to change the design of your program so you
don't call any delay routines while inside the isr (interrupt service
routine). Your interrupt routine is fairly long.

Another way is to add a 2nd instance of the CCS library code for the
delay routines. This post has an example:
http://www.ccsinfo.com/forum/viewtopic.php?t=27345&start=1
ThePraiodanish



Joined: 06 Mar 2010
Posts: 3

View user's profile Send private message

PostPosted: Thu May 13, 2010 12:47 pm     Reply with quote

Thanks for your fast reply, I didn't even recognize that warning before Smile
Now it works as it should!
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