ThePraiodanish
Joined: 06 Mar 2010 Posts: 3
|
Problem with external interrupt on 16F876A |
Posted: Thu May 13, 2010 10:33 am |
|
|
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)
|
|
|