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 does not fire up reliably!

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



Joined: 15 Sep 2003
Posts: 75

View user's profile Send private message

#int_rda does not fire up reliably!
PostPosted: Fri May 11, 2007 4:56 am     Reply with quote

Hi,

My #int_rda routine does not fire up reliably when I have a string "$123\r" sent to it periodically at 0.5s from another unit. It only fires up occasionally. Therefore, most of the time the "GotPkt" flag is always false. I have tried switching the power OFF and ON but to no avail.

Can someone suggest how I can make it to fire up more reliably?

Thank you in advance.

Code:

#include <18F2620.h>             // Written by CCS
#device ICD=TRUE            // Must rem this line for production
                              //otherwise will not reset properly on power up!
#FUSES NOWDT                    // Watchdog disabled
#FUSES XT                       //Crystal osc <= 4mhz
#FUSES NOLVP                    //No Low Voltage Programming on B3(PIC16) or B5(PIC18)
#FUSES PBADEN                    //PORTB pins are configured as analog input channels on RESET
#FUSES NOLPT1OSC                //Timer1 configured for higher power operation
#FUSES MCLR                     //Master Clear pin enabled


// 4MHz clock (internal clock of MCU=1MHz)
#use     delay(clock=4000000)

// Restart WDT while receiving chars
#use     rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, errors)

#use fast_io(a)               
#use fast_io(b)               
#use fast_io(c)               

#byte port_a = 0xF80          // Give meaningful names for these ports
#byte port_b = 0xF81
#byte port_c = 0xF82


// GLOBAL VARIABLES
char RXcommsBuff[80];
int8 RXIndex = 0;

int1 DataValid = FALSE;
int1 GotPkt = FALSE;

#byte PIR1=0xF9E //for 18 chips
#bit RDAIF=PIR1.5

#include "lcd1.c"

#case

#int_RDA
RDA_isr()
{
   char ch;

   ch = getc();
   if(ch == '$')        //$ Marks beginning of a packet
   {
      DataValid = TRUE;
      RXIndex = 0;      // Reset buffer index
   }

   if(DataValid)
   {
      RXcommsBuff[RXIndex] = ch;   // Add char to buffer
      RXIndex++;                   // Advance buffer pointer

      if(ch == '\r')    //If end of packet
      {
         DataValid = FALSE;
         GotPkt = TRUE;
      }

      if(RXIndex > 80) //If buffer is full
      {
         DataValid = FALSE;
      }
   }
}


void main(void)
{
   int8 i;

   set_tris_a(0b00000000);          // Port A:  A0 to A5 = outputs


   set_tris_b(0b11000000);          // Port B:  B6, B7  = inputs
                                    //          B0 to B5= outputs

   set_tris_c(0b10000100);          // Port C:  TBA

   setup_adc(ADC_OFF);
   delay_ms(1);

   setup_spi(FALSE);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   setup_low_volt_detect(FALSE);
   setup_oscillator(FALSE);

   lcd_init();                // Initialise LCD
   delay_ms(6);               // Allow LCD to settle

   while (RDAIF) getc();      // Flush RX buffer
   clear_interrupt(INT_RDA);
   enable_interrupts(INT_RDA);
   enable_interrupts(GLOBAL);

   while(1)
   {
      if(GotPkt)
      {
         GotPkt=FALSE;

         printf(lcd_putc,"\fRecd= ");
         for(i=0; i<6; i++)
            printf(lcd_putc,"%c", RXcommsBuff[i]);
      }
   }
}
Humberto



Joined: 08 Sep 2003
Posts: 1215
Location: Buenos Aires, La Reina del Plata

View user's profile Send private message

PostPosted: Fri May 11, 2007 8:34 am     Reply with quote

Quote:

My #int_rda routine does not fire up reliably when I have a string "$123\r" sent to it periodically at 0.5s from another unit. It only fires up occasionally


Change
// GLOBAL VARIABLES
char RXcommsBuff[80];

By this:
// GLOBAL VARIABLES
#define RX_Size 6
char RXcommsBuff[RX_Size];


