|
|
View previous topic :: View next topic |
Author |
Message |
chingB
Joined: 29 Dec 2003 Posts: 81
|
#int_rda help |
Posted: Fri Jan 16, 2004 4:28 am |
|
|
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 |
Posted: Fri Jan 16, 2004 4:37 am |
|
|
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
|
|
Posted: Fri Jan 16, 2004 5:46 am |
|
|
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
|
|
Posted: Fri Jan 16, 2004 8:58 am |
|
|
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
|
|
Posted: Fri Jan 16, 2004 5:41 pm |
|
|
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
|
|
Posted: Mon Jan 19, 2004 8:55 am |
|
|
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. |
|
|
|
|
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
|