佳博 热敏打印机 ESCPOS 指令研究

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/wowocpp/article/details/80749259

Test.txt内容:
参考打印到文档功能:
初识打印机驱动
http://www.cnblogs.com/MrDing/p/4078189.html
热敏打印头打印原理和C实现黑白位图的放大
https://www.jianshu.com/p/c754bfa377e4

ascii码 :

十六进制 十进制 字符 含义
0a 10 \n LF
0d 13 \r CR
1b 27 esc
1d 29 gs

热敏打印机参数:

首先佳博GP-L80180I票据打印机技术参数

打印方式 直接热敏式
打印密度 576点/行或512点/行
打印速度 180毫米/秒
接口类型 串口+USB+网口
打印纸宽 79.5±0.5毫米
纸张厚度 0.06~0.08毫米
纸卷外径 83毫米
可靠性 100公里
使用字库 简体中文GB18030大字库
条形码类型 UPC-A/UPC-E/JAN13(EAN13)/JAN8(EAN8)/CODE39/ITF/CODABAR/CODE93/CODE128
字符大小 ANK字符:FontA:12×24点 FontB:9×17点 简体/繁体:24×24点
打印命令 兼容ESC/POS命令

log与流程的对应关系:

对应的代码如下:

// 打印头宽度约为 80mm 的打印函数

BOOL USB_GPL801_PrintInStandardMode80(void)
{


    int ret ;

    ret = VC_POS_Reset();
    printf("VC_POS_Reset ret = %d\r\n",ret);

    VC_POS_FeedLine();
    VC_POS_FeedLine();

    //VC_POS_PreDownloadBmpToRAM("a.BMP",3);
    ret = VC_POS_PreDownloadBmpToRAM("Kitty.bmp",3);
    printf("VC_POS_PreDownloadBmpToRAM ret = %d\r\n",ret);



    int nRet = VC_POS_SetMotionUnit(180, 180);

    if(POS_SUCCESS != nRet)
    {
        return false;
    }

    VC_POS_SetMode(POS_PRINT_MODE_STANDARD);


    VC_POS_FeedLine();
    VC_POS_FeedLine();


    VC_POS_FeedLine();
    VC_POS_S_TextOut("通行卡ID:", 70, 1, 1, POS_FONT_TYPE_CHINESE,
        POS_FONT_STYLE_NORMAL);


    VC_POS_S_TextOut("3303000012345678", 190, 1, 1, POS_FONT_TYPE_CHINESE,
        POS_FONT_STYLE_NORMAL);     

        VC_POS_FeedLine();

    VC_POS_S_TextOut("入口时间:", 70, 1, 1, POS_FONT_TYPE_CHINESE,
        POS_FONT_STYLE_NORMAL);

    VC_POS_S_TextOut("2018-04-20  10:10:10", 190, 1, 1, POS_FONT_TYPE_CHINESE,
        POS_FONT_STYLE_NORMAL);

        VC_POS_FeedLine();

    VC_POS_S_TextOut("金额:", 70, 1, 1, POS_FONT_TYPE_CHINESE,
        POS_FONT_STYLE_NORMAL);    

    VC_POS_S_TextOut("86.00元", 190, 1, 1, POS_FONT_TYPE_CHINESE,
        POS_FONT_STYLE_NORMAL);

        VC_POS_FeedLine();


    VC_POS_S_TextOut("车牌:", 70, 1, 1, POS_FONT_TYPE_CHINESE,
        POS_FONT_STYLE_NORMAL);

    VC_POS_S_TextOut("鲁A66001[蓝色]", 190, 1, 1, POS_FONT_TYPE_CHINESE,
        POS_FONT_STYLE_NORMAL);   

        VC_POS_FeedLine();
        VC_POS_FeedLine();

    //VC_POS_S_PrintBmpInRAM(3,20,POS_BITMAP_PRINT_NORMAL);
    VC_POS_S_PrintBmpInRAM(3,20,POS_BITMAP_PRINT_QUADRUPLE);

    VC_POS_FeedLine();
    VC_POS_FeedLine();
    VC_POS_FeedLine();
    VC_POS_FeedLine();
    VC_POS_FeedLine();
    VC_POS_FeedLine();

    // 切纸
    VC_POS_CutPaper(POS_CUT_MODE_FULL, 0);


    return TRUE;

}

这里写图片描述
设置的太小,容易丢数据
log如下:

这里写图片描述

打印出来的效果如下:
这里写图片描述

下面开始分析:

1b 40

这里写图片描述

0a 0a —– 两次换行
这里写图片描述

