单片机 并口 控制爱普生打印机开发流程记录 您所在的位置:网站首页 并口控制软件 单片机 并口 控制爱普生打印机开发流程记录

单片机 并口 控制爱普生打印机开发流程记录

2024-06-21 06:08| 来源: 网络整理| 查看: 265

最近做一个项目,需求是通过昆仑通态的组态触摸屏作为上位机监测数据,然后将数据整合最后打印报表输出。昆仑通态以前可以直接将预览页的所有数据都打印出来,包括整屏未显示完全的。但是现在昆仑通态将WIN平台换为Linux了(据说是因为版权授权问题),于是就没有这个功能了。因为需求量不够,也不能获得厂家的直接支持,于是只能想办法通过自己下位机去驱动打印机,直接完成数据的打印输出。

市面上目前主要是惠普与爱普生打印机用得比较多,都有USB与并口两种接口,因为通过USB控制需要单独协议,对电路的外围设计与程序编写都麻烦许多,于是打算用并口。其实并口好像是专门为打印机而生的,爱普生的针式打印机还保留并口。

最后选用了爱普生的LQ-630II,查询资料,其使用的是ESC语言。

问题1:单片机如何与打印机通过并口连接起来?

答:打印机的并口线分为两端,一端连接打印机36针,一端连接PC或者单片机等控制端25针,这里作为控制端操作我们就只关心25针接口。

25针控制端接线说明如下:

PCB电路设计接线说明:

问题一总结:

1.25针接线并没有完全用到,

引脚18~25:8根引脚都是GND。

引脚1:STB,作为数据选通,也就是当STB从高电平变化为低电平时,数据引脚的数据才会被打印机读取,也就是告诉打印机数据已经准备完成,可以读取。

引脚14:FEED,自动进纸与否,控制端控制打印机状态。

引脚15:ERROR,打印机出错与否,控制端读取打印机状态。

引脚16:INIT,硬件上重启打印机,大于50us的低电平就将重启打印机,回到初始状态,比如清除打印机缓存区。

引脚11:BUSY,打印机忙标志位,高电平表示打印机正在处理数据,不能接收新的数据,直到变为低电平为止。

引脚10:ACK,我暂时没用到。

引脚2~9:共8位作为并口数据传输位,也就是一次传输8位数据(1byte)。

注意:

1.也就是说其实我们只需要 STB、BUSY、DATA 几组引脚就可以控制打印机了。

2.各个引脚上拉电阻不能少!

问题2:控制端的数据是如何到达打印机的?

答:

1.并口8根数据线赋值需要发送的数据,比如0x80。

2.判断BUSY引脚状态,是否空闲,若忙则等待。

3.空闲状态时,STB从低电平到高电平脉冲,告诉 打印机可以读取数据了。

4.打印机获取数据存于打印缓冲区,遇到换行或者回车数据,或者缓存区满则自动打印数据。

问题3:一个8位数据如何发送给打印机?

答:

1.其实就是前面问题2的解读过程,具体代码我在测试阶段使用了死循环while来等待BUSY空闲,这样保证数据不丢失,每个字节都要等待打印机接收到。

