📄 comm_mcu8051.c
字号:
if( cnt > PRINT_BUF_SIZE-1 )
{
// vsprintf()实际输出到print_buf[]中的字符个数大于了print_buf[]的容量
// 造成print_buf[]溢出
return -1;
}
// 将print_buf通过串口发送出去
if( CommSendString( commNum, print_buf ) != COMM_NO_ERR )
{
// 串口发送出错
return -1;
}
return cnt;
}
#endif
#if 0
//---------------------------------------------------------------------------
// 串口打印函数
//
// 说明:
// 本函数和ANSI C标准库stdio.h中定义的printf()函数保持兼容,本函数只是在
// 形参中多了一个“串口号”参数,其余和printf()函数完全兼容,包括形参和返回值。
//
// 不知道为什么,下面的打印函数的实现在51单片机中有错,但是在PC平台,使用
// bcc32编译器却没有问题。(下面的代码只要略微修改,就可以在PC平台中运行,
// 2004-12-20 11:03以下代码在bcc32,PC平台下实际测试通过。)
// extern void CommPrintf( INT8U commNum, const char *format, ... )
// {
// static INT8U print_buf[64];
// va_list args;
//
// va_start( args, format );
// vsprintf( print_buf, format, args );
// va_end( args );
// 将print_buf通过串口发送出去
// }
// 像上面那样实现串口打印函数,虽然代码简单,但是消耗的内存较大,这是因为
// 它是将已经格式化好了的所有数据,存入到print_buf中,这就要求print_buf占用的
// 空间比较大,以便能够容纳格式化好的所有数据。在51单片机中是很难分配这样大的
// 数据存储空间的。
//
//---------------------------------------------------------------------------
extern int CommPrintf( INT8U commNum, const char *format, ... )
{
/*
实现这个函数的时候,要注意从'%'号到格式字符之间含有'*'这种情况。
例如:
printf( "%*.*lf", 8, 3, 3.1415926 );
其中,第1个'*'号表示宽度,第2个'*'号表示精度。
*/
// 转换字符表,查这个表就可以知道相应的字符是否为转换字符
// 在ANSI C标准库stdio.h中定义的printf()的转换字符有:
// d, i, o, x, X, u, c, s, f, e, E, g, G, p, n, %
static INT8U code conversion_char_table[] =
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1,
1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
#define PRINT_BUF_SIZE 16
static INT8U idata print_buf[ PRINT_BUF_SIZE ];
#define CONVERSION_DECLARATOR_SIZE 16
static INT8U idata conversion_declarator[ CONVERSION_DECLARATOR_SIZE ]; // 存储一个转换说明
INT8U index; // conversion_declarator[]的索引
COMM_ERR_TYPE comm_err;
// 记录已经输出的字符个数,其实就是本函数的返回值
int cnt;
// 宽度和精度,因为ANSI C中要求宽度和精度必须是int类型,所以定义为int
int width, precision;
// 存储一个转换说明中的转换字符
// 在ANSI C标准库stdio.h中定义的printf()的转换字符有:
// d, i, o, x, X, u, c, s, f, e, E, g, G, p, n, %
INT8U conversion_char;
va_list arg_ptr;
va_start( arg_ptr, format );
cnt = 0;
while( *format != '\0' )
{
if( *format != '%' )
{
comm_err = CommSendByte( commNum, *format );
if( comm_err != COMM_NO_ERR )
{
return -1;
}
++cnt;
++format;
}
else
{
/*
记录从'%'号到转换字符之间的所有字符,形成字符串 => conversion_declarator[]
如果在'%'号到转换字符之间有宽度和精度,则记录其宽度 => width,
精度 => precision
记录一个转换说明中的转换字符 => conversion_char
*/
width = -1;
precision = -1;
index = 0;
conversion_declarator[ index++ ] = '%';
// 跳开第一个'%'
++format;
for( ; *format != '\0'; ++format )
{
// 防止conversion_declarator[]溢出
// 如果一个转换说明的长度超过了CONVERSION_DECLARATOR_SIZE,作为出错处理
if( index == CONVERSION_DECLARATOR_SIZE-1 )
{
return -1;
}
conversion_declarator[ index++ ] = *format;
if( *format == '*' )
{
if( width < 0 ) // 如果还没有记录宽度,则记录宽度
{
width = va_arg( arg_ptr, int );
}
else
{
if( precision < 0 ) // 如果还没有记录精度,则记录精度
precision = va_arg( arg_ptr, int );
}
}
else if( conversion_char_table[ (INT8U)(*format) ] ) // 如果是转换字符
{
conversion_char = *format; // 记录转换字符
break;
}
}
if( *format == '\0' )
return -1;
++format;
conversion_declarator[ index++ ] = '\0';
/*
assertion:
执行到这里,则:
(1)单个转换说明在conversion_declarator[]中
(2)如果有宽度,宽度在width中;没有宽度,width为-1
(3)如果有精度,精度在precision中;没有精度,precision为-1
(4)转换字符在conversion_char中
*/
// 根据转换字符取参数
switch( conversion_char )
{
case 'c':
if( width>=0 && precision>=0 )
sprintf( print_buf, conversion_declarator, width, precision, va_arg(arg_ptr, int) );
else if( width>=0 && precision<0 )
sprintf( print_buf, conversion_declarator, width, va_arg(arg_ptr, int) );
else if( width<0 && precision>=0 )
sprintf( print_buf, conversion_declarator, precision, va_arg(arg_ptr, int) );
else
sprintf( print_buf, conversion_declarator, va_arg(arg_ptr, int) );
break;
case 's':
if( width>=0 && precision>=0 )
sprintf( print_buf, conversion_declarator, width, precision, va_arg(arg_ptr, char *) );
else if( width>=0 && precision<0 )
sprintf( print_buf, conversion_declarator, width, va_arg(arg_ptr, char *) );
else if( width<0 && precision>=0 )
sprintf( print_buf, conversion_declarator, precision, va_arg(arg_ptr, char *) );
else
sprintf( print_buf, conversion_declarator, va_arg(arg_ptr, char *) );
break;
case 'o':
if( width>=0 && precision>=0 )
sprintf( print_buf, conversion_declarator, width, precision, va_arg(arg_ptr, unsigned long) );
else if( width>=0 && precision<0 )
sprintf( print_buf, conversion_declarator, width, va_arg(arg_ptr, unsigned long) );
else if( width<0 && precision>=0 )
sprintf( print_buf, conversion_declarator, precision, va_arg(arg_ptr, unsigned long) );
else
sprintf( print_buf, conversion_declarator, va_arg(arg_ptr, unsigned long) );
break;
case 'p':
if( width>=0 && precision>=0 )
sprintf( print_buf, conversion_declarator, width, precision, (unsigned long) va_arg(arg_ptr, void *) );
else if( width>=0 && precision<0 )
sprintf( print_buf, conversion_declarator, width, (unsigned long) va_arg(arg_ptr, void *) );
else if( width<0 && precision>=0 )
sprintf( print_buf, conversion_declarator, precision, (unsigned long) va_arg(arg_ptr, void *) );
else
sprintf( print_buf, conversion_declarator, (unsigned long) va_arg(arg_ptr, void *) );
break;
case 'x':
case 'X':
if( width>=0 && precision>=0 )
sprintf( print_buf, conversion_declarator, width, precision, va_arg(arg_ptr, unsigned long) );
else if( width>=0 && precision<0 )
sprintf( print_buf, conversion_declarator, width, va_arg(arg_ptr, unsigned long) );
else if( width<0 && precision>=0 )
sprintf( print_buf, conversion_declarator, precision, va_arg(arg_ptr, unsigned long) );
else
sprintf( print_buf, conversion_declarator, va_arg(arg_ptr, unsigned long) );
break;
case 'd':
case 'i':
case 'u':
if( width>=0 && precision>=0 )
sprintf( print_buf, conversion_declarator, width, precision, va_arg(arg_ptr, unsigned long) );
else if( width>=0 && precision<0 )
sprintf( print_buf, conversion_declarator, width, va_arg(arg_ptr, unsigned long) );
else if( width<0 && precision>=0 )
sprintf( print_buf, conversion_declarator, precision, va_arg(arg_ptr, unsigned long) );
else
sprintf( print_buf, conversion_declarator, va_arg(arg_ptr, unsigned long) );
break;
case 'n':
/* 到目前为止,此printf()调用输出的字符的数目将写入到相应的参数中。不进行参数转换。例如:int n; printf( "%d%ndef", 123456, &n ); n的值为6 */
if( width>=0 && precision>=0 )
sprintf( print_buf, conversion_declarator, width, precision, va_arg(arg_ptr, int *) );
else if( width>=0 && precision<0 )
sprintf( print_buf, conversion_declarator, width, va_arg(arg_ptr, int *) );
else if( width<0 && precision>=0 )
sprintf( print_buf, conversion_declarator, precision, va_arg(arg_ptr, int *) );
else
sprintf( print_buf, conversion_declarator, va_arg(arg_ptr, int *) );
break;
case 'f':
case 'e':
case 'E':
case 'g':
case 'G':
if( width>=0 && precision>=0 )
sprintf( print_buf, conversion_declarator, width, precision, va_arg(arg_ptr, double) );
else if( width>=0 && precision<0 )
sprintf( print_buf, conversion_declarator, width, va_arg(arg_ptr, double) );
else if( width<0 && precision>=0 )
sprintf( print_buf, conversion_declarator, precision, va_arg(arg_ptr, double) );
else
sprintf( print_buf, conversion_declarator, va_arg(arg_ptr, double) );
break;
default:
// 其余情况,都作为'%'处理
if( width>=0 && precision>=0 )
sprintf( print_buf, conversion_declarator, width, precision, '%' );
else if( width>=0 && precision<0 )
sprintf( print_buf, conversion_declarator, width, '%' );
else if( width<0 && precision>=0 )
sprintf( print_buf, conversion_declarator, precision, '%' );
else
sprintf( print_buf, conversion_declarator, '%' );
break;
}
comm_err = CommSendString( commNum, print_buf );
if( comm_err != COMM_NO_ERR )
{
return -1;
}
cnt += strlen( print_buf );
}
}
va_end( arg_ptr );
return cnt;
}
#endif
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -