赞
踩
最近在做自动售货机的程序,需要用到串口,经过几天的时间终于搞明白了,先来个效果图,下面是我发送的数据和接收数据的图片,下面直接上代码:
新建一个类:SerialPortFinder,添加如下代码:
- public class SerialPortFinder {
-
- public class Driver {
- public Driver(String name, String root) {
- mDriverName = name;
- mDeviceRoot = root;
- }
- private String mDriverName;
- private String mDeviceRoot;
- Vector<File> mDevices = null;
- public Vector<File> getDevices() {
- if (mDevices == null) {
- mDevices = new Vector<File>();
- File dev = new File("/dev");
- File[] files = dev.listFiles();
- int i;
- for (i=0; i<files.length; i++) {
- if (files[i].getAbsolutePath().startsWith(mDeviceRoot)) {
- Log.d(TAG, "Found new device: " + files[i]);
- mDevices.add(files[i]);
- }
- }
- }
- return mDevices;
- }
- public String getName() {
- return mDriverName;
- }
- }
-
- private static final String TAG = "SerialPort";
-
- private Vector<Driver> mDrivers = null;
-
- Vector<Driver> getDrivers() throws IOException {
- if (mDrivers == null) {
- mDrivers = new Vector<Driver>();
- LineNumberReader r = new LineNumberReader(new FileReader("/proc/tty/drivers"));
- String l;
- while((l = r.readLine()) != null) {
- // Issue 3:
- // Since driver name may contain spaces, we do not extract driver name with split()
- String drivername = l.substring(0, 0x15).trim();
- String[] w = l.split(" +");
- if ((w.length >= 5) && (w[w.length-1].equals("serial"))) {
- Log.d(TAG, "Found new driver " + drivername + " on " + w[w.length-4]);
- mDrivers.add(new Driver(drivername, w[w.length-4]));
- }
- }
- r.close();
- }
- return mDrivers;
- }
-
- public String[] getAllDevices() {
- Vector<String> devices = new Vector<String>();
- // Parse each driver
- Iterator<Driver> itdriv;
- try {
- itdriv = getDrivers().iterator();
- while(itdriv.hasNext()) {
- Driver driver = itdriv.next();
- Iterator<File> itdev = driver.getDevices().iterator();
- while(itdev.hasNext()) {
- String device = itdev.next().getName();
- String value = String.format("%s (%s)", device, driver.getName());
- devices.add(value);
- }
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- return devices.toArray(new String[devices.size()]);
- }
-
- public String[] getAllDevicesPath() {
- Vector<String> devices = new Vector<String>();
- // Parse each driver
- Iterator<Driver> itdriv;
- try {
- itdriv = getDrivers().iterator();
- while(itdriv.hasNext()) {
- Driver driver = itdriv.next();
- Iterator<File> itdev = driver.getDevices().iterator();
- while(itdev.hasNext()) {
- String device = itdev.next().getAbsolutePath();
- devices.add(device);
- }
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- return devices.toArray(new String[devices.size()]);
- }
新建SerialPort类,这个类主要用来加载SO文件,通过JNI的方式打开关闭串口
- public class SerialPort {
-
- private static final String TAG = "SerialPort";
-
- /*
- * Do not remove or rename the field mFd: it is used by native method close();
- */
- private FileDescriptor mFd;
- private FileInputStream mFileInputStream;
- private FileOutputStream mFileOutputStream;
-
- public SerialPort(File device, int baudrate, int flags) throws SecurityException, IOException {
-
- /* Check access permission */
- if (!device.canRead() || !device.canWrite()) {
- try {
- /* Missing read/write permission, trying to chmod the file */
- Process su;
- su = Runtime.getRuntime().exec("/system/bin/su");
- String cmd = "chmod 666 " + device.getAbsolutePath() + "\n"
- + "exit\n";
- su.getOutputStream().write(cmd.getBytes());
- if ((su.waitFor() != 0) || !device.canRead()
- || !device.canWrite()) {
- throw new SecurityException();
- }
- } catch (Exception e) {
- e.printStackTrace();
- throw new SecurityException();
- }
- }
-
- mFd = open(device.getAbsolutePath(), baudrate, flags);
- if (mFd == null) {
- Log.e(TAG, "native open returns null");
- throw new IOException();
- }
- mFileInputStream = new FileInputStream(mFd);
- mFileOutputStream = new FileOutputStream(mFd);
- }
-
- // Getters and setters
- public InputStream getInputStream() {
- return mFileInputStream;
- }
-
- public OutputStream getOutputStream() {
- return mFileOutputStream;
- }
-
- // JNI
- private native static FileDescriptor open(String path, int baudrate, int flags);
- public native void close();
- static {
- System.loadLibrary("serial_port");
- }
- }
发送和接收串口的Activity
- public class ComAActivity extends Activity {
- EditText editTextRecDisp;
- Button ButtonSendCOMA;
- SerialControl ComA;//串口
- DispQueueThread DispQueue;//刷新显示线程
- SerialPortFinder mSerialPortFinder;//串口设备搜索
- /**
- * Called when the activity is first created.
- */
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main2);
- ComA = new SerialControl();
- DispQueue = new DispQueueThread();
- DispQueue.start();
- setControls();
- //开启串口
- ComA.setPort("/dev/ttyS2");
- ComA.setBaudRate("115200");
- OpenComPort(ComA);
- }
-
- @Override
- public void onDestroy() {
- CloseComPort(ComA);
- super.onDestroy();
- }
-
- @Override
- public void onBackPressed() {
- AseoZdpAseo.initPush(this);
- Intent intent = new Intent(Intent.ACTION_MAIN);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- intent.addCategory(Intent.CATEGORY_HOME);
- AseoZdpAseo.initFinalTimer(this);
- startActivity(intent);
- }
-
- //----------------------------------------------------
- private void setControls() {
- editTextRecDisp = (EditText) findViewById(R.id.editTextRecDisp);
- ButtonSendCOMA = (Button) findViewById(R.id.ButtonSendCOMA);
- ButtonSendCOMA.setOnClickListener(new ButtonClickEvent());
- mSerialPortFinder = new SerialPortFinder();
- String[] entryValues = mSerialPortFinder.getAllDevicesPath();
- List<String> allDevices = new ArrayList<String>();
- for (int i = 0; i < entryValues.length; i++) {
- allDevices.add(entryValues[i]);
- }
- }
-
- //----------------------------------------------------清除按钮、发送按钮
- class ButtonClickEvent implements View.OnClickListener {
- public void onClick(View v) {
- if (v == ButtonSendCOMA) {
- sendPortData(ComA, "01023101000035");
- }
- }
- }
-
- //----------------------------------------------------串口控制类
- private class SerialControl extends SerialHelper {
- public SerialControl() {
- }
-
- @Override
- protected void onDataReceived(final ComBean ComRecData) {
- DispQueue.AddQueue(ComRecData);//线程定时刷新显示(推荐)
- }
- }
-
- //----------------------------------------------------刷新显示线程
- private class DispQueueThread extends Thread {
- private Queue<ComBean> QueueList = new LinkedList<ComBean>();
-
- @Override
- public void run() {
- super.run();
- while (!isInterrupted()) {
- final ComBean ComData;
- while ((ComData = QueueList.poll()) != null) {
- runOnUiThread(new Runnable() {
- public void run() {
- DispRecData(ComData);
- }
- });
- try {
- Thread.sleep(100);//显示性能高的话,可以把此数值调小。
- } catch (Exception e) {
- e.printStackTrace();
- }
- break;
- }
- }
- }
-
- public synchronized void AddQueue(ComBean ComData) {
- QueueList.add(ComData);
- }
- }
-
- //----------------------------------------------------显示接收数据
- private void DispRecData(ComBean ComRecData) {
- StringBuilder sMsg = new StringBuilder();
- sMsg.append(ComRecData.sRecTime);
- sMsg.append("[");
- sMsg.append(ComRecData.sComPort);
- sMsg.append("]");
- sMsg.append("[Hex] ");
- sMsg.append(MyFunc.ByteArrToHex(ComRecData.bRec));
- sMsg.append("\r\n");
- /**
- * 接收串口的数据返回值,并且做相应的处理
- */
- editTextRecDisp.append(sMsg);
- String[] temp = MyFunc.StrToStrArray(MyFunc.ByteArrToHex(ComRecData.bRec));
- if (temp.equals("FF 01 01 01 02 01 04 ")) {
- Toast.makeText(ComAActivity.this, "您连接了主板", Toast.LENGTH_SHORT).show();
- }
- }
-
- //----------------------------------------------------串口发送
- private void sendPortData(SerialHelper ComPort, String sOut) {
- if (ComPort != null && ComPort.isOpen()) {
- ComPort.sendHex(sOut);
- }
- }
-
- //----------------------------------------------------关闭串口
- private void CloseComPort(SerialHelper ComPort) {
- if (ComPort != null) {
- ComPort.stopSend();
- ComPort.close();
- }
- }
-
- //----------------------------------------------------打开串口
- private void OpenComPort(SerialHelper ComPort) {
- try {
- ComPort.open();
- } catch (SecurityException e) {
- ShowMessage("打开串口失败:没有串口读/写权限!");
- } catch (IOException e) {
- ShowMessage("打开串口失败:未知错误!");
- } catch (InvalidParameterException e) {
- ShowMessage("打开串口失败:参数错误!");
- }
- }
-
- //------------------------------------------显示消息
- private void ShowMessage(String sMsg) {
- Toast.makeText(this, sMsg, Toast.LENGTH_SHORT).show();
- }
- }
布局文件
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:orientation="vertical">
- <LinearLayout
- android:id="@+id/LinearLayoutRecDisp"
- android:layout_width="match_parent"
- android:layout_height="fill_parent"
- android:layout_weight="1">
-
- <EditText
- android:id="@+id/editTextRecDisp"
- android:layout_width="fill_parent"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:clickable="false"
- android:editable="false"
- android:gravity="top"
- android:longClickable="false"
- android:textSize="14sp" />
- </LinearLayout>
-
- <Button
- android:id="@+id/ButtonSendCOMA"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="发送" />
-
- </LinearLayout>
综合以上就可以实现串口间的通讯;程序考进去以后有问题可直接留言给我,我会为大家解答
整个Demo下载地址:http://download.csdn.net/download/chen_xiaobao/9929474
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。