1d 23 03
应该是 定义 ID号为03

1d 2a 10 06 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

这里写图片描述

x = 0x10
y = 0x06
下面的是位图数据:
101x46像素
这里写图片描述

这里写图片描述

这个文件头 54个字节 可能是理解不对

这里写图片描述

发送的数据 和 bmp 的数据 有点不一致 ,有空分析一下

16 x 6 x 8 = 768个字节
24 x 32 = 768 字节

继续下面的操作:

1d  50 b4 b4 1b  53 0a 0a 0a  

1b 24 46 00  1b 4d 03 

1d  42 00 
1d 62  00 
1d 21 00  

1b 45 00 

1b  7b 00 

1b 2d  00 
1c 2d 00  
1b 56 00 
cd  a8 d0 d0 bf  a8 49 44 3a  
1b 24 be 00               
1b 4d 03 
1d  42 00 
1d 62  00 
1d 21 00
  1b 45 00 
  1b  7b 00 
  1b 2d  00 
  1c 2d 00  1b 56 00 
  33  33 30 33 30               
30 30 30 31  32 33 34 35  36 37 38 0a  
1b 24 46 00  
1b 4d 03 1d  42 00 1d 62  00 1d 21 00  1b 45 00 1b               
7b 00 1b 2d  00 1c 2d 00  1b 56 00 
c8  eb bf da ca  b1 bc e4 3a  

1b 24 be 00  1b 4d 03 1d  42 00 1d 62               
00 1d 21 00  1b 45 00 1b  7b 00 1b 2d  00 1c 2d 00  1b 56 00 
32  30 31 38 2d  30 34 2d 32  30 20 20 31               
30 3a 31 30  3a 31 30 0a  

1b 24 46 00  1b 4d 03 1d  42 00 1d 62  00 1d 21 00  1b 45 00 1b  7b 00 1b 2d               
00 1c 2d 00  1b 56 00 bd  f0 b6 ee 3a  
1b 24 be 00  1b 4d 03 1d  42 00 1d 62  00 1d 21 00  1b 45 00 1b               
7b 00 1b 2d  00 1c 2d 00  1b 56 00 38  36 2e 30 30  d4 aa 0a 
1b  24 46 00 
1b  4d 03 1d 42  00 1d 62 00               
1d 21 00 1b  45 00 1b 7b  00 1b 2d 00  1c 2d 00 1b  56 00 b3 b5  c5 c6 3a 
1b  24 be 00 
1b  4d 03 1d 42               
00 1d 62 00  1d 21 00 1b  45 00 1b 7b  00 1b 2d 00  1c 2d 00 
1b  56 00 
c2 b3  41 36 36 30  30 31 5b c0               
b6 c9 ab 5d     鲁A66001[蓝色]


0a 0a 

1b 24  14 00 1d 23  03 1d 2f 03  0a 0a 0a 0a  0a 0a 1d 56  00

1d 50 b4 b4
这里写图片描述

1b 53
这里写图片描述

1b 24 46 00
这里写图片描述

0x46 = 70

1b 4d 03 选择中文 字体
这里写图片描述

1d 42 00
这里写图片描述

1d 62 00 —- 这个不知道

1d 21 00
这里写图片描述
这里写图片描述
1b 45 00
这里写图片描述

1b 7b 00
这里写图片描述

1b 2d 00
这里写图片描述

1c 2d 00
这里写图片描述

1b 56 00
这里写图片描述

cd a8 d0 d0 bf a8 49 44 3a
http://www.mytju.com/classcode/tools/encode_gb2312.asp
这里写图片描述

1b 24 be 00
这里写图片描述

VC_POS_S_PrintBmpInRAM(3,20,POS_BITMAP_PRINT_QUADRUPLE);

1b 24  14 00 
1d 23  03   --- 选择ID 03
1d 2f 03  0a 0a 0a 0a  0a 0a 1d 56  00

1d 2f 03
这里写图片描述

1d 56 00
这里写图片描述

这里写图片描述
这里写图片描述

这里写图片描述

《佳博热敏票据打印机编程手册.pdf》有二维码指令 (实验没有成功)

page49
这里写图片描述

直接USB发送ESCPOS指令代码

win32 工程 vs2013
该代码 打印 二维码 没有成功
佳博GP-L80180 热敏打印机

GPL80_ESCPOS_USB.cpp

代码如下:

// GPL80_ESCPOS_USB.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <windows.h>
#include <string>
#include <IOSTREAM>
#include <winioctl.h>
#include <setupapi.h>

#pragma comment(lib, "setupapi.lib")

using namespace std;

