From: dave j. <s.d...@gm...> - 2008-07-08 14:12:37
|
Hello, Does sdcc 2.8 implement scanf() for mcs51? I want to use scanf() or gets() and friends, would anyone tell me how to do or where I can get the implementation libs? Thanks. Regards, Dave. |
From: Karl H. <ka...@hi...> - 2008-07-08 14:31:52
|
dave jones wrote: > Hello, > > Does sdcc 2.8 implement scanf() for mcs51? I want to use scanf() or > gets() and friends, > would anyone tell me how to do or where I can get the implementation > libs? Thanks. Read from your UART RX buffer if your chip has one, into an array for example. Implementing your own ring buffer is easy. Then if you want to convert a number use atoi() Usually reading the UART RX buffer is in your UART interrupt handler. Then outside of the interrupt you can process your local buffer. You may be able to find sample code at somewhere perhaps start with http://sdcc.sourceforge.net/links.php -- karl |
From: dave j. <s.d...@gm...> - 2008-07-08 15:16:47
|
Karl Hiramoto wrote: > dave jones wrote: >> Hello, >> >> Does sdcc 2.8 implement scanf() for mcs51? I want to use scanf() or >> gets() and friends, >> would anyone tell me how to do or where I can get the implementation >> libs? Thanks. > > Read from your UART RX buffer if your chip has one, into an array for > example. Implementing your own ring buffer is easy. Then if you want > to convert a number use atoi() > > > Usually reading the UART RX buffer is in your UART interrupt > handler. Then outside of the interrupt you can process your local > buffer. > > You may be able to find sample code at somewhere perhaps start with > http://sdcc.sourceforge.net/links.php Thanks for the info. I implemented the getchar(), but I don't know how to do with scanf(), would you mind giving the code? Thank you. > -- > karl BR, Dave. |
From: Berwyn H. <be...@br...> - 2008-07-09 11:00:28
|
Hi Dave, Here's a cut-down scanf I wrote for the AVR (gcc). You'll have to see if it builds in SDCC because I haven't tried it. There's a bit of jiggery pokery going on with read_ram and read_rom because the format string comes from AVR ROM space and the scanned string is in RAM. Licence: Use at your own risk. Help is not guaranteed. // === Scanf === bool in_set(prog_char *set, char c, short size) { /* Searches max size chars at string set to find character c * set is NOT required to be NUL-terminated. */ while (size--) if (pgm_read_byte(set++) == c) return true; return false; } char read_ram(char *addr) { return *addr; } char read_rom(char *addr) { return pgm_read_byte(addr); } char hex2num(char hex) { if (hex>='A') { if (hex>='a') hex -= 'a'-'A'; // tolower hex -= 'A'-'9'-1; // todigit } return hex-'0'; // tohex } // atoi that terminates at maxlen and adjust input string to point to character that conversion stopped at) // Note: a maxlen of -1 equals a length of 65535 which is essentially infinite. short bounded_atoi(char fetch(char *), prog_char **s_p, short maxlen) { short number=0; bool sign=false; char c; prog_char *s = *s_p; if (fetch(s) == '-') { sign = true; s++; } while (maxlen-- and isdigit(c=fetch(s))) { number = (number<<3) + number + number; // *= 10 number += c-'0'; s++; } if (sign) number=-number; *s_p = s; return number; } // cut-down scanf // handles %% %s %[] %c %d %x (=%X) %n: // return no. conversions stored. Returns early if mismatch // Notes: // - length modifier may be supplied after '%' and it defaults to 65535 (or for %c, 1) // - %x requires length // - '*' modifier not allowed // - 'l' modifier not allowed // - %n does increment count returned (scanf docs are undecided on whether it should) // - no special whitespace handling, so a space matches just one space unsigned char vxsscanf(char *s, prog_char *fmt, va_list args) { char *sstore, *set, *s0=s; char c, count; short length; bool contains; unsigned short *number; count = 0; // how many conversions stored while (c=pgm_read_byte(fmt++), c) { if (c!='%') { if (*s++ != c) return count; // match s against c } else { if (isdigit(pgm_read_byte(fmt))) { length = bounded_atoi(read_rom, &fmt, -1); } else length = -1; c = pgm_read_byte(fmt++); switch (c) { case 'n': *va_arg(args, short *) = (short)(s-s0); count++; break; case '[': sstore = va_arg(args, char*); if (pgm_read_byte(fmt) == '^') { contains = false; fmt++; } else contains = true; set = fmt; while (pgm_read_byte(fmt) and pgm_read_byte(fmt++) != ']'); while (length-- and *s) { if (in_set(set, *s, fmt-set) == contains) *sstore++=*s++; else break; } *sstore = 0; count++; break; case 'c': // character if (length==-1) length=1; case 's': sstore = va_arg(args, char*); while (length-- and *s) *sstore++=*s++; if (c=='s') *sstore = 0; count++; break; case 'u': // unsigned short decimal number case 'd': // signed decimal number sstore = s; *va_arg(args, unsigned short *) = bounded_atoi(read_ram, &s, length); if (s==sstore) return count; // no number found count++; break; case 'x': case 'X': number = va_arg(args, unsigned short *); *number = 0; if (not isxdigit(*s)) return count; // no hex number found while (length-- and isxdigit(c=*s)) { s++; *number <<= 4; *number += hex2num(c); } count++; break; case '%': if (*s++ != '%') return count; // match s against '%' break; default: return count; // can't decode format string } } } return count; } |