|
|
View previous topic :: View next topic |
Author |
Message |
Bill_Smith
Joined: 06 Feb 2004 Posts: 26 Location: Curitiba, Brazil
|
Can't Receive Data Using getc() |
Posted: Mon Feb 09, 2004 8:45 am |
|
|
Hi Folks, I just purchased the CCS PCWH compiler last week and while going through the sample programs, I ran into a problem using the getc() function. I have already read through a dozen or so of the messages on this forum pertaining to this subject, and tried the advice from several folks but without success.
I am using an MPLAB-ICD DEMO board from Microchip which I have added a few goodies (temp sensor, second RS-232 port, etc.). For debugging, I am using an MPLAB ICE 2000 with a 20Mhz PIC16F877 emulator pod inserted into the 40 pin socket on the DEMO board. I also have an HP logic analyzer monitoring the the signals entering and exiting the emulator pod. I am using MPLAB-ICD version 6.42 and have the CCS compiler integrated using their MPLAB tool. Serial testing was done using TeraTerm, Hyperterm, vbterm, and the CCS terminal tool.
I am using the following code to test the RS-232 port, and the CCS serial library functions:
Code: | #include <16F877.h>
#use delay(clock=20000000)
#fuses NOWDT,HS, PUT, NOPROTECT, NOBROWNOUT, NOLVP, NOCPD, NOWRT, NODEBUG
#use rs232(baud=9600,parity=N,xmit=PIN_C1,rcv=PIN_C0,bits=8,STREAM=HOSTPC)
void main(void)
{
char c;
printf("\r\nPress a key: ");
while(1){ //Let's do this forever
if(kbhit()){ //Is there a byte in the receive buffer?
c=getc(); //Get the byte
printf("\r\n You've Pressed: \%c",c);
printf("\r\nPress a new key: ");
}
}
} |
This code on my hardware produces a continuous stream of text, with or without any keys on the keyboard being pressed. In fact, if I just use a simple program with only kbhit(), it always returns TRUE even though the RX signal entering the PIC16F877 is HIGH. Testing the getc() function in a simple program by itself results in no characters being received even though characters are arriving correctly at the pin of the device. Strangely, all the RS-232 send functions like putc(), printf(), etc. work fine.
Some of you might have noticed that I am using PORTC pins 0 and 1 in the program above for the RXD and TXD signals. Originally they were connected to pins 6 and 7, however after reading several of the messages on this forum, I thought I would try elliminating the hardware UART in the 16F877 as a complication. It didn't matter, the results were the same.
I am a little stumped here because I have been able to get the harware to work properly with C programs written with both the HI-Tech and FED C compilers. I was really impresed with the CCS compiler up to this point, has anyone else ran into this problem?
Thanks for any help. |
|
|
dbotkin
Joined: 08 Sep 2003 Posts: 197 Location: Omaha NE USA
|
|
Posted: Mon Feb 09, 2004 11:54 am |
|
|
So you got the same result using the hardware UART? I'm using very similar code in a program I'm working on right now (16F628, hardware UART) and it works fine:
while(1) {
if(kbhit()) {
get_string(buffer,5);
printf("\r\ntime is %lu): ", id_time);
while(!kbhit());
}
}
This is significantly abbreviated, but you get the idea. I did have some trouble trying to use the soft UART with a 12F675, but moved to the 'F628 before digging in too deep because I needed more memory and I/O anyway. If I were looking at it now, I'd start by making sure the TRIS bits are set up right. Also, what are you using for RS232 interface hardware?
Dale |
|
|
Ttelmah Guest
|
Re: Can't Receive Data Using getc() |
Posted: Mon Feb 09, 2004 11:55 am |
|
|
Bill_Smith wrote: | Hi Folks, I just purchased the CCS PCWH compiler last week and while going through the sample programs, I ran into a problem using the getc() function. I have already read through a dozen or so of the messages on this forum pertaining to this subject, and tried the advice from several folks but without success.
I am using an MPLAB-ICD DEMO board from Microchip which I have added a few goodies (temp sensor, second RS-232 port, etc.). For debugging, I am using an MPLAB ICE 2000 with a 20Mhz PIC16F877 emulator pod inserted into the 40 pin socket on the DEMO board. I also have an HP logic analyzer monitoring the the signals entering and exiting the emulator pod. I am using MPLAB-ICD version 6.42 and have the CCS compiler integrated using their MPLAB tool. Serial testing was done using TeraTerm, Hyperterm, vbterm, and the CCS terminal tool.
I am using the following code to test the RS-232 port, and the CCS serial library functions:
Code: | #include <16F877.h>
#use delay(clock=20000000)
#fuses NOWDT,HS, PUT, NOPROTECT, NOBROWNOUT, NOLVP, NOCPD, NOWRT, NODEBUG
#use rs232(baud=9600,parity=N,xmit=PIN_C1,rcv=PIN_C0,bits=8,STREAM=HOSTPC)
void main(void)
{
char c;
printf("\r\nPress a key: ");
while(1){ //Let's do this forever
if(kbhit()){ //Is there a byte in the receive buffer?
c=getc(); //Get the byte
printf("\r\n You've Pressed: \%c",c);
printf("\r\nPress a new key: ");
}
}
} |
This code on my hardware produces a continuous stream of text, with or without any keys on the keyboard being pressed. In fact, if I just use a simple program with only kbhit(), it always returns TRUE even though the RX signal entering the PIC16F877 is HIGH. Testing the getc() function in a simple program by itself results in no characters being received even though characters are arriving correctly at the pin of the device. Strangely, all the RS-232 send functions like putc(), printf(), etc. work fine.
Some of you might have noticed that I am using PORTC pins 0 and 1 in the program above for the RXD and TXD signals. Originally they were connected to pins 6 and 7, however after reading several of the messages on this forum, I thought I would try elliminating the hardware UART in the 16F877 as a complication. It didn't matter, the results were the same.
I am a little stumped here because I have been able to get the harware to work properly with C programs written with both the HI-Tech and FED C compilers. I was really impresed with the CCS compiler up to this point, has anyone else ran into this problem?
Thanks for any help. |
The 'comment' you make inline 'check if character is in the receive buffer', is _wrong_, when dealing with the soft UART. There is no 'receive buffer' for this, and so you can just go straight to getc. KBHIT, technically, should return 'true', as soon as the start bit is detected. Technically 'kbhit', on the soft UART, is exactly equivalent, to:
if (input(PIN_C0)==0)
Now your 'continuous stream of text', might well cause problems in this configuration, since while sending the data (from the printf), reception is not available. Then the kbhit, could easily 'see' a tail bit from a transmitted character as a 'start' bit, and effectively receive garbage. However this shouldn't cause the problems you are seeing.
One comment (made in the other thread), is to get rid of the stream parameter, if you are not using it. Though the functions are meant to default to the last #use RS232 parameters, I have seen problems with this when streams are enabled, and not used. Hence either use the 'fgetc' form, and specify the stream, or stop using the streams.
Double check the signal levels. The C0 input, is a Schmidt trigger input, and as such, won't see a signal as 'high', till it gets to over 4v. This can cause problems with a lot of normal TTL outputs, unless a pull-up resistor is added. A TTL logic analyser pod, will see the signal as high, when it is over 2.4v, and this can lead to a lot of 'head scratching'....
Best Wishes |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Feb 09, 2004 11:59 am |
|
|
It works perfectly for me. I copied your program verbatim into
MPLAB, and compiled it with PCM vs. 3.184. I jumpered my demo
board to use Pins C0 and C1 for RS232. Here's the output:
Press a key:
You've Pressed: A
Press a new key:
You've Pressed: B
Press a new key:
You've Pressed: C
Press a new key:
You've Pressed: D
Press a new key:
-----------------------------------------
Let's look at the actual code. You can see that the kbhit()
function just tests Pin C0. A start bit is a logic low level.
So if it sees a start bit, the code "skips" to address B6, where
it then executes the getc() function. If no start bit is seen
(ie, Pin C0 is high), then it goes to address D2, which just
jumps right back up to the start of the loop at B4.
So for your printf statements to continually execute, Pin C0
must be seeing a logic low level. But you've said it's always high.
So. "If you find a contradiction, check your premises". (Ayn Rand)
You're using an ICE. That's a substantial level of indirection
beyond what I'm using. I use the 16F877 bootloader from
http://www.microchipc.com, and run my code directly on the PIC.
What could cause this problem ?
1. The ICE is not executing the code correctly.
2. Some other aspect of the ICE is causing the problem - such as
different clocks being used by the ICE vs. the PIC. For example,
when you're using the ICE, it may not really be running the PIC
at 20 MHz ? I vaguely remember some problem like this in the
past, that someone had on this board.
3. The Pin C0 is not really at a high level. It's low. Possibly because
the wire intended for that pin, is accidently connected to another pin.
4. Perhaps you're not using a MAX232 chip on the RS232 signals,
which would cause the idle state for Pin C0 to be at a low level.
Code: | 0000 00452 .................... while(1){ //Let's do this forever
0000 00453 .................... if(kbhit()){ //Is there a byte in the receive buffer??
00B4 1807 00454 BTFSC 07.0
00B5 28D2 00455 GOTO 0D2
0000 00456 .................... c=getc(); //Get the byte
00B6 286F 00457 GOTO 06F
00B7 0878 00458 MOVF 78,W
00B8 00A1 00459 MOVWF 21
// printf() code snipped for brevity.
0000 00487 .................... }
0000 00488 .................... }
00D2 28B4 00489 GOTO 0B4
0000 00490 .................... }
0 |
|
|
|
Bill_Smith
Joined: 06 Feb 2004 Posts: 26 Location: Curitiba, Brazil
|
PIC16F877 and getc() Not Working (Problem Found!) |
Posted: Mon Feb 09, 2004 5:35 pm |
|
|
Thank you very much to all who responded to my message. All of you provided some very good information which I will save for future reference.
As it turns out, about an hour after posting my original cry for help, I got into an email exchange with someone from CCS Tech Support. We eventually got onto the subject of what were the logic levels of the RXD/TXD signals at both the PIC and PC. When I measured them with a DVM, Wow!, only 2.7V at the target. In fact, that was also the VCC supply going into the MAX232.
A closer inspection of the target setup environment revealed that I had setup the ICE 2000 to supply power for the target. The MAX232 needs at least 4.5V for the charge pumps to produce RS-232 signal levels, so the PC was not recieving a proper RS-232 signal. Applying +5V to the target, and reconfiguring the ICE to allow external target power solved my problem.
Amazing how well things work with the proper power supply voltages. :-)
I hope that my embarassment has served to help others.
Regards to all,
Bill |
|
|
|
|
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
|