您的位置:首页 > 移动开发 > Android开发

android 串口通信

2016-05-23 15:32 561 查看
FT311D接口芯片为Android手机或平板电脑提供了USB转外部UART、GPIO、PWM、I2C、SPI硬件接口功能。

因为用的是这种串口,也就得用他对应的类

FT311UARTInterface.java 接口类 直接用

//User must modify the below package with their package name
package com.example.chuankoudemo;

import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

import Database.Global;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.hardware.usb.UsbAccessory;
import android.hardware.usb.UsbManager;
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
import android.util.Log;
import android.widget.Toast;

/****************************** FT311 GPIO interface class ******************************************/
public abstract class FT311UARTInterface extends Activity {

private static final String ACTION_USB_PERMISSION = "com.UARTTest.USB_PERMISSION";
public UsbManager usbmanager;
public UsbAccessory usbaccessory;
public PendingIntent mPermissionIntent;
public ParcelFileDescriptor filedescriptor = null;
public FileInputStream inputstream = null;
public FileOutputStream outputstream = null;
public boolean mPermissionRequestPending = false;
public read_thread readThread;

private byte[] writeusbdata;
//public byte[] readBuffer; /* circular buffer */
private byte status;
//final int maxnumbytes = 1024;
final int maxnumLimit=256;
public boolean datareceived = false;
public boolean READ_ENABLE = false;
public boolean accessory_attached = false;

public static String ManufacturerString = "mManufacturer=FTDI";
public static String ModelString1 = "mModel=FTDIUARTDemo";
public static String ModelString2 = "mModel=Android Accessory FT312D";
public static String VersionString = "mVersion=1.0";

public SharedPreferences intsharePrefSettings;

@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
Global.context = this;
intsharePrefSettings = null;// sharePrefSettings;
writeusbdata = new byte[maxnumLimit];
/* 128(make it 256, but looks like bytes should be enough) */
//readBuffer = new byte[maxnumbytes];

usbmanager = (UsbManager) this.getSystemService(Context.USB_SERVICE);
// Log.d("LED", "usbmanager" +usbmanager);
mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(
ACTION_USB_PERMISSION), 0);
IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
filter.addAction(UsbManager.ACTION_USB_ACCESSORY_DETACHED);
this.registerReceiver(mUsbReceiver, filter);
}

public void SetConfig(int baud, byte dataBits, byte stopBits, byte parity,
byte flowControl) {
//配置信息写到前8个byte
/* prepare the baud rate buffer */
writeusbdata[0] = (byte) baud;
writeusbdata[1] = (byte) (baud >> 8);
writeusbdata[2] = (byte) (baud >> 16);
writeusbdata[3] = (byte) (baud >> 24);

/* data bits */
writeusbdata[4] = dataBits;
/* stop bits */
writeusbdata[5] = stopBits;
/* parity */
writeusbdata[6] = parity;
/* flow control */
writeusbdata[7] = flowControl;

/* send the UART configuration packet */
SendPacket((int) 8);
}

/* write data */
public byte SendData(int numBytes, byte[] buffer) {
status = 0x00; /* success by default */
/*
* if num bytes are more than maximum limit
*/
if (numBytes < 1) {
/* return the status with the error in the command */
return status;
}

/* check for maximum limit */
if (numBytes > maxnumLimit) {
numBytes = maxnumLimit;
}

/* prepare the packet to be sent */
for (int count = 0; count < numBytes; count++) {
writeusbdata[count] = buffer[count];
}

if (numBytes != 64) {
SendPacket(numBytes);
} else {
byte temp = writeusbdata[63];
SendPacket(63);
writeusbdata[0] = temp;
SendPacket(1);
}

return status;
}

/* method to send on USB */
private void SendPacket(int numBytes) {
try {
if (outputstream != null) {
outputstream.write(writeusbdata, 0, numBytes);
}
} catch (IOException e) {
e.printStackTrace();
}
}

