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

PIC getting stuck

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



Joined: 07 Oct 2009
Posts: 11

View user's profile Send private message

PIC getting stuck
PostPosted: Wed Oct 07, 2009 1:17 am     Reply with quote

Hi everyone
I'm writing a program for PIC18F4431.
I'm using printf and getch functions to communicate with a PC via RS232. Baudrate and other settings are correctly configured. The problem is when I send few bytes of data from the PC in a row, the pic is getting stuck. I always have to restart it.
My code is something similar to this.
Code:

func x{
int8 x,y;
x= getch();
y= getch();
printf("two bytes received");
}

Why is it getting stuck? Thanks in advance.
bkamen



Joined: 07 Jan 2004
Posts: 1615
Location: Central Illinois, USA

View user's profile Send private message

PostPosted: Wed Oct 07, 2009 10:19 am     Reply with quote

#use RS232 should include the "ERRORS" parm.

Read up on it... it clears overflows in the UART... which can cause things to stick like you describe (if I remember right).

On another note, in your code, you should have a check to see if there is even any data in the buffer... either

Code:
while (! kbhit() );


or

Code:
if ( kbhit() ) {
 do some stuff;
}


Both had their obvious uses... choose which best suits your app.

For code that needs to run while waiting for data, I like to use ISR's and better defined packets...


-Ben
_________________
Dazed and confused? I don't think so. Just "plain lost" will do. :D
cyclo.sl



Joined: 07 Oct 2009
Posts: 11

View user's profile Send private message

PostPosted: Wed Oct 07, 2009 11:41 am     Reply with quote

Thanks Ben..
I'll check and add that parm.

I used if (kbhit()) but it gave the same result. Ya I guess I have to use interrupts here.
bkamen



Joined: 07 Jan 2004
Posts: 1615
Location: Central Illinois, USA

View user's profile Send private message

PostPosted: Wed Oct 07, 2009 12:37 pm     Reply with quote

I spaced,

In your case,

You would want:

Code:
func x{
   int8 x,y;
   if ( kbhit() ) {
      x= getch();
   }
   if ( kbhit() ) {
      y= getch();
   }

   printf("two bytes received");
}



I will say an ISR with something that frames the data coming through is very nice albeit busier.

-Ben
_________________
Dazed and confused? I don't think so. Just "plain lost" will do. :D
cyclo.sl



Joined: 07 Oct 2009
Posts: 11

View user's profile Send private message

PostPosted: Wed Oct 07, 2009 10:55 pm     Reply with quote

Thanks again Ben.. Smile
Well the thing is, in my case I want my code to stay in the blocked state till I receive 2bytes of data. Means the calculation needs two byte of data to proceed, so I have to wait till the user input 2 values from the sw in pc. But if I use kbhit(), my code wont stay in the blocked state. Then I will have to use a blocking loop with kbhit(). So using getch() alone is good for my case, isn't it?
bkamen



Joined: 07 Jan 2004
Posts: 1615
Location: Central Illinois, USA

View user's profile Send private message

PostPosted: Wed Oct 07, 2009 11:19 pm     Reply with quote

Well you can't "wait until 16 bits" because the UART and RS232 in general works on 8bits at a time.

So the initial receive signals a byte... your (or my) code goes and grabs it..

We have 1.

What now?

If we do another getch(), what are we getting? another byte? How? The CPU is running at MIPS while the UART is transferring at some fraction of that speed even at 115,200b/s...

so that second "ungated" getch() is grabbing invalid dat we don't want anyway. We have to wait for the UART to signal it has another byte that we can get before continuing. Thus, the second if (kbhit()).

To sum it up, getch() takes a received char out of the RX buffer. You can't getch() something that doesn't exist yet and the only way you can know it's there is to check the reciever status yourself through kbhit() or by checking the receiver status bit which on most PICs is the RCxIF interrupt flag. (the bit always works, but does/doesn't generate an interrupt based on the enable bit and the global interrupt bit).

Let me know if that helps,

-Ben
_________________
Dazed and confused? I don't think so. Just "plain lost" will do. :D
cyclo.sl



Joined: 07 Oct 2009
Posts: 11

View user's profile Send private message

PostPosted: Thu Oct 08, 2009 1:33 am     Reply with quote

You are exactly addressing my problem. Smile
This is a part of the exact code I used.

Code:

struct bytes{
   int8 low;
   int8 high;
};

union duty_val{     
   int16 value;
   struct bytes parts;
};

void main(){
 union duty_val duty1,duty2,duty3,duty4;
 while(true){
       printf("waiting for duty values..");   
       duty1.parts.high = getch();
       duty1.parts.low = getch();
       printf("duty1 : %Lu  ",duty1.value);
     
       duty2.parts.high = getch();
       duty2.parts.low = getch();
       printf("duty2 : %Lu  ",duty2.value);
       
       
       duty3.parts.high = getch();
       duty3.parts.low = getch();
       printf("duty3 : %Lu  ",duty3.value);
       
       duty4.parts.high = getch();
       duty4.parts.low = getch();
       printf("duty4 : %Lu  ",duty4.value);
 
      //calculations
 }
}


I wrote a C# application to send above duty values. Initially I coded it to transfer 8 bytes of data when I press a button. That did not work as the pic started to get stuck after I receive "duty1:xx". (You already gave me an answer for that problem) So what I did was, I inserted a delay in between 2 bytes wondering why this happens even the both ends work at the same baud rate. Got the problem solved with that. Yet when I keep pressing the button, the same problem happens.

These are the modifications that I'm going to make.
1. Add ERRORS param to #use rs232

2. Modify the code as below
Code:

printf("waiting for duty values..");
   while(!kbhit());
       duty1.parts.high = getch();
   while(!kbhit());
       duty1.parts.low = getch();
       printf("duty1 : %Lu  ",duty1.value);


Hope I've understood you correctly. Will keep you updated.
Thanks
bkamen



Joined: 07 Jan 2004
Posts: 1615
Location: Central Illinois, USA

View user's profile Send private message

PostPosted: Thu Oct 08, 2009 12:12 pm     Reply with quote

Yep -- I think you're on the right track now.

Holler if you need it. :D

-Ben
_________________
Dazed and confused? I don't think so. Just "plain lost" will do. :D
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