发新话题
打印

Java串行端口技术协议

Java串行端口技术协议

串行通讯慨述
  串行通讯协议有很多种, 像RS232, RS485, RS422, 甚至现今盛行的USB等都是串行通讯协议。 而串行通讯技术的应用无处不在。 能够大家见的最多就是电脑的串口与Modem的通讯。 记得在PC机刚开始在中国盛行起来时(大约是在90年代前五年), 那时甚至有人用一条串行线停止两台电脑之间的数据共享。 除了这些, 手机, PDA, USB鼠标、键盘等等都是以串行通讯的方式与电脑衔接。 而笔者工作性质的关系, 所接触到的就更多了, 像多串口卡, 各种品种的具有串口通讯接口的检测与测量仪器, 串口通讯的网络设备等。
  虽然串行通讯有很多种, 但笔者所知的在整个电子通讯产品方面, 以RS232的通讯方式最为多见。 虽然USB接口的电子产品也是层出不穷, 但了解一下Java在串行通讯方面的技术还有有必要的, 说不定有哪位读者还想用此技术写一个PDA与电脑之间数据共享的顺序呢。
  本文主要以RS232为主来解说Java的串行通讯技术。
  RS232通讯根底
  RS-232-C(又称EIA RS-232-C, 以下简称RS232)是在1970年由美国电子工业协会(EIA)结合贝尔系统、调制解调器厂家及计算机终端生产厂家共同制定的用于串行通讯的规范。 RS232是一个全双工的通讯协议, 它可以同时停止数据接收和发送的工作。 RS232的端口通常有两种:9针(DB9)和25针(DB25)。
  罕见的边线方式
  罕见的通讯方式是三线式, 这种方式是将两个RS232设备的发送端(TXD)和接收端(RXD)及接地端(GND)互相衔接, 也是许多读者所知道的衔接方式:
  这种方式分别将两端的RS232接口的2--3, 3---2, 5(7)---5(7)针脚衔接起来。 其中2是数据接收线(RXD), 3是数据发送线(TXD), 5(7)是接地(RND)。 假如有一台式PC, 和一部NoteBook电脑, 就可以用这种方式连线了。 用三线式可以将大少数的RS232设备衔接起来。 但假如你认死了2--3, 3--2, 5(7)--5(7)对接这个理, 会发现在连某些RS232设备时并不奏效。 这是因为有些设备在电路外部已将2和3线调换过来了, 你只需2, 3, 5(7)针逐个对应就行了。
  小技巧:如何区分TXD和RXD端口?
  搞电子的人手边应该常备一个电表, 用来测测电压, 电阻什么的会很有用。 你只需分别测一下RS232端口的2--5或3--5针脚之间的电压, 通常TXD针脚与GND之间会有3~15V左右的负电压, 表示它是TXD针脚。
  装置Java Communications API
  Sun的J2SE中并没有直接提供以上提到的任何一种串行通讯协议的开发包, 而是以独立的jar包方式发布在java. sun网站上(从这里下载)----即comm. jar, 称之为Javatm Communications API, 它是J2SE的规范扩展。 comm. jar并不是最近才有, 早在1998年时, sun就曾经发布了这个开发包。 comm. jar分别提供了对常用的RS232串行端口和IEEE1284并行端口通讯的支持。 目前sun发布的comm. jar只有Windows和Solaris平台两个版本, 假如你需要Linux平台下的, 可以在linuxcomm. html">geeksville/~kevinh/linuxcomm. html找到。
  在使用comm. jar之前, 必须知道如何装置它。 这也是困扰许多初学java RS232通讯者的一个难题。 假如我们电脑上装置了JDK, 它将同时为我们装置一份JRE(Java Runtime Entironment), 通常我们运行顺序时都是以JRE来运行的。 所以以下的装置适用于JRE。 假如你是用JDK来运行顺序的, 请将相应的改成。
  下载了comm. jar开发包后, 与之一起的还有两个重要的文件, win32com. dll和javaxm. properties。 comm. jar提供了通讯用的java API, 而win32com. dll提供了供comm. jar调用的本地驱动接口。 而javaxm. properties是这个驱动的类配置文件。 首先将comm. jar复制到\lib\ext目录。 再将win21com. dll复制到你的RS232应用顺序运行的目录, 即user. dir。 然后将javaxm. properties复制到\lib目录。
  通讯前的准备
  假如你手头上没有现成的提供了规范RS232串口的设备, 你可以将自己的电脑模仿成两台不同的串口设备。 通常电脑主机前面的面板提供了两个9针的串口, 请将这两个串口的2, 3, 5脚按前面介绍的方法衔接。 电子市场都有现成的衔接头卖, 请不要买那种封装的严严实实的接头, 而要买用螺丝封装可以拆开的衔接头, 这样可以方便自己依据需要衔接各个针脚。
  Comm API根底
  我无意于在此详细描述Comm API每个类和接口的用法, 但我会介绍Comm API的类结构和几个重要的API用法。
  一切的comm API位于javaxm包下面。 从Comm API的javadoc来看, 它介绍给我们的只有区区以下13个类或接口:
  javaxm. CommDriver
  javaxm. CommPort
  javaxm. ParallelPort
  javaxm. SerialPort
  javaxm. CommPortIdentifier
  javaxm. CommPortOwnershipListener
  javaxm. ParallelPortEvent
  javaxm. SerialPortEvent
  javaxm. ParallelPortEventListener (extends java. util. EventListener)
  javaxm. SerialPortEventListener (extends java. util. EventListener)
  javaxm. NoSuchPortException
  javaxm. PortInUseException
  javaxm. UnsupportedCommOperationException
  下面解说一下几个主要类或接口。
  1. 枚举出系统一切的RS232端口
  在开始使用RS232端口通讯之前, 我们想知道系统有哪些端口是可用的, 以下代码列出系统中一切可用的RS232端口:
  Enumeration en = CommPortIdentifier. getPortIdentifiers();
  CommPortIdentifier portId;
  while (en. hasMoreElements())
  {
  portId = (CommPortIdentifier) en. nextElement();
  /*假如端口类型是串口, 则打印出其端口信息*/
  if (portId. getPortType() == CommPortIdentifier. PORT_SERIAL)
  {
  System. out. println(portId. getName());
  }
  }
  在我的电脑上以上顺序输入以下后果:
  COM1
  COM2
  CommPortIdentifier类的getPortIdentifiers方法可以找到系统一切的串口, 每个串口对应一个CommPortIdentifier类的实例。
  2. 打末尾口
  假如你使用端口, 必须先打开它。
  try{
  CommPort serialPort = portId. open("My App",  60);
  /*从端口中读取数据*/
  InputStream input = serialPort. getInputStream();
  input. read(. . . );
  /*往端口中写数据*/
  OutputStream output = serialPort. getOutputStream();
  output. write(. . . )
  . . .
  }catch(PortInUseException ex)
  { . . .  }
  经过CommPortIdentifier的open方法可以前往一个CommPort对象。 open方法有两个参数, 第一个是String, 通常设置为你的应用顺序的名字。 第二个参数是时间, 即开启端口超时的毫秒数。 当端口被另外的应用顺序占用时, 将抛出PortInUseException异常。
  在这里CommPortIdentifier类和CommPort类有什么区别呢?其实它们两者是逐个对应的关系。 CommPortIdentifier主要担任端口的初始化和开启, 以及管理它们的占有权。 而CommPort则是跟实践的输入和输入功用有关的。 经过CommPort的getInputStream()可以取得端口的输入流, 它是java. io. InputStream接口的一个实例。 我们可以用规范的InputStream的操作接口来读取流中的数据, 就像经过FileInputSteam读取文件的内容一样。 相应的, CommPort的getOutputStream可以获得端口的输入流, 这样就可以往串口输入数据了。
  3. 封闭端口
  使用完的端口, 必须记得将其封闭, 这样可以让其它的顺序有机会使用它, 不然其它顺序使用该端口时能够会抛出端口正在使用中的错误。 很奇怪的是, CommPortIdentifier类只提供了开启端口的方法, 而要封闭端口, 则要调用CommPort类的close()方法。 CommPort的输入流的读取方式与文件的输入流有些不一样, 那就是你能够永远不知这个InputStream何时完毕, 除非对方的OutputStream向你发送了一个特定数据表示发送完毕, 你收到这个特定字符后, 再行封闭你的InputStream。 而comm. jar提供了两种灵活的方式让你读取数据。
  1. 轮询方式(Polling)
  举个例子, 你同GF相约一起出门去看电影, 但你的GF好装扮, 这一装扮能够就是半小时甚至一小时以上。 这时你就耐不住了, 每两分钟就催问一次“好了没?”, 如此这样, 直到你的GF说OK了才算完。 这个就叫轮询(Polling)。
  在顺序中, 轮询通常设计成一个封闭的循环, 当满足某个条件时即完毕循环。 刚才那个例子中, 你的GF说“OK了!”, 这个就是完毕你轮询的条件。 在单线程的顺序中, 当循环不断执行某项任务而又无法预知它何时完毕时, 此时你的顺序看起来能够就像死机一样。 在VB顺序中, 这个问题可以用在循环结构中拔出一个doEvent语句来解决。 而Java中, 最好的方式是使用线程, 就像以下代码片断一样。
  public TestPort extend Thread
  {
  . . .
  InputStream input = serial文章由 suyin.tk 口碑最好的缩阴产品 整理,收集辛苦,希望能保留出处。
jiyizhen-buy.com颈椎保健枕太空记忆枕 igerl.com歌瑞尔内衣

TOP

发新话题