重剑无锋 https://bbs.21ic.com/?425187 [收藏] [复制] [RSS]

日志

串口微型打印机器程序

热度 1已有 2513 次阅读2008-4-9 17:09 |个人分类:AVR|系统分类:单片机| 串口, 微型打印机器, 程序

N久没来更新了,发发去年做的一个微型打印机程序;


初步版本。。实际应用中加入了硬件忙信号检测等等。。但此版本同样经过验证。


借鉴printf()函数。。精简修改,解决了AVR C编译器自带的printf()函数太庞大的问题。。


 


/*------------------------------------------------------------------------------
File   : Printer_WH.c             
Project         : Printer_WH.prj
Item   : Cam Controller TT-FZ0430607-V1.0 F60608027
New Data  : 2007-10-23
Author   : wangxinjia
Comments  : Printet - 
      Uart0 Link
      ( Uart - SIUPO(北京迅普微型打印机) )
------------------------------------------------------------------------------*/
#include  "Universal.h"
//#include "Printer_WH.h"
#include <stdarg.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>


#define  BAUD  9600
#define  UBRR_VALUE (INT32U)FCLK/16/(INT32U)BAUD -1


#define  NUL   0x00       //空
#define  BEL   0x07       //报警符
#define  BS   0x08       //退格
#define  HT   0x09       //横向列表
#define  LF   0x0A       //换行
#define  VT   0x0B       //垂直制表
#define  FF   0x0C       //换页(走纸控制)
#define  CR   0x0D       //回车
#define  SO   0x0E       //横向放大两倍(移位输出)
#define  DC4   0x14       //横向无放大(设备控制4)
#define  CAN   0x18       //删除一行(做废)
#define  ESC   0x1B       //     
#define  FS   0x1C       //
#define  SPACE  0x20       //空格


#define  PANE  0X3C       //方框  


static char  buf[25]     ;
UCHAR   PrintDataPrec   ;
UCHAR   PrintDataSignCh   ;
int    PrintDataWidth   ;
UCHAR   PrintDataFlag   ;
//--------------------------------------
#define  F_ALTFORM  0x01       /* alternate form, e.g. %#x */
#define  F_LONG   0x02       /* long modifier, e.g. %ld */
#define  F_LEFTALIGN 0x04       /* left align, e.g. %-... */
#define  F_ADDSIGN  0x08       /* sign (+ or -) e.g. %+, or %(space) */
#define  F_ZEROPADD  0x10       /* zero padded instead of space padded */
#define  F_FRACTION  0x20       /* fraction  */
//---------------------------------------


void PrinterInit(void);
void PrintLineChar(char *s);


void PrintChar(unsigned char c);
void PrintString(char *bp);
void PrintDigit(char *bp);
int MixPrintFun(CONST char *fmt, ...);


void uart0_init (void)
{
 UCSRB = 0x00;           //disable while setting baud rate
  UCSRA = 0x00;
// UCSRC = BIT(URSEL)|BIT(UPM1)|BIT(UCSZ1)|BIT(UCSZ0); //8,even,1
 UCSRC = BIT(URSEL)|BIT(UCSZ1)|BIT(UCSZ0);   //8,N,1
 UBRRL = WORD_LO(UBRR_VALUE);      //9600-0x67;38400-0x19
 UBRRH = WORD_HI(UBRR_VALUE); 
// UCSRB = BIT(TXEN);         //only enable send
 UCSRB = BIT(RXCIE)|BIT(RXEN)|BIT(TXEN);    //0x98
}
 
void PrinterInit (void)
{
 //-----串口设置--------------
 uart0_init();
 //-----初始化打印机----------
 putchar(ESC);
 putchar('@');
 //-----12*12点阵汉字----------
 putchar(ESC);
 putchar('8');
 //----------------------------
  MixPrintFun("\t产品批号: 0000%5u\n",65535);
}
/*-------------------------------
* 打印一行字符:包括汉字和字符
* 从行首开始打印
* 打印完成后自动回车换行
-------------------------------*/
void PrintLineChar (char *s)
{
 puts(s);
// printf("%s\n",s); 
}