// SetupDiGetInterfaceDeviceDetail所需要的输出长度,定义足够大
#define INTERFACE_DETAIL_SIZE    (1024)

//设备数量上限,假设16台上限
#define MAX_DEVICE 16


//USB类的GUID
const GUID USB_GUID = { 0xa5dcbf10, 0x6530, 0x11d2, { 0x90, 0x1f, 0x00, 0xc0, 0x4f, 0xb9, 0x51, 0xed } };

int GetDevicePath(LPGUID lpGuid, LPTSTR* pszDevicePath);

////////////////////////////////////////////////////////////////////////////////////////////////////////
//获取CreateFile的USB端口号
////////////////////////////////////////////////////////////////////////////////////////////////////////

// 根据GUID获得设备路径
// lpGuid: GUID指针
// pszDevicePath: 设备路径指针的指针,用于返回找到的路径
// 返回: 成功得到的设备路径个数,可能不止1个
int GetDevicePath(LPGUID lpGuid, LPTSTR* pszDevicePath)
{
    HDEVINFO hDevInfoSet;
    SP_DEVINFO_DATA spDevInfoData;
    SP_DEVICE_INTERFACE_DATA ifData;
    PSP_DEVICE_INTERFACE_DETAIL_DATA pDetail;
    int nCount;
    int nTotle;
    BOOL bResult;

    TCHAR* strUSBPrint = TEXT("USB 打印支持");

    // 取得一个该GUID相关的设备信息集句柄
    hDevInfoSet = ::SetupDiGetClassDevs(lpGuid,     // class GUID 
        NULL,                    // 无关键字 
        NULL,                    // 不指定父窗口句柄 
        DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);    // 目前存在的设备

    // 失败...
    if (hDevInfoSet == INVALID_HANDLE_VALUE)
    {
        printf("failed \r\n");

        return 0;
    }

    // 申请设备接口数据空间
    pDetail = (PSP_DEVICE_INTERFACE_DETAIL_DATA)::GlobalAlloc(LMEM_ZEROINIT, INTERFACE_DETAIL_SIZE);

    pDetail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);

    nTotle = -1;
    nCount = 0;
    bResult = TRUE;

    // 设备序号=0,1,2... 逐一测试设备接口,到失败为止
    while (bResult)
    {
        nTotle++;
        spDevInfoData.cbSize = sizeof(SP_DEVINFO_DATA);

        // 枚举符合该GUID的设备接口
        bResult = ::SetupDiEnumDeviceInfo(
            hDevInfoSet,     // 设备信息集句柄
            (ULONG)nTotle,   // 设备信息集里的设备序号
            &spDevInfoData);        // 设备接口信息

        if (bResult)
        {
            DWORD DataT;
            TCHAR buf[MAX_PATH];
            DWORD nSize = 0;

            // get Friendly Name or Device Description
            if (SetupDiGetDeviceRegistryProperty(hDevInfoSet, &spDevInfoData,
                SPDRP_FRIENDLYNAME, &DataT, (PBYTE)buf, sizeof(buf), &nSize)) {
            }
            else if (SetupDiGetDeviceRegistryProperty(hDevInfoSet, &spDevInfoData,
                SPDRP_DEVICEDESC, &DataT, (PBYTE)buf, sizeof(buf), &nSize)) {
            }
            else {
                lstrcpy(buf, _T("Unknown"));
            }

            _tprintf(_T("buf = %s \r\n"), buf);
            //是否是要找的设备类型
            if (_tcscmp(buf, strUSBPrint) != 0)
                continue;

            _tprintf(_T("OK\r\n"));

            ifData.cbSize = sizeof(ifData);

            // 枚舉符合該GUID的設備接口
            bResult = ::SetupDiEnumDeviceInterfaces(
                hDevInfoSet,     // 設備信息集句柄
                NULL,            // 不需額外的設備描述
                lpGuid,          // GUID
                (ULONG)nTotle,   // 設備信息集里的設備序號
                &ifData);        // 設備接口信息

            if (bResult)
            {
                // 取得该设备接口的细节(设备路径)
                bResult = SetupDiGetInterfaceDeviceDetail(
                    hDevInfoSet,    // 设备信息集句柄
                    &ifData,        // 设备接口信息
                    pDetail,        // 设备接口细节(设备路径)
                    INTERFACE_DETAIL_SIZE,    // 输出缓冲区大小
                    NULL,           // 不需计算输出缓冲区大小(直接用设定值)
                    NULL);          // 不需额外的设备描述

                if (bResult)
                {
                    // 复制设备路径到输出缓冲区
                    ::_tcscpy_s(pszDevicePath[nCount],256, pDetail->DevicePath);
                    // 调整计数值
                    nCount++;
                    _tprintf(_T("Cnt = %d,pDetail->DevicePath =%s\r\n"), nCount, pDetail->DevicePath);
                }
            }
        }
    }

    // 释放设备接口数据空间
    ::GlobalFree(pDetail);

    // 关闭设备信息集句柄
    ::SetupDiDestroyDeviceInfoList(hDevInfoSet);

    return nCount;
}


