|
|
View previous topic :: View next topic |
Author |
Message |
Ben
Joined: 08 Feb 2004 Posts: 1
|
int_rda get stuck |
Posted: Mon Feb 09, 2004 3:35 am |
|
|
Hi,
I'm using two interrupts, int_rda and int_timer2 which is a keypad scanning routine. Everything works fine until i receive a character from the PC, it get stuck in int_rda interrupt. I tried disabling the int_timer2, same result...
What i am doing wrong?
Thanks in advance for your help.
Compiler : PCH 3.182
Device : PIC18F452
Code: |
#include <18F452.h>
#device adc=8
#use delay(clock=10000000)
#fuses NOWDT, XT, NOPROTECT, NOOSCSEN, BROWNOUT, BORV20, NOPUT, STVREN, NODEBUG, NOLVP, NOWRT, NOWRTD, NOWRTB, NOWRTC, NOCPD, NOCPB, NOEBTR, NOEBTRB
#use rs232(baud=9600, bits=8, parity=N, xmit=PIN_C6,rcv=PIN_C7, stream=HOST_PC)
#define RS232_RX PIN_C7
#define RS232_TX PIN_C6
#define Keypad_Col1 PIN_B7
#define Keypad_Col2 PIN_B6
#define Keypad_Col3 PIN_B5
#define Keypad_Col4 PIN_B4
#define Keypad_Row1 PIN_D4
#define Keypad_Row2 PIN_D5
#define Keypad_Row3 PIN_D6
#define Keypad_Row4 PIN_D7
#define Keypad_TestLed PIN_D3
#byte RCSTA = 0xFAB
#bit OERR = RCSTA.1
#bit CREN = RCSTA.4
#priority rda, timer2
int Serial_RxBuffer = 0;
int Keypad_KeyID = 0;
//******************************************************************************
//******************************************************************************
// Timer2 interrupt handler
//******************************************************************************
//******************************************************************************
#int_timer2
void Timer2_tick(void)
{
static int iColumn;
static int iKeyID;
static int iLastKeyID = 0;
static signed int16 iScanTime = 0;
//**** Debounce delay ****
if (iScanTime < 0)
{
iScanTime = iScanTime + 1;
}
else
{
//**** Set all row as input and all column as output ****
Input(Keypad_Row1);
Input(Keypad_Row2);
Input(Keypad_Row3);
Input(Keypad_Row4);
Output_Low(Keypad_col1);
Output_Low(Keypad_col2);
Output_Low(Keypad_col3);
Output_Low(Keypad_col4);
iKeyID = 0;
for (iColumn=0;iColumn<=4;iColumn++)
{
//**** Set the current row high and wait for it to go high ****
Bit_Set(PortB, iColumn+4);
delay_us(2);
switch (PortD >> 4)
{
case 0x01: iKeyID = 1 + iColumn; break;
case 0x02: iKeyID = 5 + iColumn; break;
case 0x04: iKeyID = 9 + iColumn; break;
case 0x08: iKeyID = 13 + iColumn; break;
}
//**** Set the current row low ****
Bit_Clear(PortB, iColumn+4);
}
Output_Bit(Keypad_TestLed, iKeyID != 0);
if (iLastKeyID != iKeyID)
{
if (iKeyID)
{
iScanTime = 1;
iLastKeyID = iKeyID;
}
else
{
if (!Keypad_KeyID)
{
if (iScanTime > 0) Keypad_KeyID = iLastKeyID;
iLastKeyID = 0;
iScanTime = KeyScanTime_Debounce;
}
}
}
else
{
if (iScanTime > 0) iScanTime++;
if ((iScanTime > KeyScanTime_BeforeShift) && (!Keypad_KeyID))
{
Keypad_KeyID = (0x80 + iLastKeyID);
iScanTime = 0;
}
}
}
}
//******************************************************************************
//******************************************************************************
// UART receive data available
//******************************************************************************
//******************************************************************************
#int_rda
void UART_Receive(void)
{
Serial_RxBuffer = getc();
if (OERR)
{
CREN = 0;
CREN = 1;
}
}
//******************************************************************************
//******************************************************************************
// Entry point
//******************************************************************************
//******************************************************************************
void main(void)
{
enable_interrupts(global);
//**** Enable Keypad scanning (Using Timer2) ****
setup_timer_2(T2_DIV_BY_16,100,5);
enable_interrupts(int_timer2);
//**** Enable UART RX interrupt ****
enable_interrupts(int_rda);
WHILE(TRUE)
{
delay_ms(1000);
printf("\fRx: %d", Serial_RxBuffer);
}
} |
Last edited by Ben on Wed Feb 11, 2004 10:29 pm; edited 1 time in total |
|
|
Ttelmah Guest
|
|
Posted: Mon Feb 09, 2004 4:23 am |
|
|
I'd change a series of things:
1) You are specifying 'errors', but are clearing any error condition yourself. This might cause problems. Either remove the OERR test, or the ERRORS directive (I prefer clearing OERR myself, since it allows you to be aware of the error, and do some 'housekeeping' if required, without having to worry about the RS232_ERRORS variable).
2) Either switch to not using streams, or use fgetc. Though 'getc', is meant to automatically use the STDIN (the last #use RS232), I have had problems using the default, when using the streams ability. Hence in general, if streams are in use, I allways use the fgetc form.
3) I'd stop using the long delay. Instead code the printout with something like:
Code: |
void main(void)
{
int8 temp;
enable_interrupts(global);
//**** Enable Keypad scanning (Using Timer2) ****
setup_timer_2(T2_DIV_BY_16,100,5);
enable_interrupts(int_timer2);
//**** Enable UART RX interrupt ****
enable_interrupts(int_rda);
WHILE(TRUE)
{
while (Serial_RxBuffer==0) ;
disable_interrupts(int_rda);
temp=SerialRxBuffer;
SerialRxBuffer=0;
enable_interrupts(int_rda);
printf("\fRx: %d", temp);
}
}
|
Instead of waiting for one second, This will wait till a non zero character is received, and immediately print it. In the event that characters are received while the transmission is taking place, the last one will be seen.
Why have a WDT prescaler value specified, when you have selected 'NOWDT'?.
Best Wishes |
|
|
|
|
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
|