|
|
View previous topic :: View next topic |
Author |
Message |
deltatech
Joined: 22 Apr 2006 Posts: 87
|
Not detecting ASCII Charecters ! Why ? |
Posted: Fri Jun 23, 2006 12:38 pm |
|
|
I should be getting 15 ASCII Charecters In the buffer . But on the Monitor
All I get is RUNNING...
Can any one tell me whats wron here ? Many Thanks
ASCII Charecters comming into PIN_B2
300 Baud ,7 Data Bits, Even Parity,
Code: | #include <16F877A.h> // register definition file for
#fuses HS,NOWDT // a Microchip PIC16F877
#use delay(clock=20000000)
#use rs232(baud=9600,parity=E,xmit=PIN_C6,rcv=PIN_C7,stream=HOSTPC,bits=7)
#use rs232(baud=300,parity=e,rcv=PIN_B2,bits=7, FORCE_SW, stream=MSF)
#define RX_BUFFER_SIZE 15
char Rx_Buffer[RX_BUFFER_SIZE+1]; // character array (buffer)
char RX_Wr_Index = 0; //index of next char to be put into the buffer
char RX_Rd_Index = 0; //index of next char to be fetched from the buffer
char RX_Counter = 0; //a total count of characters in the buffer
int1 RX_Buffer_Overflow = 0; // This flag is set on UART Receiver
// buffer overflow
// UART Transmit buffer
#define TX_BUFFER_SIZE 15
char TX_Buffer [TX_BUFFER_SIZE+1]; // character array (buffer)
char TX_Rd_Index = 0; //index of next char to be put into the buffer
char TX_Wr_Index = 0; //index of next char to be fetched from the buffer
char TX_Counter = 0; //a total count of characters in the buffer
int1 fPrimedIt = 0; // this flag is used to start the transmit
// interrupts, when the buffer is no longer empty
// USART Receiver interrupt service routine
#int_rda // preprocessor directive identifying the
// following routine as an interrupt routine
void serial_rx_isr()
{
//k=getc();
Rx_Buffer[RX_Wr_Index] = fgetc(MSF); // put received char in buffer
if(++RX_Wr_Index > RX_BUFFER_SIZE) // wrap the pointer
RX_Wr_Index = 0;
if(++RX_Counter > RX_BUFFER_SIZE) // keep a character count
{ // overflow check..
RX_Counter = RX_BUFFER_SIZE; // if too many chars came
RX_Buffer_Overflow = 1; // in before they could be used
} // that could cause an error!!
}
// Get a character from the UART Receiver buffer
char bgetc(void)
{
char c;
while(RX_Counter == 0) // wait for a character...
;
c = Rx_Buffer[RX_Rd_Index]; // get one from the buffer..
if(++RX_Rd_Index > RX_BUFFER_SIZE) // wrap the pointer
RX_Rd_Index = 0;
if(RX_Counter)
RX_Counter--; // keep a count (buffer size)
return c;
}
// USART Transmitter interrupt service routine
#int_tbe
void serial_tx_isr()
{
if(TX_Counter != 0)
{
putc(TX_Buffer[TX_Rd_Index]);
// otherwise, send char out port
// test and wrap the pointer
if(++TX_Rd_Index > TX_BUFFER_SIZE)
TX_Rd_Index = 0;
TX_Counter--; // keep track of the counter
if (TX_Counter == 0)
disable_interrupts(int_tbe);
}
}
// write a character to the serial transmit buffer
void bputc(char c)
{
char restart = 0;
while(TX_Counter > (TX_BUFFER_SIZE-1))
; // WAIT!! Buffer is getting full!!
if(TX_Counter == 0) // if buffer empty, setup for interrupt
restart = 1;
TX_Buffer[TX_Wr_Index++]=c; // jam the char in the buffer..
if(TX_Wr_Index > TX_BUFFER_SIZE) // wrap the pointer
TX_Wr_Index = 0;
// keep track of buffered chars
TX_Counter++;
// do we have to "Prime the pump"?
if(restart == 1)
enable_interrupts(int_tbe);
}
void main(void)
{
unsigned char k;
enable_interrupts(global);
enable_interrupts(int_rda);
bputc('b');
printf(bputc,"\r\n\Running...\r\n");
while(1)
{
if(RX_Counter > 5) // are there any received characters??
{
while (RX_Counter > 0)
{
k = bgetc(); // get the character
bputc(k); // and echo it back
}
}
// since there is no waiting on getchar or putchar..
// other things can be done!!
}
}
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Jun 23, 2006 12:43 pm |
|
|
#int_rda only works with the hardware UART, on pins C6 and C7.
You're trying to use it with a soft UART on pin B2.
Also, where's your NOLVP fuse ? |
|
|
deltatech
Joined: 22 Apr 2006 Posts: 87
|
|
Posted: Fri Jun 23, 2006 12:54 pm |
|
|
I have changed it as below still nothing !
Code: | #use rs232(baud=300,parity=E,rcv=PIN_C7,stream=MSF,bits=7)
#use rs232(baud=9600,parity=E,xmit=PIN_C6,rcv=PIN_B0,stream=HOSTPC,bits=7) |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Jun 23, 2006 1:09 pm |
|
|
You can't split the hardware UART pins. It's not allowed. Your revised
code will generate two soft UARTs.
To generate code for a hardware UART, pins C6 and C7 must both be in
the same #use rs232() statement. |
|
|
rwyoung
Joined: 12 Nov 2003 Posts: 563 Location: Lawrence, KS USA
|
|
Posted: Fri Jun 23, 2006 1:10 pm |
|
|
deltatech wrote: | I have changed it as below still nothing !
Code: | #use rs232(baud=300,parity=E,rcv=PIN_C7,stream=MSF,bits=7)
#use rs232(baud=9600,parity=E,xmit=PIN_C6,rcv=PIN_B0,stream=HOSTPC,bits=7) |
|
Look at your LST file to confirm that your code is using the hardware UART. Since you have defined two streams, I'm not sure what it will do.
Blink a LED just toggle a port pin and watch with a scope as you enter and exit the RDA ISR. That will confirm is you are even getting into your ISR.
There are functions for changing the bit rate so you might be able to create a single stream and alter the baud rate as you enter and then exit the transmit interrupt.
Alternatively, if you must transmit at a different rate than receive and you can tolerate NOT having the transmit stream use the TBE interrupt, just move the transmit stream off of the hardware uart pins and let the compiler create a software uart for transmit. _________________ Rob Young
The Screw-Up Fairy may just visit you but he has crashed on my couch for the last month! |
|
|
deltatech
Joined: 22 Apr 2006 Posts: 87
|
|
Posted: Fri Jun 23, 2006 1:31 pm |
|
|
This is what i have in the list file I am not sure if this is waht you meant
with the two streams What i am trying to do is intput one data stream and echo on the RS232 I/O montor what was received just to confirm correct reception .
#use rs232(baud=300,parity=E,rcv=PIN_C7,stream=MSF,bits=7)
#use rs232(baud=9600,parity=E,xmit=PIN_B2,rcv=PIN_B0,stream=HOSTPC,bits=7)
Code: | . .................... #include <16F877A.h> // register definition file for
.................... //////// Standard Header file for the PIC16F877A device ////////////////
.................... #device PIC16F877A
.................... #list
....................
.................... #fuses HS,NOWDT // a Microchip PIC16F877
.................... #use delay(clock=20000000)
....................
.................... #use rs232(baud=300,parity=E,rcv=PIN_C7,stream=MSF,bits=7) |
|
|
|
Humberto
Joined: 08 Sep 2003 Posts: 1215 Location: Buenos Aires, La Reina del Plata
|
|
Posted: Fri Jun 23, 2006 1:50 pm |
|
|
Quote: |
Not detecting ASCII Charecters ! Why ?
|
You are in the point where to find out what is wrong it is not easy, it is a common and recurrent mistake. Serial communication with microcontrollers it is not a plug & play stuff (unless you have learned some skills).
You should start running a simplest and fool proof code to be sure that the serial comm configurations and the involved hardware are all OK, in the PIC side and PC side.
Once you get running successfully such simple code, you can start debugging more complex code like the one you posted.
Humberto |
|
|
rwyoung
Joined: 12 Nov 2003 Posts: 563 Location: Lawrence, KS USA
|
|
Posted: Fri Jun 23, 2006 2:38 pm |
|
|
Deltatech -
The LST file shows all the assembly code generated. It is important that you can at least READ PIC assembly code. If you can't then I suggest you open up that section of the data sheet and be prepared for some slogging.
Everywhere you make write to the stream or read from the stream, examine the LST file. You are looking for writes or reads associated with the hardware UART addresses.
I get the feeling you are "learning" as you go. While C is a very powerful tool for writing embedded software it is no substitute for being able to understand the assembly listing. CCS C (and most others I've used) are notorious for doing odd things behind the curtain and you will never know there is a mistake until you examine the actual assembly code. To steal a line from Roger Waters, "Give a man enough rope and he'll f**k it up". C is like that.
Humberto is right, you should start a little bit smaller. Don't use the interrupts, just getc and putc. If you have RS232 level translators on your circuit, just talk to your PC. Hyperterminal, for all its failings, is generally a pretty good program. SIOW that comes with PCHW is pretty good too. As is Bray++.
Good luck. _________________ Rob Young
The Screw-Up Fairy may just visit you but he has crashed on my couch for the last month!
Last edited by rwyoung on Fri Jun 23, 2006 4:05 pm; edited 2 times in total |
|
|
Ttelmah Guest
|
|
Posted: Fri Jun 23, 2006 2:50 pm |
|
|
Ignoring the _very good_ advice to start simpler, I'll still point out that you will _only_ get the hardware UART operating, if you define both the transmit, and receive pins for the hardware. You don't have to use them (the code is not generated unless you do), but unless the hardware is selected, the compiler will assume you want to use the software UART, and the interrupt will never work.
Define both C6, and C7, in the #use statement.
Best Wishes |
|
|
|
|
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
|