/* resume accessory */
public int ResumeAccessory() {
// Intent intent = getIntent();
if (inputstream != null && outputstream != null) {
return 1;
}

UsbAccessory[] accessories = usbmanager.getAccessoryList();
if (accessories != null) {
Toast.makeText(Global.context, "Accessory Attached",
Toast.LENGTH_SHORT).show();
} else {
// return 2 for accessory detached case
accessory_attached = false;
return 2;
}

UsbAccessory accessory = (accessories == null ? null : accessories[0]);
if (accessory != null) {
if (-1 == accessory.toString().indexOf(ManufacturerString)) {
Toast.makeText(Global.context, "Manufacturer is not matched!",
Toast.LENGTH_SHORT).show();
return 1;
}

if (-1 == accessory.toString().indexOf(ModelString1)
&& -1 == accessory.toString().indexOf(ModelString2)) {
Toast.makeText(Global.context, "Model is not matched!",
Toast.LENGTH_SHORT).show();
return 1;
}

if (-1 == accessory.toString().indexOf(VersionString)) {
Toast.makeText(Global.context, "Version is not matched!",
Toast.LENGTH_SHORT).show();
return 1;
}

Toast.makeText(Global.context,
"Manufacturer, Model & Version are matched!",
Toast.LENGTH_SHORT).show();
accessory_attached = true;

if (usbmanager.hasPermission(accessory)) {
OpenAccessory(accessory);
} else {
synchronized (mUsbReceiver) {
if (!mPermissionRequestPending) {
Toast.makeText(Global.context,
"Request USB Permission", Toast.LENGTH_SHORT)
.show();
usbmanager.requestPermission(accessory,
mPermissionIntent);
mPermissionRequestPending = true;
}
}
}
} else {
}

return 0;
}

/* destroy accessory */
public void DestroyAccessory(boolean bConfiged) {

if (true == bConfiged) {
READ_ENABLE = false; // set false condition for handler_thread to
// exit waiting data loop
writeusbdata[0] = 0; // send dummy data for instream.read going
SendPacket(1);
} else {
SetConfig(9600, (byte) 1, (byte) 8, (byte) 0, (byte) 0); // send
// default
// setting
// data
// for
// config
try {
Thread.sleep(10);
} catch (Exception e) {
}

READ_ENABLE = false; // set false condition for handler_thread to
// exit waiting data loop
writeusbdata[0] = 0; // send dummy data for instream.read going
SendPacket(1);
if (true == accessory_attached) {
saveDefaultPreference();
}
}

try {
Thread.sleep(10);
} catch (Exception e) {
}
CloseAccessory();
}

/********************* helper routines *************************************************/

public void OpenAccessory(UsbAccessory accessory) {
filedescriptor = usbmanager.openAccessory(accessory);
if (filedescriptor != null) {
usbaccessory = accessory;

FileDescriptor fd = filedescriptor.getFileDescriptor();

inputstream = new FileInputStream(fd);
outputstream = new FileOutputStream(fd);
/* check if any of them are null */
if (inputstream == null || outputstream == null) {
return;
}

if (READ_ENABLE == false) {
READ_ENABLE = true;
readThread = new read_thread(inputstream);
readThread.start();
}
}
}

private void CloseAccessory() {
try {
if (filedescriptor != null)
filedescriptor.close();

} catch (IOException e) {
}

try {
if (inputstream != null)
inputstream.close();
} catch (IOException e) {
}

try {
if (outputstream != null)
outputstream.close();

} catch (IOException e) {
}
/* FIXME, add the notfication also to close the application */

filedescriptor = null;
inputstream = null;
outputstream = null;

System.exit(0);
}

protected void saveDetachPreference() {
if (intsharePrefSettings != null) {
intsharePrefSettings.edit().putString("configed", "FALSE").commit();
}
}

protected void saveDefaultPreference() {
if (intsharePrefSettings != null) {
intsharePrefSettings.edit().putString("configed", "TRUE").commit();
intsharePrefSettings.edit().putInt("baudRate", 9600).commit();
intsharePrefSettings.edit().putInt("stopBit", 1).commit();
intsharePrefSettings.edit().putInt("dataBit", 8).commit();
intsharePrefSettings.edit().putInt("parity", 0).commit();
intsharePrefSettings.edit().putInt("flowControl", 0).commit();
}
}

/*********** USB broadcast receiver *******************************************/
private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (ACTION_USB_PERMISSION.equals(action)) {
synchronized (this) {
UsbAccessory accessory = (UsbAccessory) intent
.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
if (intent.getBooleanExtra(
UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
Toast.makeText(Global.context, "Allow USB Permission",
Toast.LENGTH_SHORT).show();
OpenAccessory(accessory);
} else {
Toast.makeText(Global.context, "Deny USB Permission",
Toast.LENGTH_SHORT).show();
Log.d("LED", "permission denied for accessory "
+ accessory);

}
mPermissionRequestPending = false;
}
} else if (UsbManager.ACTION_USB_ACCESSORY_DETACHED.equals(action)) {
saveDetachPreference();
DestroyAccessory(true);
} else {
Log.d("LED", "....");
}
}
};

