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

int_rda get stuck

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



Joined: 08 Feb 2004
Posts: 1

View user's profile Send private message

int_rda get stuck
PostPosted: Mon Feb 09, 2004 3:35 am     Reply with quote

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







PostPosted: Mon Feb 09, 2004 4:23 am     Reply with quote

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
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