一个通过java串口通信控制LED显示数据的实例
串口通讯涉及到的部分主要代码:
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的缓存区域,那么此时可能就会出现将早先的数据进行覆盖的问题,以上只是猜测,后来程序调试好了也没有再理会)
?
1 楼 yangyiqian 2008-05-06 兄弟,好久就想看这方面的资料了,大哥在这谢了! 2 楼 dopic 2008-12-25 good