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

📄 comm_mcu8051.c

📁 用quartusII编写的
💻 C
📖 第 1 页 / 共 2 页
字号:
      
      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 + -