📄 rprintf.c
字号:
#include <avr/pgmspace.h>
//#include <string-avr.h>
//#include <stdlib.h>
#include <stdarg.h>
#include "global.h"
#include "rprintf.h"
#ifndef TRUE
#define TRUE -1
#define FALSE 0
#endif
#define INF 32766 // maximum field size to print
#define READMEMBYTE(a,char_ptr) ((a)?(pgm_read_byte(char_ptr)):(*char_ptr))
#ifdef RPRINTF_COMPLEX
static unsigned char buf[128];
#endif
static char __attribute__ ((progmem)) HexChars[] = "0123456789ABCDEF";
static void (*rputchar)(unsigned char c);
void rprintfInit(void (*putchar_func)(unsigned char c))
{
rputchar = putchar_func;
}
inline void rprintfChar(unsigned char c)
{
rputchar(c);
}
void rprintfStr(char str[])
{
if (!str) return;
while (*str)
rprintfChar(*str++);
}
void rprintfStrLen(char str[], unsigned int start, unsigned int len)
{
register int i=0;
if (!str) return;
while((i++<start) && (*str++));
for(i=0; i<len; i++)
{
if(*str)
rprintfChar(*str++);
else
rprintfChar(' ');
}
}
void rprintfProgStr(const prog_char str[])
{
register char c;
if (!str) return;
while((c = pgm_read_byte(str++)))
rprintfChar(c);
}
void rprintfCRLF(void)
{
rprintfChar('\r');
rprintfChar('\n');
}
void rprintfu04(unsigned char data)
{
rprintfChar(pgm_read_byte( HexChars+(data&0x0f) ));
}
void rprintfu08(unsigned char data)
{
rprintfu04(data>>4);
rprintfu04(data);
}
void rprintfu16(unsigned short data)
{
rprintfu08(data>>8);
rprintfu08(data);
}
void rprintfu32(unsigned long data)
{
rprintfu16(data>>16);
rprintfu16(data);
}
void rprintfNum(char base, char numDigits, char isSigned, char padchar, long n)
{
char *p, buf[32];
unsigned long x;
unsigned char count;
if( isSigned && (n < 0) )
{
x = -n;
}
else
{
x = n;
}
count = (numDigits-1)-(isSigned?1:0);
p = buf + sizeof (buf);
*--p = '\0';
*--p = pgm_read_byte(HexChars + (x%base)); x /= base;
while(count--)
{
if(x != 0)
{
*--p = pgm_read_byte(HexChars + (x%base)); x /= base;
}
else
{
*--p = padchar;
}
}
if( isSigned )
{
if(n < 0)
{
*--p = '-';
}
else if(n > 0)
{
*--p = '+';
}
else
{
*--p = ' ';
}
}
count = numDigits;
while(count--)
{
rprintfChar(*p++);
}
}
#ifdef RPRINTF_FLOAT
void rprintfFloat(char numDigits, double x)
{
unsigned char firstplace = FALSE;
unsigned char negative;
unsigned char i, digit;
double place = 1.0;
negative = (x<0);
x = (x>0)?(x):(-x);
for(i=0; i<15; i++)
{
if((x/place) < 10.0)
break;
else
place *= 10.0;
}
if(negative)
rprintfChar('-');
else
rprintfChar('+');
for(i=0; i<numDigits; i++)
{
digit = (x/place);
if(digit | firstplace | (place == 1.0))
{
firstplace = TRUE;
rprintfChar(digit+0x30);
}
else
rprintfChar(' ');
if(place == 1.0)
{
rprintfChar('.');
}
x -= (digit*place);
place /= 10.0;
}
}
#endif
#ifdef RPRINTF_SIMPLE
int rprintf1RamRom(unsigned char stringInRom, const char *format, ...)
{
char format_flag;
unsigned int u_val, div_val, base;
va_list ap;
va_start(ap, format);
for (;;)
{
while ((format_flag = READMEMBYTE(stringInRom,format++) ) != '%')
{ // Until '%' or '\0'
if (!format_flag)
{
va_end(ap);
return(0);
}
rprintfChar(format_flag);
}
switch (format_flag = READMEMBYTE(stringInRom,format++) )
{
case 'c': format_flag = va_arg(ap,int);
default: rprintfChar(format_flag); continue;
case 'd': base = 10; div_val = 10000; goto CONVERSION_LOOP;
case 'x': base = 16; div_val = 0x10;
CONVERSION_LOOP:
u_val = va_arg(ap,int);
if (format_flag == 'd')
{
if (((int)u_val) < 0)
{
u_val = - u_val;
rprintfChar('-');
}
while (div_val > 1 && div_val > u_val) div_val /= 10;
}
do
{
rprintfChar(pgm_read_byte(HexChars+(u_val/div_val)));
u_val %= div_val;
div_val /= base;
} while (div_val);
}
}
va_end(ap);
}
#endif
#ifdef RPRINTF_COMPLEX
int rprintf2RamRom(unsigned char stringInRom, const char *sfmt, ...)
{
register unsigned char *f, *bp;
register long l;
register unsigned long u;
register int i;
register int fmt;
register unsigned char pad = ' ';
int flush_left = 0, f_width = 0, prec = INF, hash = 0, do_long = 0;
int sign = 0;
va_list ap;
va_start(ap, sfmt);
f = (unsigned char *) sfmt;
for (; READMEMBYTE(stringInRom,f); f++)
{
if (READMEMBYTE(stringInRom,f) != '%')
{ // not a format character
rprintfChar(READMEMBYTE(stringInRom,f));
}
else
{
f++; // if we have a "%" then skip it
if (READMEMBYTE(stringInRom,f) == '-')
{
flush_left = 1; // minus: flush left
f++;
}
if (READMEMBYTE(stringInRom,f) == '0'
|| READMEMBYTE(stringInRom,f) == '.')
{
// padding with 0 rather than blank
pad = '0';
f++;
}
if (READMEMBYTE(stringInRom,f) == '*')
{ // field width
f_width = va_arg(ap, int);
f++;
}
else if (Isdigit(READMEMBYTE(stringInRom,f)))
{
f_width = atoiRamRom(stringInRom, (char *) f);
while (Isdigit(READMEMBYTE(stringInRom,f)))
f++; // skip the digits
}
if (READMEMBYTE(stringInRom,f) == '.')
{ // precision
f++;
if (READMEMBYTE(stringInRom,f) == '*')
{
prec = va_arg(ap, int);
f++;
}
else if (Isdigit(READMEMBYTE(stringInRom,f)))
{
prec = atoiRamRom(stringInRom, (char *) f);
while (Isdigit(READMEMBYTE(stringInRom,f)))
f++; // skip the digits
}
}
if (READMEMBYTE(stringInRom,f) == '#')
{ // alternate form
hash = 1;
f++;
}
if (READMEMBYTE(stringInRom,f) == 'l')
{ // long format
do_long = 1;
f++;
}
fmt = READMEMBYTE(stringInRom,f);
bp = buf;
switch (fmt) { // do the formatting
case 'd': // 'd' signed decimal
if (do_long)
l = va_arg(ap, long);
else
l = (long) (va_arg(ap, int));
if (l < 0)
{
sign = 1;
l = -l;
}
do {
*bp++ = l % 10 + '0';
} while ((l /= 10) > 0);
if (sign)
*bp++ = '-';
f_width = f_width - (bp - buf);
if (!flush_left)
while (f_width-- > 0)
rprintfChar(pad);
for (bp--; bp >= buf; bp--)
rprintfChar(*bp);
if (flush_left)
while (f_width-- > 0)
rprintfChar(' ');
break;
case 'o': // 'o' octal number
case 'x': // 'x' hex number
case 'u': // 'u' unsigned decimal
if (do_long)
u = va_arg(ap, unsigned long);
else
u = (unsigned long) (va_arg(ap, unsigned));
if (fmt == 'u')
{ // unsigned decimal
do {
*bp++ = u % 10 + '0';
} while ((u /= 10) > 0);
}
else if (fmt == 'o')
{ // octal
do {
*bp++ = u % 8 + '0';
} while ((u /= 8) > 0);
if (hash)
*bp++ = '0';
}
else if (fmt == 'x')
{ // hex
do {
i = u % 16;
if (i < 10)
*bp++ = i + '0';
else
*bp++ = i - 10 + 'a';
} while ((u /= 16) > 0);
if (hash)
{
*bp++ = 'x';
*bp++ = '0';
}
}
i = f_width - (bp - buf);
if (!flush_left)
while (i-- > 0)
rprintfChar(pad);
for (bp--; bp >= buf; bp--)
rprintfChar((int) (*bp));
if (flush_left)
while (i-- > 0)
rprintfChar(' ');
break;
case 'c': // 'c' character
i = va_arg(ap, int);
rprintfChar((int) (i));
break;
case 's': // 's' string
bp = va_arg(ap, unsigned char *);
if (!bp)
bp = (unsigned char *) "(nil)";
f_width = f_width - strlen((char *) bp);
if (!flush_left)
while (f_width-- > 0)
rprintfChar(pad);
for (i = 0; *bp && i < prec; i++)
{
rprintfChar(*bp);
bp++;
}
if (flush_left)
while (f_width-- > 0)
rprintfChar(' ');
break;
case '%': // '%' character
rprintfChar('%');
break;
}
flush_left = 0, f_width = 0, prec = INF, hash = 0, do_long = 0;
sign = 0;
pad = ' ';
}
}
va_end(ap);
return 0;
}
unsigned char Isdigit(char c)
{
if((c >= 0x30) && (c <= 0x39))
return TRUE;
else
return FALSE;
}
int atoiRamRom(unsigned char stringInRom, char *str)
{
int num = 0;;
while(Isdigit(READMEMBYTE(stringInRom,str)))
{
num *= 10;
num += ((READMEMBYTE(stringInRom,str++)) - 0x30);
}
return num;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -