View previous topic :: View next topic |
Author |
Message |
big_nige
Joined: 30 Nov 2009 Posts: 7
|
using fputc and kbhit with streams |
Posted: Wed Apr 28, 2010 12:19 am |
|
|
Hi all,
Using PCWH 4.107 with a 18LF2550.
I am trying to use a software uart on a couple of pins in conjunction with the main UART. I can't get the second uart to work however, the following code just hangs on the fgetc or kbhit (commented in this bit of code). I have isolated the circuit on my board and installed a loopback so the sent message appears on the receive pin. I have checked on the CRO and the message definitely gets to pin C1.
Code: |
#include <18F2550.h>
#include <stdlib.h>
#fuses INTRC_IO,CPUDIV1,NOWDT,NOPROTECT
#use delay(clock=8MHZ, RESTART_WDT)
#use rs232(xmit=PIN_C0, rcv=PIN_C1, baud=57600, stream=HILO)
#use rs232(xmit=PIN_C6, rcv=PIN_C7, baud=57600, stream=UART1, ERRORS)
void main(){
char msg[60];
delay_ms(1000);
while(1){
msg = "Marco";
fprintf(UART1, "I sent:%s\r\n", msg);
fprintf(HILO, msg);
//delay_ms(10);
//while(!kbhit(HILO));
msg[0] = fgetc(HILO);
fprintf(UART1, "After kbhit\r\n"); //code never gets to here
delay_ms(500);
}
}
|
As always, any assistance would be greatly appreciated.
Cheers,
Nigel |
|
![](templates/subSilver/images/spacer.gif) |
Wayne_
Joined: 10 Oct 2007 Posts: 681
|
|
Posted: Wed Apr 28, 2010 2:22 am |
|
|
Two problems I see
1 is the use of msg
You define an array
char msg[60];
You then use
msg = "Marco";
This is wrong, what this will do is make the pointer msg point to the string "Marco" which would normally be placed in ROM.
This presents 2 problems later on.
1. If it is in read only memory then
msg[0] = fgetc(HILO); will fail.
2. If it places the string in RAM then it will only allocate the 6 bytes for the string and if you try to write past that you will be corrupting memory.
In order to put the string "Marco" in the array msg you need to use
strcpy(msg, "Marco");
or
sprintf(msg, "Marco");
2 is the fact you are using a software UART and you are sending to yourself. Not sure you can do this! do a search on here. |
|
![](templates/subSilver/images/spacer.gif) |
big_nige
Joined: 30 Nov 2009 Posts: 7
|
|
Posted: Wed Apr 28, 2010 2:38 am |
|
|
Thanks for the reply Wayne,
1 - I dont think so. The code pasted is cut out of a larger piece of code. The msg array is used for variable length strings fed in from a GPRS module (SMS messages). I have been using this array elsewhere in code without any issues (I just manually check for CR/LF).
So it is more complex than it needs to be, but the possible overrun is not my issue here - the piece of code you pasted fails too.
Also the commented out while(!kbhit(HILO)); also hangs - in this second test case I am not even using the msg array.
2 - Don't know. It works just fine on the hardware UART and I have been testing RS232 comms on loopback many times before without problems. To address the possible lag in character detection on loopback, you will note there is a software delay commented out in this code. I have tried delays from 5us to 500ms without success.
Cheers,
Nigel |
|
![](templates/subSilver/images/spacer.gif) |
Wayne_
Joined: 10 Oct 2007 Posts: 681
|
|
Posted: Wed Apr 28, 2010 5:33 am |
|
|
1.
char msg[60];
msg = "Macro";
This is wrong code for C but it appears CCS have implimented functionality to allow you to use the = operator to copy a const string to an array at some point. I am pretty sure you couldn't do this in the past with CCS.
2. Hardware UART will work on loop back because the hardware is toggling the pin to send the byte leaving your code to do what ever it likes.
With software UART the software has to toggle the pin. It will most likely do this either via an interrupt or in a tight loop. If it is in a tight loop then your code would not be able to read the input line to see if it is a 1 or 0 unless you have an interrupt on change for the incomming pin, this could disrupt the routine sending the byte out and mess up the baud rate.
If you toggle the pin using an interrupt then your pic can still run code to read the pin.
Either way, you need to free up the incomming buffer by reading the char before you can recieve another char. If the CCS code does this, how many chars can it buffer ?
Just my thoughts on the matter. |
|
![](templates/subSilver/images/spacer.gif) |
big_nige
Joined: 30 Nov 2009 Posts: 7
|
|
Posted: Wed Apr 28, 2010 3:19 pm |
|
|
Aah - understand what you are getting at now. I agree - it is very un-c - but, if if works . Must admit that I didn't think you could do it either - the actual code reads an external EEPROM into the array in a loop. I took the shortcut once to test a routine and was as suprised as you that it worked. I haven't been using ccs for long, so just assumed that it was a convenient quirk to the compiler.
We may be getting to the nub of the problem with you comments on point 2. There is no IOC on port C on the 2550. Because it is not a UART port there also isnt a character buffer - so after sleeping on it I realised that neither the test loop or the original code is going to work.
No matter - the two RS232 devices in my design operate mutually exclusively - just have to slave them up on the hardware UART.
Thanks for your help Wayne - when I saw your response this morning the penny finally dropped.
Cheers,
Nigel |
|
![](templates/subSilver/images/spacer.gif) |
bkamen
Joined: 07 Jan 2004 Posts: 1611 Location: Central Illinois, USA
|
|
Posted: Thu Apr 29, 2010 10:47 am |
|
|
Wayne_ wrote: | 1.
char msg[60];
msg = "Macro";
This is wrong code for C but it appears CCS have implimented functionality to allow you to use the = operator to copy a const string to an array at some point. I am pretty sure you couldn't do this in the past with CCS.
|
That is correct. You could not.
Normal C in PIC-land as I've ever seen it has been to copy a string over using strcpy or strncpy.
CCS has added some things to make string handling a lot easier. People need to realize though that their want of an "easier way" also breaks the standard.
I'd have to look again in my K&R book to make sure.
-Ben _________________ Dazed and confused? I don't think so. Just "plain lost" will do. :D |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Apr 29, 2010 12:37 pm |
|
|
Apparently CCS is doing a C++ like construct.
This guy compares string handling in C and C++.
http://cs.smu.ca/~porter/csc/ref/c_cpp_strings.html
On the left he shows C, and on the right C++:
Code: |
Assigning to a C-string variable Assigning to a C++ string object
-------------------------------- -----------------------------
Can't do it, i.e., can't do this: string str;
char str[10]; str = "Hello";
str = "Hello!"; str = otherString;
|
|
|
![](templates/subSilver/images/spacer.gif) |
Wayne_
Joined: 10 Oct 2007 Posts: 681
|
|
Posted: Fri Apr 30, 2010 1:27 am |
|
|
The difference being between C and C++ is that in C a string is a char array which is null terminated, in C++ string is an object which has an overloaded operator = for copying other string objects or a string literal to the string object. |
|
![](templates/subSilver/images/spacer.gif) |
|