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 help

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



Joined: 29 Dec 2003
Posts: 81

View user's profile Send private message

#int_rda help
PostPosted: Fri Jan 16, 2004 4:28 am     Reply with quote

hello...

I have a code that will receive packets from a PC. The packet send by the PC is of variable length but not exceeding 64bytes.

Code list:

Code:

#define RX_SIZE 64         // RS485 buffer for serial reception
byte rxbuffer[RX_SIZE];    // RS485 serial RX buffer
byte rx_in  = 0;           // RS485 RX data IN index
byte rx_out = 0;           // RS485 RX data OUT index

#int_rda
void rx_isr()         // RS485 serial RX interrupt service routine
{
   int t;                   // local data storage

   if (kbhit(Com1))
   {
      t = fgetc(Com1);  // get rx data and save to buffer
      rxbuffer[rx_in] = t ; // and save to buffer
      t = rx_in;                    // save current rx index
      rx_in = (rx_in+1) % RX_SIZE;  // increment index
   }
}



My concern is? how can I able to detect that their is no character send by the PC? and How can I incorporate a flag that will prevent a multi-trigger of another packet while the program process the previous packet?

BTW, I am using PIC18F452 at 20MHz clock.

Need your info, comments and/or suggestions.

Thank you.
Ttelmah
Guest







Re: #int_rda help
PostPosted: Fri Jan 16, 2004 4:37 am     Reply with quote

chingB wrote:
hello...

I have a code that will receive packets from a PC. The packet send by the PC is of variable length but not exceeding 64bytes.

Code list:

Code:

#define RX_SIZE 64         // RS485 buffer for serial reception
byte rxbuffer[RX_SIZE];    // RS485 serial RX buffer
byte rx_in  = 0;           // RS485 RX data IN index
byte rx_out = 0;           // RS485 RX data OUT index

#int_rda
void rx_isr()         // RS485 serial RX interrupt service routine
{
   int t;                   // local data storage

   if (kbhit(Com1))
   {
      t = fgetc(Com1);  // get rx data and save to buffer
      rxbuffer[rx_in] = t ; // and save to buffer
      t = rx_in;                    // save current rx index
      rx_in = (rx_in+1) % RX_SIZE;  // increment index
   }
}



My concern is? how can I able to detect that their is no character send by the PC? and How can I incorporate a flag that will prevent a multi-trigger of another packet while the program process the previous packet?

BTW, I am using PIC18F452 at 20MHz clock.

Need your info, comments and/or suggestions.

Thank you.

1) Consider flow control.
2) Do a search back through the archives. Neutone (I think), published a very tidy combination of buffered receive, with a timer based 'time out'.

Best Wishes
chingB



Joined: 29 Dec 2003
Posts: 81

View user's profile Send private message

PostPosted: Fri Jan 16, 2004 5:46 am     Reply with quote

Hi,

I got the code of neutone... listed below:

Code:

#int_TIMER1                                                 //*********************************
TIMER1_isr()                                                // 1.5 byte periods after last byte I&O
{  disable_interrupts(int_TIMER1);                          // TMR1 Overflow Interrupt Enable bit off
   PacketA_Byte_Count=PacketA_Index;                        // Store length of packet
   if (PacketA_TX)                                          // Has last bit cleared transmit shift buffer?
   {  PacketA_TX=0;                                         // Turn off 485 transmitter driver
   }
   else                                                     // Incomming packet recieved?
   {  PacketA_IN=1;                                         // Tag packet for processing
   }
}

#int_RDA                                                    //**************
RDA_isr()                                                   // BYTE RECEIVED
{  PacketA_Data=fgetC(chanA);                               // Store incoming byte
   if(!PacketA_IN&&!TXIE)                                   // Don't receive transmitting noise or overrun last packet
   {  if(bit_test(RS232_ERRORS,2))                          // Check for framing errors
      {  if (++PacketA_Errors & 8)                          // If 32 errors
         {  if(!(PacketA_Baud & 16))                        // is baudrate locked
            {  if(++PacketA_Baud & 8)
               PacketA_Baud=0;
               if(PacketA_Baud==0)
               {  Set_UART_Speed(57600,chanA);
                  PacketA_timeout=64128;
               }
               if(PacketA_Baud==1)
               {  Set_UART_Speed(38400,chanA);
                  PacketA_timeout=63424;
               }
               if(PacketA_Baud==2)
               {  Set_UART_Speed(28800,chanA);
                  PacketA_timeout=62720;
               }
               if(PacketA_Baud==3)
               {  Set_UART_Speed(19200,chanA);
                  PacketA_timeout=61312;
               }
               if(PacketA_Baud==4)
               {  Set_UART_Speed(9600,chanA);
                  PacketA_timeout=57088;
               }
               if(PacketA_Baud==5)
               {  Set_UART_Speed(4800,chanA);
                  PacketA_timeout=48640;
               }
               if(PacketA_Baud==6)
               {  Set_UART_Speed(2400,chanA);
                  PacketA_timeout=31744;
               }
               if(PacketA_Baud==7)
               {  Set_UART_Speed(1200,chanA);
                  PacketA_timeout=0;
               }
            }
         }
      }
      PacketA[PacketA_Index++]=PacketA_Data;                // Place incoming byte in Packet Buffer
      set_timer1(PacketA_timeout);                          // Wait 1.5 byte periods then interrupt
      TMR1IF=0;                                             // Clear timer1 overflow Interrupt Flag bit
      enable_interrupts(int_TIMER1);                        // TMR1 Overflow Interrupt Enable bit on
   }
}