void PrintChar(unsigned char c)
{
 unsigned char i;
 switch ((unsigned char) c) {
    case '\a' :
   putchar(BEL); //putchar(0x07);报警符
   break;
    case '\b' :
   putchar(BS); //putchar(0x08);退格
   break;
    case '\t' :
//   putchar(HT); //putchar(0x09);横向列表
   for(i=0;i<4;i++){
    putchar(' ');
   }
   break;
    case '\n' :
   putchar(LF); //putchar(0x0A);换行
   break;   
    case '\f' :
   putchar(FF); //putchar(0x0C);走纸控制(换页)
   break;            
    case '\r' :
   putchar(CR); //putchar(0x0D);回车
   break;
  default :
      putchar ((unsigned char) c);


 }


}
// 字符串的格式化打印
// 程序先对补0和前导以及符号位进行判断处理
// 然后输出数据,注意小数点的位置
void PrintString(char *bp)
{
 UCHAR i;
 if (PrintDataWidth)       //指定了宽度
     PrintDataWidth -= strlen(bp);   //除去字符剩余的宽度
    if (PrintDataWidth && (PrintDataFlag & F_ADDSIGN)) //除去数据字符的宽度里面再除去符号位
       PrintDataWidth--; 
 if (PrintDataWidth && (PrintDataFlag & F_FRACTION)) //除去数据字符的宽度里面再除去小数点位
       PrintDataWidth--;  
    if (PrintDataFlag & F_ZEROPADD){   //前端补0
  if (PrintDataFlag & F_ADDSIGN)   //sign
   PrintChar(PrintDataSignCh);
  if (!(PrintDataFlag & F_LEFTALIGN)){ //不要求左对齐,即指定宽度右对齐
   while (PrintDataWidth > 0){
    PrintChar('0');
    PrintDataWidth--;
   }
  } 
 }else{
  if (!(PrintDataFlag & F_LEFTALIGN)){ //不要求左对齐,即指定宽度右对齐
   while (PrintDataWidth > 0){   //前端补' '
    PrintChar(' ');
       PrintDataWidth--;
   }
  }
  if (PrintDataFlag & F_ADDSIGN)
   PrintChar(PrintDataSignCh);
    }
 i=strlen(bp);
 while(i){    //数据输出
  if ( (i==PrintDataPrec) && (PrintDataFlag & F_FRACTION) ){
   PrintChar('.');  //小数点
  }
  PrintChar(*bp);
  bp++;
  i--;
 }
}
// 数据打印处理
void PrintDigit(char *bp)
{
 int i;
    if (PrintDataPrec){   
     i = strlen(buf);
     if (PrintDataPrec > i) //小数点位置不能越界
      PrintDataPrec = i;
    }
 PrintString(bp);
}
/*-------------------------------
* cntrl_string  格式化文本字符串
* va_list    不确定类型(变长参数),需要stdarg.h; va_start,va_end成对使用。
* cnt_printed_chars 返回输出的字符个数
-------------------------------*/
int MixPrintFun(CONST char *fmt, ...)
{
 va_list va;
 char *bp;
 char *s;
 unsigned char* cs;
   unsigned char done;
   int i;
 
 va_start(va, fmt);
 
// val = _print((void (*)(char))putchar, fmt, va);
 for ( ; *fmt; fmt++){    //非格式字符%
       if (*fmt != '%'){
           PrintChar(*fmt);
           continue;
        }
  bp = buf;
  PrintDataFlag = 0;
  PrintDataWidth= 0;
       PrintDataPrec = 0; 
  PrintDataSignCh= ' ';
       ++fmt;
  PrintDataFlag=0;
  for (done = 0; ; fmt++){   //查找格式控制字符
         switch (fmt[0]){
          case '#':  // o/0x/0X 引导
              PrintDataFlag |= F_ALTFORM;
              break;
          case '-':  //左对齐
              PrintDataFlag |= F_LEFTALIGN;
              break;
           case '+':  //正整数前面加符号+
              PrintDataFlag |= F_ADDSIGN;
              PrintDataSignCh = '+';
              break;
          case ' ':  //显示符号位
              PrintDataFlag |= F_ADDSIGN;
              PrintDataSignCh = ' ';
              break;
          case '0':  //用0代替输出的空格
              PrintDataFlag |= F_ZEROPADD;
              break;
          default:
              done = 1; //格式控制字符后面的数据宽度和精度以及类型等的处理
              break;
            }
         if (done)   /* break here so fmt++ would not happen */
             break;
        }//for (done = 0; ; fmt++)
  //获得宽度
       if (isdigit (fmt[0])) {   //取格式化字符指定的宽度(1 bit)
           PrintDataWidth = atoi ((char *) fmt);
           while (isdigit (*fmt))
               fmt++;
        }else if (fmt[0] == '*'){  //参数指定宽度
           PrintDataWidth = va_arg(va, int); 
           fmt++;
        }
  if (fmt[0] == '.'){    //获得精度
   PrintDataFlag |= F_FRACTION;
           ++fmt;
           if (isdigit(fmt[0])){  //取格式化字符指定的精度(1 bit)
             PrintDataPrec = atoi ((char *) fmt);
             while (isdigit (*fmt))
                 fmt++;
            }else if (fmt[0] == '*'){ //参数指定精度
             PrintDataPrec = va_arg(va, int);
             fmt++;
            }
        }
  switch (*fmt){     //输出数据格式处理
         default:     //无效格式,当字符处理
            PrintChar(*fmt);
            break;
   case 'c':     //输出字符
    PrintChar(va_arg (va, int) );
    break; 
   case 's':     //输出字符串
    cs = va_arg(va, unsigned char *);
     i = 0;
     while (cs ) {
        PrintChar (cs [i++]);
    }    
    break;  
         case 'd':     //10进制int输出
    i = va_arg (va, int);
               if (i < 0){
                  PrintDataFlag |= F_ADDSIGN;
                  PrintDataSignCh = '-';
                  i = -i;
                }
               itoa (bp, i, 10);
    PrintDigit(bp);
    break;
         case 'u':     //10进制无符号数输出
//    break;
   case 'o':     //八进制数据输出
//    break;
   case 'x':     //16进制小写输出
//    break;
   case 'X':     //16进制大写输出
    i = va_arg (va, unsigned int);
    if (*fmt == 'u'){
     utoa (bp, i, 10);
    }else if (*fmt == 'o'){
     if (PrintDataFlag & F_ALTFORM)
                    *bp++ = 'o';
     utoa (bp, i, 8); 
     bp--;  //'o'
    }else{
     if (PrintDataFlag & F_ALTFORM){
                    *bp++ = '0';
                    *bp++ = fmt[0];
                 }
     utoa (bp, i, 16);
     if (fmt[0] == 'X'){
                  for (s = buf; *s; s++)
                      *s = toupper(*s);
     }
     bp-=2;  //0x  
    }
    PrintDigit(bp);
    break;  
  }//switch (*fmt)
 }//for ( ; *fmt; fmt++)  
 va_end(va);


 return 1;
}


路过

鸡蛋

鲜花

握手

雷人

发表评论 评论 (4 个评论)

帮帮忙 2008-7-21 17:56
[emot]2[/emot] 可以给我一份驱动吗? 我有迅普的58mm SP-T32SK热敏打印机,但找不到驱动啊。。。。 谢谢! 我的邮箱: rfde@sina.com

QUOTE:
以下为wxjia2004的回复: 上面程序的就是驱动啊
宝贝老虎 2009-5-15 02:10
老大有没有编译后的程序啊。
回复 雷子 2009-5-24 10:53
这个怎么用!一直找不到相应的驱动,跟楼上同求
回复 linlh11 2014-9-29 00:30
很好的资料。下载先参考参考