|
|
View previous topic :: View next topic |
Author |
Message |
TL
Joined: 15 Sep 2003 Posts: 75
|
#int_rda does not fire up reliably! |
Posted: Fri May 11, 2007 4:56 am |
|
|
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
|
|
Posted: Fri May 11, 2007 8:34 am |
|
|
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
|
|
Posted: Fri May 11, 2007 11:45 am |
|
|
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
|
|
Posted: Fri May 11, 2007 2:57 pm |
|
|
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
|
|
Posted: Fri May 11, 2007 3:49 pm |
|
|
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
|
|
Posted: Mon May 14, 2007 8:18 am |
|
|
I have finally solved the problem. 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
|
|
Posted: Wed Jun 27, 2007 7:42 am |
|
|
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
|
|
Posted: Wed Jun 27, 2007 8:08 am |
|
|
put some pull up resistors on the receive lines |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Jun 27, 2007 11:08 am |
|
|
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
|
|
Posted: Wed Jun 27, 2007 12:01 pm |
|
|
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. |
|
|
|
|
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
|