注:本文为原创文章,转载时请注明转载地址。
在很多应用程序中都需要用到pc机与外部设备如:嵌入式系统、传感器、开关设备等进行数据通讯。其中,最常用的接口就是RS-232串口和并口。SUN的CommAPI分别提供了对常用的RS232串行端口和IEEE1284并行端口通讯的支持。
至于java串口通讯的配置以及通讯模式在sun的demo以及网上都有很多具体的实例。
下面是我在开发一个叫号功能模块时通过串口通信来控制LED显示的实例,由于第一次进行相关的开发,看似一个非常简单的功能在实际开发中却遇到了一些问题,希望本人的解决方式能够对大家有所帮助,也希望大家能够提出更好的解决方式。
先看一下LED显示屏厂商提供的通讯协议:
---遥控单双色、单双行、混合屏
一、 每一次对任一特定地址发送信息由内码帧(7f/7e),数码帧
(6f/6e),定时帧(5f),时间帧(4f)中的一种或多种构成,结束
时发送一结束帧。
二、帧结构:每帧由84字节构成。
1、 内码帧:一幕由一起始帧和零或多个中间帧组成,一次
发送可有多幕。
1) 起始帧:地址(1字节)+帧控制7F(1字节)
+幕号(1字节)+COMMAND(8字节)
+内码/ASCII(73字节)
2) 中间帧:地址(1字节)+帧控制7E(1字节)+
幕号(1字节)+COMMAND(8字节)+内码/ASCII
(73字节)
3)COMMAND:
前4字节未定义,后4字节依次为动画(0~4), 移入及移出(各16种),速度(0~255),追加
(D3连续、D2停止、D0闪烁、D4时间、D6暂停、
D7动画)
4)内码/ASCII结构:
a、 内码4字节,依次为控制字节(D7宽体/正常体、 D4绿色、D5红色、D3粗体、D2细体反白、D1
粗体反白、D0细体),内码高位,内码低位,未用
b、ASCII 2字节,依次为控制字节(D7宽体/正常体、 D5绿色、D4红色、D3粗体、D2细体反白、D1粗体
反白、D0细体),ASCII码
2、数码帧:由一起始帧和零或多中间帧组成。
1) 起始帧:地址(1字节)+帧控制6F(1字节)+
数据(82字节)
2) 间帧:地址(1字节)+帧控制6E(1字节)+
数据(82字节)
3、定时帧:由一帧组成。
起始帧:地址(1字节)+帧控制5F(1字节)+
数据(48字节)+无效数据
包括8个定时器,每个6字节,结构如下:
开/关(0为OFF、1为ON),日期(0~6为
sunday~satday、7为每一天),小时(0~23),
分钟(0~59),起始幕,结束幕。
4、时间帧:由一帧组成。
地址(1字节)+帧控制4F(1字节)+年高二位
(1字节)+年低二位(1字节)+月(1字节)+日
(1字节) +时(1字节)+分(1字节)+星期(1字节)
+无效数据
日期都用十进制表示,星期部分0为星期日。
4、结束帧:由一帧组成。
地址(1字节)+帧控制7D(1字节)+无效数据(82 字节)
3)移入,移出模式:各16种模式,可任意组合。
三、 移入模式: 移出模式:
模式0:移入← 移出←
模式1:移入→ 移出→
模式2:移入↑ 移出↑
模式3:移入↓ 移出↓
模式4:跳入← 跳出←
模式5:展开→ 展开→
模式6:展开← 展开←
模式7:展开↑ 展开↑
模式8:展开↓ 展开↓
模式9:展开←→ 展开←→
模式10:展开→← 展开→←
模式11:展开↑↓ 展开↑↓
模式12:展开↓↑ 展开↓↑
模式13:即入 即出
模式14:预备 预备
模式15:随机(已设为循环)随机(已设为循环)
四、通讯卡接口:
1)初始化通讯卡:
a、将0xFF写入地址211H
b、从211H读入一字节,判断D3是否为‘1’,如为 ‘0’则重复此步骤
c、将0x00写入地址211H
d、从211H读入一字节,判断D3是为‘0’,如为 ‘1’则重复此步骤
e、初始化完成
2)写入数据地址:210H
3)读状态地址:211H
状态标志:D0写允许,高电平有效
注:未使用字节必须置为0X00.
232口: 8位数据位, 1位停止位, 无效验位, 波特率为9600.
* 每帧84字节, 每幕发一个7F帧, 超过18个字的条屏, 每幕需加发一个7E帧,
所有幕发完后,发7D帧(结束帧)
串口通讯涉及到的部分主要代码:
import java.io.*; import javax.comm.*; public class SerialBean { static SerialBean bean; String PortName; CommPortIdentifier portId; SerialPort serialPort; OutputStream out; InputStream in; public String getPortName() { return PortName; } public void setPortName(String portName) { PortName = portName; } private SerialBean(int PortID) { PortName = "COM" + PortID; } public static SerialBean getInstance() { if (bean == null) { if (!portInit(1)) return null; } return bean; } public static boolean portInit(int port) { if (bean != null) { bean.ClosePort(); } bean = new SerialBean(port); return bean.initialize(); } public boolean initialize() { try { portId = CommPortIdentifier.getPortIdentifier(PortName); try { serialPort = (SerialPort) portId.open("SerialBean", 3000); } catch (PortInUseException e) { e.printStackTrace(); return false; } try { in = serialPort.getInputStream(); out = serialPort.getOutputStream(); } catch (IOException e) { return false; } try { serialPort.setSerialPortParams(9600, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE); } catch (UnsupportedCommOperationException e) { e.printStackTrace(); return false; } } catch (NoSuchPortException e) { e.printStackTrace(); return false; } return true; } public void writePort(byte[] bytes) { for(byte b:bytes){ writePort(b); } } public void writePort(byte b) { try { out.write(b); out.flush(); } catch (Exception e) { e.printStackTrace(); } } public void ClosePort() { if (out != null) { try { out.close(); in.close(); } catch (Exception e) { e.printStackTrace(); } } serialPort.close(); } }
向LED发送数据代码,以下测试代码将大部分涉及到通讯协议中的模式以及指令都写死在程序中,有必要可以进行重构
static int number = 0; static byte target = 0x00; static byte font = (byte) 0; //默认字体 static int LED_LENGTH = 16; //默认LED显示字体数目(汉字) static byte MODULE=0x00; //默认模式 static byte[] beg = new byte[]{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; byte[] end = new byte[]{0x7D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; public void display(String meg) { SerialBean sb = SerialBean.getInstance(); int bytes = LED_LENGTH * 4; writeNext(sb); //汉字在LED中显示所占的宽度是字母或者数字的2倍,以下进行区分 for (int i = 0; i < meg.length(); i++) { String s = meg.substring(i, i + 1); byte[] b = s.getBytes(); if (b.length == 2) { if (bytes < 4) { for (int n = 0; n < bytes + 73 - LED_LENGTH * 4; n++) { sb.writePort(0x00); } bytes = LED_LENGTH * 4; writeNext(sb); } sb.writePort(font); sb.writePort(s.getBytes()); sb.writePort(0x00); bytes -= 4; } else if (b.length == 1) { if (bytes < 2) { for (int n = 0; n < bytes + 73 - LED_LENGTH * 4; n++) { sb.writePort(0x00); } bytes = LED_LENGTH * 4; writeNext(sb); } sb.writePort(font); sb.writePort(meg.charAt(i)); bytes -= 2; } } for (int n = 0; n < bytes + 73 - LED_LENGTH * 4; n++) { sb.writePort(0x00); } sb.writePort(target); sb.writePort(end); sb.ClosePort(); } private void writeNext(SerialBean sb) { sb.writePort(target); sb.writePort(0x7F); sb.writePort((byte) number++); sb.writePort(beg); sb.writePort(MODULE); }
以上代码刚开始写完后进行测试认为基本上没有问题,但是一测试却发现LED上没有任何反应,刚开始以为没有将数据发送过去,采用一些串口监测工具却发现数据已经发送成功;在网上也没有查到任何资料,后来折腾了半天突然想到是不是电脑数据发送太快导致LED中处理数据时导致丢失数据帧,于是立马在发送每个字节后加了一个时间延迟,结果立马有反应,后来适当调节延迟时间一切ok。
public void writePort(byte b) {
try {
out.write(b);
out.flush();
Thread.sleep(10);
} catch (Exception e) {
e.printStackTrace();
}
}
(后来想了一下,LED处理数据时可能采用缓存操作,当pc向其发送信息时首先发送至缓存区域,LED此时读取缓存开始处理数据,但是如果pc发送信息太快以致led还没有处理完数据并且数据的大小超出了LED的缓存区域,那么此时可能就会出现将早先的数据进行覆盖的问题,以上只是猜测,后来程序调试好了也没有再理会)
发布日期:2008-1-11 9:11:00 发布者:[IT电子教育门户] 评论:[ 0] 浏览: 1246
不少人为自己是Java开发者中的一员而感到骄傲,新年伊始,大家一定对这个与自己息息相关的语言和平台有不少的期待。以下为2008年Java开发者五个最迫切的期待,可能其中有不合你意者,但相信大多数Java开发者会对此认同:
JavaFx不再只是空谈
在2007年的JavaOne上,我们听到了一个救世主——JavaFx,不幸的是,当初的所有许诺却没有成为现实。希望2008它能成为一个真正的、简单的、可用选择,从而Java开发者不必在富交互技术领域无“本宗”技术可选。
Glassfish成为应用服务器的选择
Glassfish是一款非常好的开源应用服务器和平台,也是第一个遵从Java EE 5标准的,它强大而有效。然而在企业端它还不被熟知,许多企业主管甚至从未听说它。即使Java开发者,很多也从未下载使用过,甚至部分人还没有用就在印象中觉得它不够正规。希望2008年开发者能够有效利用它。
重量级/轻量级(Lightweight/Heavyweight)之争当停止
由于Java EE正不断吸取各种框架、工具、库等的优点,开发方法变得更加直接和简单,所以传统的所谓的重量级Java和轻量级之间的区别也越来越模糊。然而此间关于重量级和轻量级的争论仍未停止。
Google青睐Java,希望Apple也能
iPhone非常风靡而且许多iPhone应用正在开发,然而迄今Java仍然是iPhone的毒药,希望08年这一局面可以改观。Google已经通过它众多的Java API和服务帮助了全世界的Java开发者,这也再一次证明,强者用之则发扬广大。所以希望包括Apple在内的更多强者可以用Java.
弃糟粕、大统一
凭借Java的枝繁叶茂,再复杂的任务Java都可以提供很好的解决,然而它也因为自身分支和技术的太过丰富而使开发者迷乱。Java开发者花费了几年时间去弄清楚一大堆商业和开源框架、工具、库……希望在2008年,其中的一些可以被废弃。虽然专政(指Java统一)是有害的,但一个统一的领土有更多的优势。
Definition of: AT command set
1)A series of machine instructions used to activate features on an intelligent modem. Developed by Hayes Microcomputer Products and officially known as the Hayes Standard AT Command Set, it is used entirely or partially by most every modem manufacturer. AT is a mnemonic code for ATtention, which is the prefix that initiates each command to the modem.
2)Also known as the Hayes Standard AT Command Set. A language that enables PC communications software to get an asynchronous and "Hayes-compatible modem" to do what you want it to do. So called "AT" because all the commands begin with "AT," which is short for ATtention. The most common commands include ATDT (touchtone a number), ATA (manually answer the phone), ATZ (reset modem — it will answer OK), ATSO=O (disable auto-answer), and ATH (hang up the phone).
See more reference:
http://en.wikipedia.org/wiki/AT_command
http://en.wikipedia.org/wiki/Motorola_Phone_AT_Commands
See : http://www.pcmag.com/encyclopedia_term/0,2542,t=Hayes+Smartmodem&i=44139,00.asp
Definition of: Hayes Smartmodem
A family of modems developed by Hayes, which was the industry leader for many years (see
Hayes
). Hayes developed the "intelligent modem" for the first personal computers in 1978, and its command language became the de facto standard for modem control (Hayes Standard AT Command Set).
Two States of Operation
An intelligent modem has a command state and an online state. In the command state, it accepts instructions. In the online state, it dials, answers, transmits and receives.
Handshaking
Once connected, the modem performs the handshaking with the remote modem, which are the whistles and tones you hear from the speaker. This is similar to the opening exchange of a human telephone call: called party says "hello;" calling party says "hello, this is..."; after that, the conversation begins. After the handshake is completed, you are online with the other computer, and data can be transmitted back and forth.
Escape Sequence
The escape sequence tells the modem to switch from online to command state. It consists of three plus signs in sequence (+++) with a Hayes-patented, one-second guard time interval before and after, which prevents the modem from mistaking a random occurrence of plus signs for an escape sequence. The escape sequence and guard time interval can be programmed in the modem's status registers.
To issue an escape sequence, hold down the shift key and press + three times with a pause of at least one second before and after the sequence. The modem will return the OK result code, indicating it is ready to accept commands.
See: http://en.wikibooks.org/wiki/Serial_Programming:Modems_and_AT_Commands
What is Hayes?
Hayes Microcomputer Products, Inc. was a modem manufacturer from the beginning of the 1980s until the end of the 1990s, with its heyday in the early '90s. The name Hayes still exists as a brand name, owned by Zoom Telephonics, Inc. (as of Fall 2004).
In 1981, Hayes developed the Hayes Smartmodem . This was a unique product at the time, because this modem was no longer simply a "dumb" device blindly converting serial data to and from audio tones, but contained some "intelligence". It was possible to send commands to the modem to configure it, to execute certain operations (such as dialing a number, quieting the speaker, hanging up, etc.), and to read the current status of the connection. Hayes developed and published a command set to control the modem over a serial line. This command set became popular among consumer modem manufacturers, and was cloned a thousand times. Known as both the "Hayes command set" and the "AT command set", it has long been the de-facto standard for controlling consumer modems and also many professional modems. Modems which support this command set are called Hayes-compatible .
The commands were standardised at some point in time, however, as it is typical with standards, there are several standards. Plus, of course, there are still vendor-specific extensions and implementations in different modems vary slightly. Some of these enhancements were required to support at that time emerging features, such as data compression and FAX support. As a result, the command sets of modern modems are not fully compatible with each other. The original Hayes commands, however, should still work, and still form the core of almost all consumer modem command sets.
The basic set of commands was at some point in time standardised as TIA/EIA-602 and the syntax as EIA/TIA-615. But as already mentioned, modem manufacturers added their extensions. A larger extended set, particular under the presure from cell phone manufacturers, was standardised as ITU V.250 (old name V.25ter). That one usually forms the base for professional Hayes-compatible modems, and cell phones with build in data modems. ITU V.250 further referes to a bunch of other standards (e.g. V.251, V.252, V.253) for particular applications and extensions, and also has some suplements. Plus, of course there are the many standards defining other aspects of a modem, like compression and transmission.
What are AT Commands?
Almost all of the Hayes modem commands start with the two letter sequence AT - for getting the modem's attention . Because of this, modem commands are often called AT Commands . This still holds for many of the manufacturer specific command set extensions. Most of them also start with AT , and are called AT Commands , too. Please note, that just because an AT command contains a & does not make it an extensions. & commands were already part of the original Hayes command set.
The exact usage of the term AT command set slightly varies from manufacturer to manufacturer, often subject to marketing blurbs. In general, it can be assumed that a modem with an AT command set
- uses commands mostly starting with AT ,
- uses the original Hayes way of separating data and commands, and
- supports the original Hayes commands and register settings as a subset.
What is a Modem?
A modem in the classic sense is a mo dulator/dem odulator for transmitting digital information over analog wires, such as the analog telephone system's two-wire or four-wire lines. The term has come to be used as acceptable slang for many communication devices used to link a computer to either another computer, or a wide-area network ( Wikipedia:WAN ). For example, the Ricochet radio data transceivers were commonly known as "Ricochet modems".
This module deals with the classic type of smart modems, designed to convert data from/to a serial interface to/from an analog line. The module also applies to modems which provide the classic serial interface but connect over a different physical layer, such as a digital line, as well as devices providing a serial modem-like interface for other purposes. For our purpose, the modem is a classic DCE (data communications equipment) device, controlled via serial line by a classic DTE device (such as a computer).
Depending on the type of modem, the modem can use a number of different technologies and speeds to transmit the data over the analog line. The details of these technologies are of no particular interest here, other than to note that it is possible with most modems to specify these communication parameters (for example, to disable compression, or to change modulation techniques). The data this module deals with is not the data on the analog line, but the data as it appears on the serial interface between the DTE and DCE.
(Smart ) Modems also provide auxiliary services, such as dialing a particular number to set up a connection. As a consequence, a modem can be in a number of different states and modes, which are not always orthogonal. It is possible, for example, for a modem to be in the command mode while still keeping a connection (see the +++ sequence for details).