Code:

//Then in the #int_rda:
  ..........
  if(RXIndex >= RX_Size) //If buffer is full
    {
      DataValid = FALSE;
    }
   
// In main()
................
 while(1)
   {
     if(GotPkt)
      {
        disable_interrupts(INT_RDA);
        GotPkt=FALSE;
        printf(lcd_putc,"\fRecd= ");
        for(i=0; i<RX_Size; i++)
             printf(lcd_putc,"%c", RXcommsBuff[i]);
        for(i=0; i<RX_Size; i++)  // Clear the buffer
             RXcommsBuff[i] = 0;
        enable_interrupts(INT_RDA);   
    }
}



Humberto
TL



Joined: 15 Sep 2003
Posts: 75

View user's profile Send private message

PostPosted: Fri May 11, 2007 11:45 am     Reply with quote

Thanks Humberto for your comments.

My real program is quite long and I managed to create this smaller test program to present the problem. I cannot disable the int_rda interrupt in main() for my real program because the remote unit may send requests to it at any time. The RXcommsBuff contents in int_rda() will be copied to another buffer for processing in the real program.

I'll try your changes to see if it makes any difference on Monday. Also, I'll try using another PIC18F2620 just in case. The reason I say this is that I could not get my ICD-S to start a debugging session with the test program. Prior to this, I damaged an ICD-S40 when debugging this problem. I suspect it could be a faulty component in ICD-S40 near the RJ12 socket. I have contacted CCS about the ICD-S40.
Ttelmah
Guest







PostPosted: Fri May 11, 2007 2:57 pm     Reply with quote

As a separate comment (should not occur with your small data sizes, but may do), your 'limit' check for the buffer is invalid. A 80 character buffer, allows indexes, from 0 to 79. An index of 80 (which you allow), would write the character into the _next_ memory location (probably RXindex), which would screw the value in this, resulting in the code failing. You _must_ ensure that tests do limit at the right point.
You are also setting TRIS incorrectly for the port. You set C7=1, and C6=0. Check the data sheet. To use the UART, both C6, and C7, need to be _1_. The UART overrides these, to perform it's I/O.

Best Wishes
TL



Joined: 15 Sep 2003
Posts: 75

View user's profile Send private message

PostPosted: Fri May 11, 2007 3:49 pm     Reply with quote

Thanks Ttelmah for your comments.

Yes, I agree with you about the limit check.

Quote:

You are also setting TRIS incorrectly for the port. You set C7=1, and C6=0. Check the data sheet. To use the UART, both C6, and C7, need to be _1_. The UART overrides these, to perform it's I/O.


I didn't know that! I thought RX is 1 and TX is 0 for all the PIC's. I have checked the datasheet and you are absolutely correct for PIC18F2620. It appears that other PIC's (eg. PIC18F6720) do not follow the above. I'll definitely try your suggestions as well.
TL



Joined: 15 Sep 2003
Posts: 75

View user's profile Send private message

PostPosted: Mon May 14, 2007 8:18 am     Reply with quote

I have finally solved the problem. Smile The transmitting unit was only sending 1 string on power up and the transmitting index was set incorrectly. This explains why I had the #int_rda routine in the receiving unit firing up occasionally!
bungee-



Joined: 27 Jun 2007
Posts: 206

View user's profile Send private message

PostPosted: Wed Jun 27, 2007 7:42 am     Reply with quote

I have INT_RDA related problem. I have transmitter receiver pair which is conditionally working.

Problem is that if I connect receive and transmit pins together at power up receiver does not register, but if I connect transmit receive pins when everything is powered up everything works.

Transmitter code:
Code:

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

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES INTRC_IO                 //Internal RC Osc, no CLKOUT
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOMCLR                   //Master Clear pin used for I/O
#FUSES NOCPD                    //No EE protection
#FUSES PUT                      //Power Up Timer
#FUSES NOIESO                   //Internal External Switch Over mode disabled
#FUSES NOFCMEN                  //Fail-safe clock monitor disabled

