|
|
View previous topic :: View next topic |
Author |
Message |
ktallevi
Joined: 17 Dec 2005 Posts: 58
|
115,200bps UART Communication problem |
Posted: Tue Oct 03, 2006 11:35 am |
|
|
Im having trouble communcating with an external device over 115,200bps. Bascially I send a command to the module using fprintf, then enable RDA interupt... the data coming back from the module should get printed onto the debug port (going to HyperTerminal) sometimes it works, sometimes not..and sometimes I get garbage coming back from the external device.
I copied and pasted the relavent code below from main.c and main.h
Any help would be greatly appreciated... thanks.
main.c
--
#int_RDA
RDA_isr()
{
buffer[buffidx] = fgetc(Bluetooth);
if(buffer[buffidx] == 0x0D) {
buffer[buffidx++]=0x00;
fprintf(DebugPort,buffer);
}
else { buffidx++; }
}
void main()
{
enable_interrupts(int_rda);
enable_interrupts(GLOBAL);
fprintf(Bluetooth,"AT&F\n\r");
}
main.h
--
#include <18F8722.h>
#use delay(clock=40000000)
#FUSES H4
#use rs232(baud=115200,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,stream=Bluetooth)
#use rs232(baud=115200,parity=N,xmit=PIN_E1,rcv=PIN_D7,bits=8,FORCE_SW,stream=DebugPort) |
|
|
jma_1
Joined: 08 Feb 2005 Posts: 147 Location: Wisconsin
|
|
Posted: Tue Oct 03, 2006 12:13 pm |
|
|
Greetings,
You might try adding 'ERRORS' to your #use rs232 definition. I have never used the 'FORCE_SW' option. Do you need this? Try removing it. How is the bufferidx index initialized? Do you ever reset it (bufferidx = (bufferidx + 1) % BUFFER_SIZE or similar? Perhaps your buffer is overflowing. Does the behavior happen when only a single byte is transmitted?
Cheers,
JMA |
|
|
ktallevi
Joined: 17 Dec 2005 Posts: 58
|
115,200bps UART Communication problem |
Posted: Tue Oct 03, 2006 12:19 pm |
|
|
Sorry I forgot to include:
free(buffer);
buffidx=0;
before the fprintf command... to clear the buffer and reset the buffer index. I added errors and still get the same problem. Seems that the PIC is not grabbing the incoming data all the time properly.
Maybe CTS/RTS flow control would improve things. |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Tue Oct 03, 2006 12:31 pm |
|
|
Is it possible for you to use the second hardware UART in your chip? It would make things a lot easier and more stable. |
|
|
Ttelmah Guest
|
|
Posted: Tue Oct 03, 2006 2:52 pm |
|
|
The problem is that you are doing much too much inside the interrupt, when you output the buffer contents. You don't say how large the buffer is, but assuming it is (say) eight characters long, then when you output the contents, the receive ISR will be unable to accept any characters for eight character times. If your buffer is larger, even longer. There is only a maximum of 2.999 characters of hardware buffering, so if more than this many characters arrive in this time, date _will_be lost/corrupted.
First, use the second hardware port for your output, and preferably drive this using an interrupt driven output routine. To output the 'buffer', just set a flag in the ISR, and print it from inside the main (this won't help if using the software serial, since the interrupts will interfere with the transmission).
Best Wishes |
|
|
ktallevi
Joined: 17 Dec 2005 Posts: 58
|
115,200bps UART Communication problem |
Posted: Tue Oct 03, 2006 5:09 pm |
|
|
My main concern isnt the Debug port output (using software uart). My biggest concern is capturing the incoming bytes from the hardware "Bluetooth" serial port.
The code is simply grabbing all the incoming bytes until an "enter" keystroke is detected. (signalling the end of the data) Once that is detected it will output the data to the debug port. My buffer is more than large enough, 100bytes, and the incoming data is no more than 22 bytes at a time.
Unless there is an easier way to grab the incoming data at 115,200 and store it in a buffer until the 'enter' key is detected? (timed getc doesnt seem fast enough). |
|
|
asmallri
Joined: 12 Aug 2004 Posts: 1634 Location: Perth, Australia
|
|
Posted: Tue Oct 03, 2006 6:19 pm |
|
|
Here is an example doing the processing outside the ISR
Code: | #int_RDA
void serial_isr()
///////////////////////////////////////////////////////////////////////////
// Serial Rx Interrupt Handler
//
// Invoked when a character has been received by the hardware UART
//
// Entry:
// RxBaseC Console receive ring buffer
// RxHeadC Next free loaction in the receive buffer
// RxCQsize Size of the receive buffer
///////////////////////////////////////////////////////////////////////////
{
RxBaseC[RxHeadC++]=getc();
RxHeadC %= RxCQsize;
// indicate serial receive activity
TMR_Activity = CTMR_Activity;
bit_set(LED_Health);
}
|
Main execution loop calls ServiceRxConsole() on each pass
Code: | while (1)
{
// Main execution loop
// service the Console Rx Q
ServiceRxQConsole();
//.......
}
}
|
ServiceRxConsole() parses the ring buffer and constructs a linear command string
Code: | void ServiceRxQConsole()
///////////////////////////////////////////////////////////////////////////
//
// ServiceRxQConsole
//
// Basic polled Console Rx Q service subroutine (NON BLOCKING)
// Receives a byte from the Console Rx buffer and queues it to the
// console command buffer.
//
// Once a <CR> has been detected SrvCMD is invoked.
//
// On Exit:
// RxTailC = RxHeadC (Console buffer emptied)
//
// Calls:
// putc_QModem
//
///////////////////////////////////////////////////////////////////////////
{
char LastC;
while (RxTailC != RxHeadC)
{
LastC = getc_QConsole();
switch (LastC)
{
case 0x08: // BS
if (CntCmdC)
CntCmdC--;
break;
case 0x0d: // <CR>
CCRC[CntCmdC] = 0; // terminate the string with a NULL
SrvCmd(CCRC); // go service the command
CntCmdC = 0; // initialise number of characters in the command buffer
printf("By your COMMAND>");
return;
break;
case 0x0a: // <LF>
break;
default :
CCRC[CntCmdC] = LastC; // put into the command construction register
if (CntCmdC < CCRSize)
CntCmdC++;
break;
}
}
} |
getc_QConsole fetches the next character from the receive ring buffer
Code: |
char getc_QConsole()
///////////////////////////////////////////////////////////////////////////
// getc_QConsole
//
// Routine to read (remove) a byte from the Console receive buffer
//
// On Entry:
// Rx_TailC points to next byte to be read from the logger receive buffer
//
// On Exit:
// Rx_TailC points to the next position in the buffer
///////////////////////////////////////////////////////////////////////////
{
Char RxChar;
While (RxTailC == RxHeadC)
;
RxChar = RxBaseC[RxTailC++];
RxTailC %= RxCQSize;
return(RxChar);
} |
SrvCmd processes the constructed command string... _________________ Regards, Andrew
http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!! |
|
|
|
|
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
|