set_timer1(PacketA_timeout); ---> how can I compute for timer1 using PIC18F452 at 20MHz clock? what would be the difference if I use timer3 instead of timer1?

Is timer1 calculation has a correlation with the baudrate for serial communication? What would the calculation in order to have 1.5bytes period for either timer1 or timer3?

I notice that the code use PacketA_TX=0; as flow control for transmit and receive packet. I don't see any point on how I can detect that PC has already stop sending data? I can't figure out the code for multi-trigger prevention.

In addition, I plan to use a 115,200bps baudrate for the UART.

Any help please....

Thnx
Neutone



Joined: 08 Sep 2003
Posts: 839
Location: Houston

View user's profile Send private message

PostPosted: Fri Jan 16, 2004 8:58 am     Reply with quote

chingB wrote:
Hi,

I got the code of neutone... listed below:

Code:

#int_TIMER1                                                 //*********************************
TIMER1_isr()                                                // 1.5 byte periods after last byte I&O
{  disable_interrupts(int_TIMER1);                          // TMR1 Overflow Interrupt Enable bit off
   PacketA_Byte_Count=PacketA_Index;                        // Store length of packet
   if (PacketA_TX)                                          // Has last bit cleared transmit shift buffer?
   {  PacketA_TX=0;                                         // Turn off 485 transmitter driver
   }
   else                                                     // Incomming packet recieved?
   {  PacketA_IN=1;                                         // Tag packet for processing
   }
}

#int_RDA                                                    //**************
RDA_isr()                                                   // BYTE RECEIVED
{  PacketA_Data=fgetC(chanA);                               // Store incoming byte
   if(!PacketA_IN&&!TXIE)                                   // Don't receive transmitting noise or overrun last packet
   {  if(bit_test(RS232_ERRORS,2))                          // Check for framing errors
      {  if (++PacketA_Errors & 8)                          // If 32 errors
         {  if(!(PacketA_Baud & 16))                        // is baudrate locked
            {  if(++PacketA_Baud & 8)
               PacketA_Baud=0;
               if(PacketA_Baud==0)
               {  Set_UART_Speed(57600,chanA);
                  PacketA_timeout=64128;
               }
               if(PacketA_Baud==1)
               {  Set_UART_Speed(38400,chanA);
                  PacketA_timeout=63424;
               }
               if(PacketA_Baud==2)
               {  Set_UART_Speed(28800,chanA);
                  PacketA_timeout=62720;
               }
               if(PacketA_Baud==3)
               {  Set_UART_Speed(19200,chanA);
                  PacketA_timeout=61312;
               }
               if(PacketA_Baud==4)
               {  Set_UART_Speed(9600,chanA);
                  PacketA_timeout=57088;
               }
               if(PacketA_Baud==5)
               {  Set_UART_Speed(4800,chanA);
                  PacketA_timeout=48640;
               }
               if(PacketA_Baud==6)
               {  Set_UART_Speed(2400,chanA);
                  PacketA_timeout=31744;
               }
               if(PacketA_Baud==7)
               {  Set_UART_Speed(1200,chanA);
                  PacketA_timeout=0;
               }
            }
         }
      }
      PacketA[PacketA_Index++]=PacketA_Data;                // Place incoming byte in Packet Buffer
      set_timer1(PacketA_timeout);                          // Wait 1.5 byte periods then interrupt
      TMR1IF=0;                                             // Clear timer1 overflow Interrupt Flag bit
      enable_interrupts(int_TIMER1);                        // TMR1 Overflow Interrupt Enable bit on
   }
}



set_timer1(PacketA_timeout); ---> how can I compute for timer1 using PIC18F452 at 20MHz clock? what would be the difference if I use timer3 instead of timer1?

Is timer1 calculation has a correlation with the baudrate for serial communication? What would the calculation in order to have 1.5bytes period for either timer1 or timer3?

I notice that the code use PacketA_TX=0; as flow control for transmit and receive packet. I don't see any point on how I can detect that PC has already stop sending data? I can't figure out the code for multi-trigger prevention.

In addition, I plan to use a 115,200bps baudrate for the UART.

Any help please....

Thnx


PacketA_TX is the pin that turns the 485 driver chip to transmit.
Timer 3 will work just as well as timer 1.
I was using a clock of 19660800hz so 20Mhz would use the same timer preloads just fine.
If you plan to run at 115,200bps baudrate you should not use this routine. I had a lot of timing issues with getting into and out of the interupt code at that baud rate.
chingB



Joined: 29 Dec 2003
Posts: 81

View user's profile Send private message

PostPosted: Fri Jan 16, 2004 5:41 pm     Reply with quote

Hi,

Can you provide me a math calculation for the values of PacketA-timeout. Do you have any idea on how I can prevent muti-trigger of packet?

Thanx
Neutone



Joined: 08 Sep 2003
Posts: 839
Location: Houston

View user's profile Send private message

PostPosted: Mon Jan 19, 2004 8:55 am     Reply with quote

The timer counts up from 0 to 65536 it then overflows to 0 and interupt occures.

With the timer set to increment every instruction cycle what value do you preload to cause the timer to interupt after a specified period?

The byte period is 1mS for 9600 baud.
The timeout period is 1.5 byte periods.
There are 1 instruction cycle in 0.25 uS at 20Mhz crystle.
There are 6000 instruction cycles in in 1.5mS.
The value to preload for for 9600 baud is 65536-6000.

This assumes a byte stream on the serial port. You can not get this to work if the bytes arrive with a pause between them.

To prevent multitrigger of packets do not clear the packet in flag untill the packet has been fully processed.
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