⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rprintf.c

📁 实现功能ATmega单片机上处理GSM模块的数据
💻 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 + -