We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
Hi everybody. I've a question. I must modify the standard getkey function: #include <reg51.h> char _getkey () { char c; while (!RI); c = SBUF; RI = 0; return (c); } to know if it receives something by RS232 in 30 sec. If in this time i don't receive anything i must return an error. My problem is how to know if 30 seconds are passed. Thanks everybody.
I've make a version like this. But I haven't test it. #include <reg51.h> char _getkey () { char c; unsigned long i; while ((!RI) || (i<100000)) {i++;} if (RI) { c = SBUF; RI = 0; return (c); } else {return("\3");} } Thanks
I've make a version like this You're on the right track. You need a loop that waits either for RI, or for time to expire. Incrementing a variable is a dubious way to measure a precise interval, though. Your 8051 variant has two, probably three, and maybe more hardware timers that can give you a more precise result. You'll need to read your data sheet to understand exactly how to program the timers, and you'll need to talk with your chief or any other programmers to know if the hardware timers are already being used for some purpose in your application. This statement return("\3"); is almost certainly wrong. getkey() returns a character. This statement returns a pointer to a string which happens to be an ASCII 3 followed by a null (as with all C strings). I imagine you wanted to return an ASCII 3 to signal a timeout, which you could do with return '\3' (note the single quotes for a char literal instead of a string) or just simply return 3;. You probably want to define this special value as a constant so you can easily share it with clients of this routine. If you use a return type of char, you'll need to pick a special character to signal your timeout. This means that particular character can never be received from getkey(). This may not be a problem for a non-printable value (say 255) if you're just transferring text, but if you send binary data you'll need another solution. Consider the getchar() in the standard library, which returns an int, so that negative values can be returned for errors while still preserving the full range of values for the character on success. Here's some code snippets that give you an idea of how to initialize timer 0 on one particular variant. You'll have to check your own design to see how to calculate the tick rate for your timers and how to initialize your timer. (This part, for example, has a couple of options on the frequency of the input clock which your part may or may not have.)
#define MsecToTicks(msec) (65536 - (((CPU_CLOCK / 1000) * (msec)) / 12)) void InitPolledTimer (void) { TR0 = 0; // stop timer 0 TMOD = (TMOD & 0xf0) | 0x1; // timer 0 mode 1: 16 bit ctr CKCON &= ~T0M; // divide clock by 12 (instead of 4) TF0 = 0; } void StartPolledTimer (U16 ticks) { TR0 = 0; TL0 = ticks; TH0 = ticks >> 8; TF0 = 0; TR0 = 1; // start timer } #define StopPolledTimer() TR0 = 0; #define PolledTimerExpired() TF0 #define GetkeyTimeout 3 char TimedGetkey (U16 msec) { char c = GetkeyTimeout; // default to timeout StartPolledTimer(MsecToTicks(msec)); while (!PolledTimerExpired()) { if (RI) { c = SBUF; RI = 0; break; // we're done } } return c; }