HANDLE hPort = NULL;  //句柄


int   WriteData(string meg)
{
    DWORD dwWrite;
    return WriteFile(hPort, meg.c_str(), (DWORD)meg.length(), &dwWrite, NULL);
}

int WriteBuf(char *buf, int len)
{
    DWORD dwWrite;
    return WriteFile(hPort, buf, len, &dwWrite, NULL);
}

int POS_Reset(void)
{
    string s;
    s = "\x1B\x40";
    WriteData(s);

    return 0;
}

int POS_FeedLine(void)
{
    string s;
    s = "\x0A";
    WriteData(s);

    return 0;

}

int POS_SetMotionUnit(int x,int y)
{
    string s;
    s = "\x1D\x50\xB4\xB4";
    WriteData(s);
    s = "\x1B\x53";
    WriteData(s);

    return 0;
}

int POS_S_TextOut(string &abc)
{
    string s;

    char SetAbsPos[4] = {0x1B,0x24,0x46,0x00};
    WriteBuf(SetAbsPos,4);


    char SelctFontType[3] = { 0x1B, 0x4D, 0x03 };
    WriteBuf(SelctFontType, 3);

    char SelctOutMode[3] = { 0x1D, 0x21, 0x00 };

    WriteBuf(SelctOutMode, 3);


    WriteData(abc);

    return 0;
}

int POS_CutPaper()
{

    char CutPaperMode[4] = { 0x1D, 0x56, 0x41,0x00 };

    WriteBuf(CutPaperMode, 4);

    return 0;
}

int POS_OutQRCode()
{
    char  QRCode1[8] = { 0x1d, 0x28 ,0x6b ,0x03, 0x00, 0x31 ,0x43, 0x05 };

    char  QRCode2[16] = { 0x1d, 0x28, 0x6b, 0x0b, 0x00, 0x31, 0x50, 0x30, 0x47, 0x70, 0x72, 0x69,
                            0x6e, 0x74, 0x65, 0x72 };

    char  QRCode3[8] = { 0x1d, 0x28, 0x6b, 0x03, 0x00, 0x31, 0x51, 0x30 };


    WriteBuf(QRCode1, 8);

    WriteBuf(QRCode2, 16);

    WriteBuf(QRCode3, 8);

    return 0;
}

int _tmain(int argc, _TCHAR* argv[])
{

    //遍历USB设备,找到POS打印机路径
    int i, nDevice;
    TCHAR * szDevicePath[MAX_DEVICE];        // 设备路径

//  string Port;  //串口端口号
    setlocale(LC_CTYPE, "chs");//设置中文字符

    TCHAR * Port;

    // 分配需要的空间
    for (i = 0; i < MAX_DEVICE; i++)
    {
        szDevicePath[i] = new TCHAR[256];
    }

    // 取设备路径
    nDevice = GetDevicePath((LPGUID)&USB_GUID, szDevicePath);

    i = 0;


    while (i < nDevice){

        Port = szDevicePath[i++];

        _tprintf(_T("device.Port = %s\n"), Port);
    }


    hPort = CreateFile(Port, GENERIC_READ | GENERIC_WRITE,
        0, NULL,
        OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL, NULL);

    if (hPort == INVALID_HANDLE_VALUE)
    {   // 打开端口失败
        return false;
    }


    DWORD iBytesLength;
    string s;

    POS_Reset();
    POS_FeedLine();
    POS_FeedLine();

    POS_SetMotionUnit(180, 180);

    s = "你好";
    POS_S_TextOut(s);
    POS_FeedLine();

    s = "123abc";
    POS_S_TextOut(s);
    POS_FeedLine();

    s = "666";
    POS_S_TextOut(s);
    POS_FeedLine();
    POS_FeedLine();

    POS_OutQRCode();

    //s = "777";
    //POS_S_TextOut(s);

    POS_FeedLine();
    POS_FeedLine();

    POS_FeedLine();
    POS_FeedLine();

    POS_CutPaper();




    return 0;
}

打印效果:

这里写图片描述

展开阅读全文

没有更多推荐了,返回首页