CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Problem to get strings with getc

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
id31



Joined: 19 Dec 2014
Posts: 16

View user's profile Send private message

Problem to get strings with getc
PostPosted: Thu Feb 02, 2017 5:42 am     Reply with quote

Hi all,
I'm using PIC18f8722.

I try to get a string in UART. The Uart pins is not the hw pins (PINS D2, D7).
My method is to getc(STREAM) every char to an array of chars. the program call getc only after kbhit(STREAM).
when I use the same methods for numbers (hex) it works well.
when I use fprintf() the data is going well to my PC.

Example:
Code:

if (kbhit(stream_name)
  x[i]=getc(stream_name);

BUT when I'm using to get an array of chars i got garbage..
1. when i send long string after couple of garbage chars i got the correct data.
2. when i use getc() without kbhit() it works well.

Do you have an idea what is wrong and how to do it right?
temtronic



Joined: 01 Jul 2010
Posts: 9245
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Thu Feb 02, 2017 5:57 am     Reply with quote

EVERY time you use the hardware UART you MUST add 'errors' to the uses rs232(...options...), EVERY time.
Since you didn't post your code, I will assume 'errors' is not in the list.

It is required into order for the compiler to add a bit of code to keep the UART from 'locking up' after 2-3 characters are received.

Also you should look at the ex_sisr.c example program, as ANY serial input should be done in an ISR ( Interrupt Service Routine). This allows the pIC to do a LOT more than just wait for 'something' to come in.

Jay
id31



Joined: 19 Dec 2014
Posts: 16

View user's profile Send private message

PostPosted: Thu Feb 02, 2017 6:01 am     Reply with quote

Hi, thank you for the quick reply.
As i wrote before - the uart is not HW so i use kbhit() instead of int_rda.
when i configured the uart i added errors.
temtronic



Joined: 01 Jul 2010
Posts: 9245
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Thu Feb 02, 2017 6:27 am     Reply with quote

oops... gues I need TRIfocals.....sigh,getting old ...
OK have to ask why can't you use the HW UART?

You should post your serial ISR so we can see. All ISRs must be small and fast, NO fancy math, no prints, no delays.....

Jay
Ttelmah



Joined: 11 Mar 2010
Posts: 19546

View user's profile Send private message

PostPosted: Thu Feb 02, 2017 6:39 am     Reply with quote

Problem is time.

Understand that 'kbhit' will only return true, once the character has already started. So using kbhit, you will be late actually starting to receive the character. Use the option 'SAMPLE_EARLY' in your #use rs232 setup. This tells the getc code to not wait half a bit time after being called.

Also understand that using software serial, you can only send or receive at any time. If data arrives while you are sending, it will be lost.
id31



Joined: 19 Dec 2014
Posts: 16

View user's profile Send private message

PostPosted: Thu Feb 02, 2017 6:52 am     Reply with quote

The other UARTs is for other communication serials (I have 3 "ports").
I tried "SAMPLE EARLY" but it didn't help.
still I got the start of the string wrong and after correct.

the method is:

char a[100]={0};
run_timer4(); //I have a function that when interrupt it set timeout=TRUE
for (int i=0;i<100;i++)
{
while ((!kbhit(UART_STREAM) && (!timout))
{
a[i]=getc(UART_STREAM);
}
}
jeremiah



Joined: 20 Jul 2010
Posts: 1355

View user's profile Send private message

PostPosted: Thu Feb 02, 2017 7:05 am     Reply with quote

You need fgetc() for streams.

Also, understand that your timing must be very tight and you shouldn't use interrupts while receiving data. Interrupts can corrupt the data stream when doing SW uart. There is an option to DISABLE_INTS in the #use rs232() directive that is specifically for SW uarts.
id31



Joined: 19 Dec 2014
Posts: 16

View user's profile Send private message

PostPosted: Thu Feb 02, 2017 7:44 am     Reply with quote

I used fgetc() - didn't change the results..
I enable "DISABLE_INTS" - still the same..

:(
Ttelmah



Joined: 11 Mar 2010
Posts: 19546

View user's profile Send private message

PostPosted: Thu Feb 02, 2017 7:50 am     Reply with quote

Your new logic is testing the wrong way round. You are calling the getc, when kbhit is not true:
Code:

   char a[100]={0};
   run_timer4(); //I have a function that when interrupt it set timeout=TRUE
   for (int i=0;i<100;i++)
   {
      while ((!kbhit(UART_STREAM) && (!timout))
         ; //wait for either a timeout or a character
      if (timout) //
         break; //exit if a timeout
      a[i]=getc(UART_STREAM); //otherwise get character
   }
id31



Joined: 19 Dec 2014
Posts: 16

View user's profile Send private message

PostPosted: Thu Feb 02, 2017 8:27 am     Reply with quote

OK!
it solved.

first of all - thank you for the quick replies!
YOU WERE RIGHT ALL THE TIME - the problem is time.

it was my fault not to paste the exact code..
the exact code is

char a[100];
if (kbhit(UART_STREAM))
{
for (int i=0;i<100;i++)
{
a[i]=0;
}

run_timer4(); //I have a function that when interrupt it set timeout=TRUE
for (int i=0;i<100;i++)
{
while ((!kbhit(UART_STREAM) && (!timout))
{
a[i]=getc(UART_STREAM);
}
}
}
}

the bolded text (init the array) took too much time. so I init at when declared (as i wrote i did.. ) and it solved!

so - thank you and im sorry, i learned for the next time.
I have 2 more questions please:
1. I have 2MHz crystal - so why the init of the array took so much time?
2. Why did you advise me to use fgetc and not getc?
jeremiah



Joined: 20 Jul 2010
Posts: 1355

View user's profile Send private message

PostPosted: Thu Feb 02, 2017 11:48 am     Reply with quote

id31 wrote:

I have 2 more questions please:
1. I have 2MHz crystal - so why the init of the array took so much time?
2. Why did you advise me to use fgetc and not getc?


#2 first: The compiler officially supports fgetc for streams, not getc. Using unsupported things (even if they work) is a bad idea.

#1
2MHZ crystal = 500kHz instruction clock => 2us instruction time. You are looping through 100 elements. Assuming around 10 instructions per assignment/loop test/loop increment:

2us * 100 elements * 10 instructions = 2ms

If you are operating anything 9600 baud or faster, then you can miss edge transitions in a software UART. Reception with a software UART is very tricky to get right in complicated designs. I would offer that you reconsider your design and see if one of the other UART connections is more suited to SW uart and make this one HW if possible. If a connection only transmits, for example, it is a better candidate for SW uart. Or if you know the exact time a response comes and the exact size of the data, then it is a better candidate. Anything that lets you avoid taking up time doing other things. Also consider bumping up the speed of your clock.
Ttelmah



Joined: 11 Mar 2010
Posts: 19546

View user's profile Send private message

PostPosted: Thu Feb 02, 2017 12:51 pm     Reply with quote

It's also worth asking 'why'.
Just clear the array before you start waiting for the character.
Understand that with the software UART, when you see 'kbhit' you are already inside the character being received, and you have less than half a bit time to actually start reading the data.
There is actually no point in clearing the array anyway. Just write a null when you exit (last character or timeout). The rest of the array is being filled with the characters as they are received.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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