#use delay(clock=8000000)
#use rs232(baud=19200,parity=N,xmit=PIN_B7,rcv=PIN_B5,bits=8)

#include "manch.c"

int16 odd;
int t1,t2,t3;

void init()
{
   setup_adc_ports(NO_ANALOGS|VSS_VDD);
   setup_adc(ADC_OFF);
   setup_spi(SPI_SS_DISABLED);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_oscillator( OSC_8MHZ );
}


void main()
{
   init();
   
   
   while(1)
   {
      putc('$');
      for (t1=0;t1<=7;t1++)
      {
         odd=man_encode(t1);
         t2=make8(odd,0);
         t3=make8(odd,1);
         putc(t2);
         putc(t3);
      }
      putc('!');
      delay_ms(500);
   }
   
}


Receiver code:
Code:

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

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES INTRC_IO                 //Internal RC Osc, no CLKOUT
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOMCLR                   //Master Clear pin used for I/O
#FUSES NOCPD                    //No EE protection
#FUSES PUT                      //Power Up Timer
#FUSES NOIESO                   //Internal External Switch Over mode disabled
#FUSES NOFCMEN                  //Fail-safe clock monitor disabled

#use delay(clock=8000000)
#use rs232(baud=19200,parity=N,xmit=PIN_B7,rcv=PIN_B5,bits=8)

//#include "manch.c"

int kbit=0;
int rbuff[20];
short datar,recv=0;


#int_RDA
void  RDA_isr()
{
int r_tmp;

   r_tmp=getc();
   
   if ((r_tmp=='$')&!recv)
   {
      recv=1;
      kbit=0;
      datar=0;
      return;
   }
   
   if (recv)
   {
      if (r_tmp=='!')
      {
         recv=0;
         kbit=0;
         datar=1;
         return;
      }
   
      rbuff[kbit]=r_tmp;
      kbit++;
      
      if (kbit==20)
      {
         recv=0;
         datar=1;
         kbit=0;
         return;
      }
      return;
   }
   return;

}



void init()
{
   setup_adc_ports(NO_ANALOGS|VSS_VDD);
   setup_adc(ADC_OFF);
   setup_spi(SPI_SS_DISABLED);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_oscillator( OSC_8MHZ );   
}


void main()
{
int t1;

   init();
   
   printf("receiving \n\r");

   for (t1=0;t1<=19;t1++) rbuff[t1]=0;
   
   clear_interrupt(INT_RDA);
   enable_interrupts(INT_RDA);
   enable_interrupts(GLOBAL);
   
   while(1)
   {      
      if (datar)
      {
         for(t1=0;t1<=15;t1=t1+2)
         {
//            printf("%x.%x=%x ",rbuff[t1+1],rbuff[t1],man_decode(make16(rbuff[t1+1],rbuff[t1])));
            printf("%d-%x%x ",t1,rbuff[t1+1],rbuff[t1]);
         }
         printf("\n\r");
          datar=0;
      }
      
   }
}


I don't think this is compiller related, but some tiny detail I can not see. Thank you for support.

P.S.: manch.c is manchester encoding/decoding that does not affect other code (I tried with both ways)
kevcon



Joined: 21 Feb 2007
Posts: 142
Location: Michigan, USA

View user's profile Send private message

PostPosted: Wed Jun 27, 2007 8:08 am     Reply with quote

put some pull up resistors on the receive lines
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Jun 27, 2007 11:08 am     Reply with quote

Also add the ERRORS directive to both of your #use rs232() statements
as shown in bold below:
Quote:

#use rs232(baud=19200, xmit=PIN_B7, rcv=PIN_B5, ERRORS)
bungee-



Joined: 27 Jun 2007
Posts: 206

View user's profile Send private message

PostPosted: Wed Jun 27, 2007 12:01 pm     Reply with quote

PCM programmer wrote:
Also add the ERRORS directive to both of your #use rs232() statements
as shown in bold below:
Quote:

#use rs232(baud=19200, xmit=PIN_B7, rcv=PIN_B5, ERRORS)

Thank you very much! This was it. Very Happy
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