void printByte(unsigned char ch){ while(P_BUSY); P_DATA = ch; printDelay(500); P_STB = 0; printDelay(1000);//延时保证 STB > 1um P_STB = 1; printDelay(1000);}

2.其实很明显,上面的死循环在操作系统使用多线程还可以,如果是纯单片机那就是完全不能用的,所以后来改进了一下,采用轮训方式,发送成功返回1下次发送下一个数据,失败返回0并且下次继续发送该数据。

unsigned char printByte(unsigned char ch){ if(0 == P_BUSY) { P_DATA = ch; printDelay(500); P_STB = 0; printDelay(1000);//延时保证 STB > 1um P_STB = 1; printDelay(1000); return 1; } return 0;}

问题4:一次发送多个数据是如何操作的?需要注意些什么?

答:

1.首先是前面提到的数据到达打印机过程,也就是先解决了发送一个字节数据的问题(见问题3过程)。

2.其实多个字节发送的实质也是一个个字节发送的,第一个字节发送完成,判断忙状态,空闲则继续发送下一个字节。

3.为了保证每一个数据都到达打印机,不存在控制端发送了,不管打印机是否正确接收。我想的方法是:用一个本地BUF将我这次需要发送的N个字节数据一次存入其中,给一个从0开始的BUF下标计数值,采用轮训去发送该BUF,每次发送成功则下标加1,即发送下一个数据,否则下标保持不变,继续发送该数据。

#define _PRINT_BUF_NUM_ 250unsigned int Print_Sign = 0;unsigned char Print_Buf[_PRINT_BUF_NUM_]; ////将指定一字节数据存入Print_Buf中,其存入数据个数与下标对应void PrintDataToBuf(unsigned int *dataAddr, unsigned char byte){ if((*dataAddr) < _PRINT_BUF_NUM_) Print_Buf[(*dataAddr)++] = byte;}//将指定字符串存入Print_Buf中,注意不能包含0x00,字符串会自动切断void PrintDataToBufs(unsigned int *dataAddr, unsigned char mydata){ unsigned int i = 0; for(i = 0;i < strlen(mydata);i++) { if((*dataAddr) < _PRINT_BUF_NUM_) { Print_Buf[(*dataAddr)++] = mydata[i]; } }}

问题5:这两个函数怎么使用的?

答:

1.主函数中对命令等数据操作都是一个一个存入BUF中的,而对于字符串则使用第二个函数一次存入。

#define _GJJLBB_ "打印测试内容\r\n" Print_Sign = 0;//每次存入前复位下标,表示从0开始 //设置左边界 PrintDataToBuf(&Print_Sign, 0x1B); PrintDataToBuf(&Print_Sign, 0x6C); PrintDataToBuf(&Print_Sign, 0x01); //设置下划线 PrintDataToBuf(&Print_Sign, 0x1C); PrintDataToBuf(&Print_Sign, 0x2D); PrintDataToBuf(&Print_Sign, 1); PrintDataToBufs(&Print_Sign, _GJJLBB_); //真实打印数据 //取消下划线 PrintDataToBuf(&Print_Sign, 0x1C); PrintDataToBuf(&Print_Sign, 0x2D); PrintDataToBuf(&Print_Sign, 0); PrintDataToBufs(&Print_Sign, "\r\n"); //打印机遇到回车换行才回去马上打印出来 RowDataCombinationOK = 1; //本次数据组合完成,需要开始打印标志

2.到这里有没有发现,我本次需要打印的数据都存在Print_Buf中,从下标0开始,一共存入了多少数据呢?其实就是Print_Sign的值,因为传入的指针,所以每次存数据后其值也会对应改变。

问题6:数据已经存入BUF中,个数也已经知道,如何轮训发送给打印机呢?

答:

1.关键步骤如下,具体在哪里轮训需要根据你自己的程序需求。

//PrintDataReadAddr 是从0 开始的读取BUF数据的下标地址//Print_Sign代表本次BUF中一个有多少数据if(PrintDataReadAddr < Print_Sign){ //BUF中读取数据下标地址与其当前读取成功的个数相等,也就是读取地址==打印机获取个数,则代表读取后已经写入打印机,下次可以读取下一个数据。 if(PrintWriteNum == PrintDataReadAddr) { PrintWriteNum++; readPrintBufData = Print_Buf[PrintDataReadAddr]; } //将读取值发送给打印机,成功才累加读取地址 if(printByte(readPrintBufData)) { PrintDataReadAddr++; }}//本次一行数据写入完成else{ PrintRowOK = 1; //该标志位用于允许新的数据写入BUF中,本次读取完全才能重新写入新的数据,从0地址开始。}

问题7:上位机有很多数据需要发送给打印机打印,怎能操作呢?

答:

1.打印机是接收到一行数据(若该行数据中包含回车换行则自动立即打印),否则需要等待打印机的缓存区满才自动打印。

2.LQ-630II打印机缓存区 32K。

3.为了保证打印机每次完整打印一行数据后再去打印下一行,我们使用的是应答方式,也就是下位机作为直接驱动打印机的控制端,在打印机完成一行打印后主动请求下一行数据,上位机收到新的数据请求后将数据发送给下位机。这中间最重要的是通讯协议中需要定义行标志,上下统一,从而保证请求与接收数据的唯一性。

总结:下位机需要打印第一行,则向上位机发送1,上位机收到1则将第一行数据按照特定格式与编号1一起发送给下位机,下位机收到1与自己请求编号1相同,则获取该消息后的数据包,解析数据,打印出来。接着将请求编号设置为2,去请求第二行数据,依次类推。

目前已经完成所有打印需求,文档更新不够详细,很多具体细节有需要的可以留言讨论。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有