/* usb input data handler */
private class read_thread extends Thread {
FileInputStream instream;

read_thread(FileInputStream stream) {
instream = stream;
}

@Override
public void run() {
super.run();
while (READ_ENABLE == true && !isInterrupted()) {
byte[] usb = new byte[1024];
try {
if (instream == null) {
return;
}
int readcount = instream.read(usb);
if (readcount > 0) {
onDataReceived(usb, readcount);
}
} catch (IOException e) {
e.printStackTrace();
return;
}
}
}
}

protected abstract void onDataReceived(final byte[] buffer, final int size);

}


用的时候 主类extends FT311UARTInterface一下

MainActivity.java

package com.example.chuankoudemo;

//import java.io.UnsupportedEncodingException;
//import java.util.ArrayList;

import Database.Global;
import android.annotation.SuppressLint;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends FT311UARTInterface implements OnClickListener{

private long main_time = Global.threadPeriod;
protected CharSequence sError;
protected boolean reflag;
protected EditText etReceive=null;
private Button btSend=null;
private EditText etSend=null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 初始化所有控件
allinit();
System.out.println("start");
new Thread(new Homethread()).start();
}

private void allinit() {// 初始化监听以及控件定义
etReceive=(EditText)findViewById(R.id.etReceive);
etSend=(EditText)findViewById(R.id.etSend);
btSend=(Button)findViewById(R.id.btSend);
btSend.setOnClickListener(this);

}

@Override
protected void onResume() {
super.onResume();
ResumeAccessory();
SetConfig(115200, (byte) 8, (byte) 1, (byte) 0, (byte) 0);
}
@Override
protected void onPause() {
super.onPause();
}
@Override
protected void onDestroy() {
super.onDestroy();
DestroyAccessory(true);
android.os.Process.killProcess(android.os.Process.myPid());
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {// end
return true;
}

/**
* @Fields handler : 用于线程间通信
*/
@SuppressLint("HandlerLeak")
public Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
byte[] usbdata = new byte[64];
switch (msg.what) {
case 1:// 回复
Toast.makeText(getApplicationContext(), Global.sendCMD, 30).show();
usbdata = Global.sendCMD.getBytes();
int size = usbdata.length;
SendData(size, usbdata);
break;
case 6:
Toast.makeText(getApplicationContext(), sError, 30).show();
default:
break;
}
super.handleMessage(msg);
}
};

class Homethread implements Runnable {
long start = 0;
long end = 0;
String text = "";
@Override
public void run() {
SetConfig(115200, (byte) 8, (byte) 1, (byte) 0, (byte) 0);
while (!Thread.interrupted()) {
start=System.currentTimeMillis();
System.out.println("HomeThread");
Message message = new Message();
//处理接受命令

end = System.currentTimeMillis();
try {
if (end - start < main_time) {
Thread.sleep(main_time - (end - start));
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

@Override
protected void onDataReceived(final byte[] buffer, final int size) {
runOnUiThread(new Runnable() {
public void run() {

String a = new String(buffer, 0, size);
//usbBuffer.append(a);
etReceive.append(a,0,size);
}
});
}

@Override
public void onClick(View v) {
// TODO
if(v.getId()==R.id.btSend){
Global.sendCMD=etSend.getText().toString();
Message message=new Message();
message.what=1;
this.handler.sendMessage(message);
}
}
}


main里面用到我在global里定义的几个参数

Global.java

public class Global {
public static Context context = null;
public static long threadPeriod = 1000;// 子线程周期
public static String sendCMD = "";// 要发送的命令
public static boolean sendSwitch = false;// 发送命令开关

public static synchronized void setSendSwitch(boolean set) {
Global.sendSwitch = set;
}
public static boolean canSend(){
return sendSwitch;
}
}


现在程序还不能直接用

还要在AndroidManifest申请权限

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" >
</uses-permission>


再在对应的activity中添加

<intent-filter>
<action android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" />
</intent-filter>

<meta-data
android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED"
android:resource="@xml/accessory_filter" >
</meta-data>


accessory_filter.xml

<?xml version="1.0" encoding="utf-8"?>

<resources>
<usb-accessory model="FTDIUARTDemo" manufacturer="FTDI" version="1.0"/>
<usb-accessory model="Android Accessory FT312D" manufacturer="FTDI" version="1.0"/>
</resources>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: