引言
随着Internet的高速发展,通信工具日益更新,传真凭借其具有凭证确认、快速、方便等特点,是企业不可或缺的通信工具。传统硬件传真机存在很多问题,影响了企业使用传真机的成本和效率。很多企业已经放弃使用传统传真机,或是寻找替代产品。无纸传真系统正是针对企业的这种需求应运而生的。其实质是电子化收发传真。无纸化传真系统启动后,在无人参与条件下可自动可靠地运行,减少多余的环节,缩短信息的传递时间,使传真尽快得到处理。同时,增强了传真的保密性。电子化过程可以节省大量资源,包括人力、纸张、打印、通信费用、维护费用等,从而减少成本。目前无纸化传真系统对企业的重要作用已经逐步显现,使用也越来越广泛。
1 传真协议介绍
T.30协议为PSTN网上的传真传输协议与规程,是标准传真。它对3类传真机在普通电话网上的通信流程、所采用的信号格式、控制信令以及纠错方式都作了详细的描述和规定。该协议规定了8种可能的操作方式,每种操作方式均可用5个独立而又连贯的阶段来描述:呼叫建立阶段、报文传输前标识和选择所需性能的过程、报文传输阶段、报文后处理阶段和呼叫释放阶段。其中传真报文的传输将按照T4协议中所描述的调制方式进行。
T4是ITU—T制定的传真协议。该协议用于3类传真终端文件传输的标准化协议。它定义了黑白文件和彩色文件在普通电话交换网,国际租用电路以及ISDN进行三类传真的各种特性,包括编码、线扫描等定义。
2 μC/OS-lI操作系统介绍
μC/OS-II是一种公开源代码、结构小巧、具有可剥夺实时内核的实时操作系统。μC/OS-II大部分代码是用C语言编写的。CPU硬件相关部分是用汇编语言编写的。总量约200行的汇编语言部分被压缩到最低限度,为的是便于移植到其他的CPU上。用户只要有标准的ANSI的C交叉编译器、汇编器、连接器等软件工具,就可以将μC/OS-II嵌入到开发的产品中。μC/OS-II具有执行效率高、占用空间小、实时性能优良和可扩展性强等特点。最小内核可编译至2KB。μC/OS-II操作系统已经移植到了大部分知名的CPU上。
3 传真数据处理的算法设计
收到传真数据后,往往需要对数据进行解析,比如生成tiff文件、格式转换、错误统计等。由前文所述,T.4协议中规定了传真数据采用前缀编码,所以本文采用霍夫曼树进行数据解析。
霍夫曼算法一般用于数据压缩,基本思想是根据数据的统计频度,生成一种带权路径长度最短的二叉树。从根节点到叶子节点所经历的路径即代表该叶子节点的编码。本文采用了这种思想对传真数据进行解析,比如N的编码为0001,该编码为前缀编码,每个码字之间不会出现混淆。霍夫曼二叉树如图1所示。
μC/OS-II" p="" src="http://files.chinaaet.com/images/20110920/b1968d59-0df6-4b18-bb55-99f63123ee24.jpg" title="μC/OS-II" />
基于霍夫曼树的思想,将T.4协议中对传真扫描点的编码构建成一颗带权二叉树,如图2所示。
其中每一个叶子节点对应于某一个编码,首先设置一个游标,用于标识当前位置,其初始位置为根节点,收到传真数据后,根据数据中的bit位移动游标,可能有以下3种情况:
①游标到达某一个叶子节点,但此叶子节点不是EOL,表明收到一个完整的编码,但1行还没结束,游标返回到根节点;
②游标到达EOL叶子节点,表明1行结束,游标返回根节点;
③游标下一步没有路径可走,表明数据出错,此时需要搜寻下一个EOL用于重新同步。
4 无纸传真收发系统设计
4.1 基本模式
按照T.30协议规定,文件传真在公用电话交换网上的传输操作方法可能有8种组合,如表1所列。本文设计的系统采用的操作方法为4-T,即主叫站与被叫站均为自动操作,主叫站作为传真的发送方,被叫站作为传真的接收方。
4.2 硬件框架
整个传真系统的硬件框图如图3所示。左侧虚线框内模块和右侧的FAX模块是从交换机的两根电话线中分离出来的2个独立传真模块。右侧的FAX模块是普通纸传真机,为测试左侧虚框内模块的功能而配置的。左侧虚线框内4大模块为无纸传真模块。
无纸传真模块中,左侧的PC机为辅助设备,利用PC机上的集成开发调试环境IAR和代码编辑软件sourceinsight进行源码编辑与调试,将调试无误的代码通过JLINK下载到STM32芯片中。STM32芯片和Fax Modem都是通过USB线与PC机相连来供电。
Fax Modem内部包含CX68033芯片,其通过串口与STM32芯片相连,支持标准的AT命令集,使得二者可以交互信令和数据,STM32芯片主要负责任务管理和文件管理,并且通过串口控制Fax Modem。同样为了便于测试,焊了一根线接出“USB转串口模块”来与电脑通信,进而可以利用串口调试助手软件来辅助测试。
4.3 总流程设计
两台传真机相互通信的规约称为协议或传真呼叫时间序列,分为A、B、C、D、E五个阶段,如图4所示。
(1)阶段A:呼叫建立阶段
这一阶段与电话呼叫建立的过程相似,不同之处在于要发送包含标识发送/接收终端的传真单音。
(2)阶段B:报文前处理阶段
这个处理阶段主要进行传真能力的协商与训练。完成传真机功能的鉴别、选送合适的传输模式、核对相位、发送线路校验信号以及可以接收的信号等。
过程描述:首先由被叫站发送DIS信号,DIS信号中包含了被叫站传真机具有的各种兼容性功能信息、传输数码率、扫描线密度和最小行扫描时间等。当主叫站收到DIS信号后,了解到被叫站传真机的功能,再根据本站传真机的功能和操作人员事先安排的指令,发出DCS信号,DCS信号是数字接收指令,由发送方进行发送,要求接收方是接收传真。该指令还指定了接收传真机的工作方式、传输数码率、扫描线密度、稿件宽度以及最小行扫描时间等。被叫站接收到DCS信号后,按命令选择合适的工作模式,这时,主叫站发出线路校验信号TCF。TCF信号是一个持续时间为1.5s的0序列,它用于校验信道在这个数码率下可接受的程度。当被叫站收到这个线路校验信号之后认为合格,就发送CFR信号,CFR信号标志全部报文前处理过程已经结束。当主叫站收到CFR信号,就可以发送稿件。
(3)阶段C:报文传输过程
按照T.4规程传输传真报文,并进行报文传输控制,包括报文同步、误码检测和纠错、线路监测等。
(4)阶段D:报文后处理阶段
这个处理阶段主要提供报文的证实、报文结束、多页续发等控制操作。当发送方发完稿件后,将出现若干不同的情况,如是否还要继续向接收方发送稿件,如果需要发送,是继续发送还是重新进行报文前处理后再发送,是否暂时中断进行通话后再发送等。为了满足上述要求,发送方共设置6种主要的传真控制字段分别对应6种指令。当接收方收到这6种指令中的一种后,就会发出响应信号,这些指令和响应只有传真控制字段,而无传真信息字段。
(5)阶段E:呼叫释放阶段
呼叫释放发生在某一特定的条件下,当最后一页稿件发送完毕后,进行最后一个信息处理,发送EOP信号,在EOP信号之后,过程转入阶段E,呼叫释放,切断接续,电路由传真状态返回到电话状态。
图5是单页传真正常传输的一个实例,便于传真流程的理解。
4.4 功能模块设计
本设计自底向上包括如下3个功能模块,如图6所示。底层串口模块、中层数据缓冲区模块和上层传真模块。各个模块由μC/OS-II负责管理,其中底层串口模块包含了所有基于串口的基本操作,包括读串口和写串口等;中层数据缓冲区模块做了大量的细节性数据处理工作;上层传真模块封装了发送传真和接收传真的基本功能。
4.4.1 底层串口模块
底层串口模块的代表性函数包括如下3个。
①void RxInterrupt_Handler();
功能说明:fax modem每次接收到数据后都会发生中断,跳入此函数。通过mdm_append_data函数将串口收到的新数据添加到接收缓冲区。
②void USART1_SendByre(INT16U byte);
功能说明:直接向串口中发送一个字节,并等待完成。
③void USART1 SendData(INT8U*data,INT16S len);
功能说明:直接向串口写数据并等待完成,数据长度不限。它被fax_send_cmd函数和fax_send_frame函数多次调用。
4.4.2 中层数据缓冲区模块
本模块采用队列来管理数据,如图7所示。底层串口模块收到数据后,将数据存入队尾缓存,上层传真模块从队头取出数据进行处理,这种方式使得程序不必关心串口接收数据的方式,一定程度上减小了程序的耦合性。
队列的数据结构定义如下:
本模块提供了以下接口函数,供上层传真机模块调用。
①void mdm_init_buffer();
功能说明:本函数用于初始化缓冲区,一般在程序启动时调用。
②char*mdm_get_line(int timeout);
功能说明:在timeout规定的时间里面,等待并读取一行数据(以/r/n结尾),如果超时则返回NULL。
③int mdm_get_byte(char*byte,int timeout);
功能说明:在timeout规定的时间里,等待并读取一个字节的数据,如果有数据则返回1,如果超时则返回0。
④int mdm_get_byte_count();
功能说明:获取当前缓冲区内的数据量,单位为字节。
⑤void mdm_clear_buffer();
功能说明:清空缓冲区的数据。
⑥void mdm_append_data(char data);
功能说明:向缓冲区队尾添加一个数据,该函数在串口接收中断中被调用。
4.4.3 上层传真模块
上层传真模块分为发送传真接口和接收传真接口两大部分,其中发送部分为1个集成的函数,而接收部分为3个按时序相接的功能分支。
(1)发送传真接口
原型说明:im fax_send(char*num,char*page[]);
功能说明:发送传真,对端的传真号为num,传真文件通过page变量传入,结尾以NULL指针或空字符串结尾。
(2)接收传真接口
①int faX_ringing();
功能说明:循环检测并接收响铃,只有接通了,才会跳出循环。该函数可以在一个task里面调用,进行传真监听,当收到“RING”时,退出函数,等待应答。
②int fax_answer_and_connect();
功能说明:传真应答与连接。该函数一般在收到“RING”时调用。当连接成功后,即可接收传真。
③int fax_receive(int*pagenum,char*dir);
功能说明:接收传真,收到的传真页数为pagenum,保存地址为dir。只有当连接成功后才能调用该函数。
4.5 传真接口调用示例
结语
本文对无纸传真进行了研究,在该研究的基础上开发出一套实用的系统,其扩展性强,具有很好的移植性。一般的传真机仅限于纸质文件的传输,而本系统则辅助实现了纸质文件与电子版文件的转化传输。本系统存在的意义在于,用户可以将此传真模块作为一个独立功能单元集成到其他产品中,以较低的成本来增加产品的功能。
作者:张聪敏 刘军 刘福良 游向东 来源:单片机与嵌入式系统