精华内容
下载资源
问答
  • android 串口通信实例分析

    千次阅读 2016-07-19 22:33:55
    android 串口通信实例分析,用的时开源的android-serialport-api 这个是用android ndk实现的串口通信,我把他做了一个简化,适合于一般的程序的串口通信移植,欢迎拍砖~~~~~~~~~ 先说jni接口吧,原本文件...

    android 串口通信实例分析,用的时开源的android-serialport-api

    这个是用android ndk实现的串口通信,我把他做了一个简化,适合于一般的程序的串口通信移植,欢迎拍砖~~~~~~~~~

    先说jni接口吧,原本文件太多,其实只需要SerialPort.c和Android.mk就可以实现

    Serialport.c

    #include     <stdio.h>
    #include     <stdlib.h>
    #include     <unistd.h>
    #include     <sys/types.h>
    #include     <sys/stat.h>
    #include     <fcntl.h>
    #include     <termios.h>
    #include     <errno.h>
    #include 	 <jni.h>
    #include     <android/log.h>
    
    #define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "", __VA_ARGS__))//在logcat上打印信息用
    //#define LOGD(fmt, args...) __android_log_print(ANDROID_LOG_DEBUG, TAG, fmt, ##args)
    //#define LOGE(fmt, args...) __android_log_print(ANDROID_LOG_ERROR, TAG, fmt, ##args)
    
    static speed_t getBaudrate(jint baudrate)
    {
    	switch(baudrate) {
    	case 0: return B0;
    	case 50: return B50;
    	case 75: return B75;
    	case 110: return B110;
    	case 134: return B134;
    	case 150: return B150;
    	case 200: return B200;
    	case 300: return B300;
    	case 600: return B600;
    	case 1200: return B1200;
    	case 1800: return B1800;
    	case 2400: return B2400;
    	case 4800: return B4800;
    	case 9600: return B9600;
    	case 19200: return B19200;
    	case 38400: return B38400;
    	case 57600: return B57600;
    	case 115200: return B115200;
    	case 230400: return B230400;
    	case 460800: return B460800;
    	case 500000: return B500000;
    	case 576000: return B576000;
    	case 921600: return B921600;
    	case 1000000: return B1000000;
    	case 1152000: return B1152000;
    	case 1500000: return B1500000;
    	case 2000000: return B2000000;
    	case 2500000: return B2500000;
    	case 3000000: return B3000000;
    	case 3500000: return B3500000;
    	case 4000000: return B4000000;
    	default: return -1;
    	}
    }
    
    /*
     * Class:     com.huangcheng.serial.SerialPort
     * Method:    open
     * Signature: (Ljava/lang/String;II)Ljava/io/FileDescriptor;
     *
     * 用于打开串口,配置串口参数,包括的参数有path(需要打开的串口设备文件路径),baudrate(波特率),flags(打开串口的参数,如O_NONBLOCK之类的,可以随不同情况设置)
     * 其串口数据的读取是用FileDescriptor来实现的
     *
     */
    JNIEXPORT jobject JNICALL Java_com_huangcheng_serial_SerialPort_open
      (JNIEnv *env, jclass thiz, jstring path, jint baudrate, jint flags)
    {
    	int fd;
    	speed_t speed;
    	jobject mFileDescriptor;
    
    	/* Check arguments */
    	{
    		speed = getBaudrate(baudrate);
    		if (speed == -1) {
    			/* TODO: throw an exception */
    			LOGI("Invalid baudrate");
    			return NULL;
    		}
    	}
    
    	/* Opening device */
    	{
    		jboolean iscopy;
    		const char *path_utf = (*env)->GetStringUTFChars(env, path, &iscopy);
    		LOGI("Opening serial port %s with flags 0x%x", path_utf, O_RDWR | flags);
    		fd = open(path_utf, O_RDWR | flags);
    		LOGI("open() fd = %d", fd);
    		(*env)->ReleaseStringUTFChars(env, path, path_utf);
    		if (fd == -1)
    		{
    			/* Throw an exception */
    			LOGI("Cannot open port");
    			/* TODO: throw an exception */
    			return NULL;
    		}
    	}
    
    	/* Configure device */
    	{
    		struct termios cfg;
    		LOGI("Configuring serial port");
    		if (tcgetattr(fd, &cfg))
    		{
    			LOGI("tcgetattr() failed");
    			close(fd);
    			/* TODO: throw an exception */
    			return NULL;
    		}
    
    		cfmakeraw(&cfg);
    		cfsetispeed(&cfg, speed);
    		cfsetospeed(&cfg, speed);
    
    		if (tcsetattr(fd, TCSANOW, &cfg))
    		{
    			LOGI("tcsetattr() failed");
    			close(fd);
    			/* TODO: throw an exception */
    			return NULL;
    		}
    	}
    
    	/* Create a corresponding file descriptor */
    	{
    		jclass cFileDescriptor = (*env)->FindClass(env, "java/io/FileDescriptor");
    		jmethodID iFileDescriptor = (*env)->GetMethodID(env, cFileDescriptor, "<init>", "()V");
    		jfieldID descriptorID = (*env)->GetFieldID(env, cFileDescriptor, "descriptor", "I");
    		mFileDescriptor = (*env)->NewObject(env, cFileDescriptor, iFileDescriptor);
    		(*env)->SetIntField(env, mFileDescriptor, descriptorID, (jint)fd);
    	}
    
    	return mFileDescriptor;
    }
    
    /*
     * Class:     com.huangcheng.serial.SerialPort
     * Method:    close
     * Signature: ()V
     *
     * 用于串口关闭
     */
    JNIEXPORT void JNICALL Java_com_huangcheng_serial_SerialPort_close
      (JNIEnv *env, jobject thiz)
    {
    	jclass SerialPortClass = (*env)->GetObjectClass(env, thiz);
    	jclass FileDescriptorClass = (*env)->FindClass(env, "java/io/FileDescriptor");
    
    	jfieldID mFdID = (*env)->GetFieldID(env, SerialPortClass, "mFd", "Ljava/io/FileDescriptor;");
    	jfieldID descriptorID = (*env)->GetFieldID(env, FileDescriptorClass, "descriptor", "I");
    
    	jobject mFd = (*env)->GetObjectField(env, thiz, mFdID);
    	jint descriptor = (*env)->GetIntField(env, mFd, descriptorID);
    
    	LOGI("close(fd = %d)", descriptor);
    	close(descriptor);
    }
    Android.mk

    LOCAL_PATH := $(call my-dir)
    
    include $(CLEAR_VARS)
    
    LOCAL_MODULE    := serial_port
    LOCAL_SRC_FILES := SerialPort.c
    
    LOCAL_LDLIBS    := -llog
    include $(BUILD_SHARED_LIBRARY)

    然后,直接在目录下ndk-build一下,便可得到我们需要的lib库文件。看看怎么调用吧,首先在SerialPort.java中实现打开和关闭串口,引用了lib 库

    package com.huangcheng.serial;
    
    import java.io.File;
    import java.io.FileDescriptor;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    
    import android.util.Log;
    
    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");
    	}
    }
    然后他做了一个很聪明的控制串口打开和关闭的类Application.java,继承自android.app.Application 这样,他便可以在所有的Activity类中调用实现串口打开和关闭。
    /*
     * Copyright 2009 Cedric Priscal
     * 
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     * 
     * http://www.apache.org/licenses/LICENSE-2.0
     * 
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License. 
     */
    
    package com.huangcheng.serial;
    
    import java.io.File;
    import java.io.IOException;
    import java.security.InvalidParameterException;
    
    public class Application extends android.app.Application {
    
    	private SerialPort mSerialPort = null;
    
    	public SerialPort getSerialPort() throws SecurityException, IOException, InvalidParameterException {
    		if (mSerialPort == null) {
    			/* Open the serial port */
    			mSerialPort = new SerialPort(new File("/dev/ttyUSB0"),19200, 0);
    		}
    		return mSerialPort;
    	}
    
    	public void closeSerialPort() {
    		if (mSerialPort != null) {
    			mSerialPort.close();
    			mSerialPort = null;
    		}
    	}
    }
    最后写了一个类SerialPortActivity.java实现串口打开和关闭,串口数据通过Input/OutputStrean流来读取和发送,所有继承这个类的Activiy就可以实现串口读取或者发送。

    /*
     * Copyright 2009 Cedric Priscal
     * 
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     * 
     * http://www.apache.org/licenses/LICENSE-2.0
     * 
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License. 
     */
    
    package com.huangcheng.serial;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.security.InvalidParameterException;
    
    import com.huangcheng.zigbeeview.R;
    
    import android.app.Activity;
    import android.app.AlertDialog;
    import android.content.DialogInterface;
    import android.content.DialogInterface.OnClickListener;
    import android.os.Bundle;
    public abstract class SerialPortActivity extends Activity {
    
    	protected Application mApplication;
    	protected SerialPort mSerialPort;
    	protected OutputStream mOutputStream;
    	private InputStream mInputStream;
    	private ReadThread mReadThread;
    
    	private class ReadThread extends Thread {
    
    		@Override
    		public void run() {
    			super.run();
    			while(!isInterrupted()) {
    				int size;
    				try {
    					byte[] buffer = new byte[64];
    					if (mInputStream == null) return;
    					size = mInputStream.read(buffer);
    					if (size > 0) {
    						onDataReceived(buffer, size);
    					}
    				} catch (IOException e) {
    					e.printStackTrace();
    					return;
    				}
    			}
    		}
    	}
    
    	private void DisplayError(int resourceId) {
    		AlertDialog.Builder b = new AlertDialog.Builder(this);
    		b.setTitle("Error");
    		b.setMessage(resourceId);
    		b.setPositiveButton("OK", new OnClickListener() {
    			public void onClick(DialogInterface dialog, int which) {
    				SerialPortActivity.this.finish();
    			}
    		});
    		b.show();
    	}
    
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		mApplication = (Application) getApplication();
    		try {
    			mSerialPort = mApplication.getSerialPort();
    			mOutputStream = mSerialPort.getOutputStream();
    			mInputStream = mSerialPort.getInputStream();
    
    			/* Create a receiving thread */
    			mReadThread = new ReadThread();
    			mReadThread.start();
    		} catch (SecurityException e) {
    			DisplayError(R.string.error_security);
    		} catch (IOException e) {
    			DisplayError(R.string.error_unknown);
    		} catch (InvalidParameterException e) {
    			DisplayError(R.string.error_configuration);
    		}
    	}
    
    	protected abstract void onDataReceived(final byte[] buffer, final int size);
    
    	@Override
    	protected void onDestroy() {
    		if (mReadThread != null)
    			mReadThread.interrupt();
    		mApplication.closeSerialPort();
    		mSerialPort = null;
    		super.onDestroy();
    	}
    }

    最后,是一个测试Activity实现串口收发,ConsoleActivity.java
    /*
     * Copyright 2009 Cedric Priscal
     * 
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     * 
     * http://www.apache.org/licenses/LICENSE-2.0
     * 
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License. 
     */
    
    package com.huangcheng.serial;
    
    import java.io.IOException;
    
    import com.huangcheng.zigbeeview.R;
    
    import android.os.Bundle;
    import android.view.KeyEvent;
    import android.widget.EditText;
    import android.widget.TextView;
    import android.widget.TextView.OnEditorActionListener;
    
    public class ConsoleActivity extends SerialPortActivity {
    
    	EditText mReception;
    
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.console);
    
    //		setTitle("Loopback test");
    		mReception = (EditText) findViewById(R.id.EditTextReception);
    
    		EditText Emission = (EditText) findViewById(R.id.EditTextEmission);
    		Emission.setOnEditorActionListener(new OnEditorActionListener() {
    			public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
    				int i;
    				CharSequence t = v.getText();
    				char[] text = new char[t.length()];
    				for (i=0; i<t.length(); i++) {
    					text[i] = t.charAt(i);
    				}
    				try {
    					mOutputStream.write(new String(text).getBytes());
    					mOutputStream.write('\n');
    				} catch (IOException e) {
    					e.printStackTrace();
    				}
    				return false;
    			}
    		});
    	}
    
    	@Override
    	protected void onDataReceived(final byte[] buffer, final int size) {
    		runOnUiThread(new Runnable() {
    			public void run() {
    				if (mReception != null) {
    					mReception.append(new String(buffer, 0, size));
    				}
    			}
    		});
    	}
    }
    展开全文
  • android串口通信实例分析

    万次阅读 热门讨论 2012-05-21 23:31:18
    android 串口通信实例分析,用的时开源的android-serialport-api 这个是用android ndk实现的串口通信,我把他做了一个简化,适合于一般的程序的串口通信移植,欢迎拍砖~~~~~~~~~ 先说jni接口吧,原本文件...

    android 串口通信实例分析,用的时开源的android-serialport-api

    这个是用android ndk实现的串口通信,我把他做了一个简化,适合于一般的程序的串口通信移植,欢迎拍砖~~~~~~~~~

    先说jni接口吧,原本文件太多,其实只需要SerialPort.c和Android.mk就可以实现

    Serialport.c

    #include     <stdio.h>
    #include     <stdlib.h>
    #include     <unistd.h>
    #include     <sys/types.h>
    #include     <sys/stat.h>
    #include     <fcntl.h>
    #include     <termios.h>
    #include     <errno.h>
    #include 	 <jni.h>
    #include     <android/log.h>
    
    #define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "", __VA_ARGS__))//在logcat上打印信息用
    //#define LOGD(fmt, args...) __android_log_print(ANDROID_LOG_DEBUG, TAG, fmt, ##args)
    //#define LOGE(fmt, args...) __android_log_print(ANDROID_LOG_ERROR, TAG, fmt, ##args)
    
    static speed_t getBaudrate(jint baudrate)
    {
    	switch(baudrate) {
    	case 0: return B0;
    	case 50: return B50;
    	case 75: return B75;
    	case 110: return B110;
    	case 134: return B134;
    	case 150: return B150;
    	case 200: return B200;
    	case 300: return B300;
    	case 600: return B600;
    	case 1200: return B1200;
    	case 1800: return B1800;
    	case 2400: return B2400;
    	case 4800: return B4800;
    	case 9600: return B9600;
    	case 19200: return B19200;
    	case 38400: return B38400;
    	case 57600: return B57600;
    	case 115200: return B115200;
    	case 230400: return B230400;
    	case 460800: return B460800;
    	case 500000: return B500000;
    	case 576000: return B576000;
    	case 921600: return B921600;
    	case 1000000: return B1000000;
    	case 1152000: return B1152000;
    	case 1500000: return B1500000;
    	case 2000000: return B2000000;
    	case 2500000: return B2500000;
    	case 3000000: return B3000000;
    	case 3500000: return B3500000;
    	case 4000000: return B4000000;
    	default: return -1;
    	}
    }
    
    /*
     * Class:     com.huangcheng.serial.SerialPort
     * Method:    open
     * Signature: (Ljava/lang/String;II)Ljava/io/FileDescriptor;
     *
     * 用于打开串口,配置串口参数,包括的参数有path(需要打开的串口设备文件路径),baudrate(波特率),flags(打开串口的参数,如O_NONBLOCK之类的,可以随不同情况设置)
     * 其串口数据的读取是用FileDescriptor来实现的
     *
     */
    JNIEXPORT jobject JNICALL Java_com_huangcheng_serial_SerialPort_open
      (JNIEnv *env, jclass thiz, jstring path, jint baudrate, jint flags)
    {
    	int fd;
    	speed_t speed;
    	jobject mFileDescriptor;
    
    	/* Check arguments */
    	{
    		speed = getBaudrate(baudrate);
    		if (speed == -1) {
    			/* TODO: throw an exception */
    			LOGI("Invalid baudrate");
    			return NULL;
    		}
    	}
    
    	/* Opening device */
    	{
    		jboolean iscopy;
    		const char *path_utf = (*env)->GetStringUTFChars(env, path, &iscopy);
    		LOGI("Opening serial port %s with flags 0x%x", path_utf, O_RDWR | flags);
    		fd = open(path_utf, O_RDWR | flags);
    		LOGI("open() fd = %d", fd);
    		(*env)->ReleaseStringUTFChars(env, path, path_utf);
    		if (fd == -1)
    		{
    			/* Throw an exception */
    			LOGI("Cannot open port");
    			/* TODO: throw an exception */
    			return NULL;
    		}
    	}
    
    	/* Configure device */
    	{
    		struct termios cfg;
    		LOGI("Configuring serial port");
    		if (tcgetattr(fd, &cfg))
    		{
    			LOGI("tcgetattr() failed");
    			close(fd);
    			/* TODO: throw an exception */
    			return NULL;
    		}
    
    		cfmakeraw(&cfg);
    		cfsetispeed(&cfg, speed);
    		cfsetospeed(&cfg, speed);
    
    		if (tcsetattr(fd, TCSANOW, &cfg))
    		{
    			LOGI("tcsetattr() failed");
    			close(fd);
    			/* TODO: throw an exception */
    			return NULL;
    		}
    	}
    
    	/* Create a corresponding file descriptor */
    	{
    		jclass cFileDescriptor = (*env)->FindClass(env, "java/io/FileDescriptor");
    		jmethodID iFileDescriptor = (*env)->GetMethodID(env, cFileDescriptor, "<init>", "()V");
    		jfieldID descriptorID = (*env)->GetFieldID(env, cFileDescriptor, "descriptor", "I");
    		mFileDescriptor = (*env)->NewObject(env, cFileDescriptor, iFileDescriptor);
    		(*env)->SetIntField(env, mFileDescriptor, descriptorID, (jint)fd);
    	}
    
    	return mFileDescriptor;
    }
    
    /*
     * Class:     com.huangcheng.serial.SerialPort
     * Method:    close
     * Signature: ()V
     *
     * 用于串口关闭
     */
    JNIEXPORT void JNICALL Java_com_huangcheng_serial_SerialPort_close
      (JNIEnv *env, jobject thiz)
    {
    	jclass SerialPortClass = (*env)->GetObjectClass(env, thiz);
    	jclass FileDescriptorClass = (*env)->FindClass(env, "java/io/FileDescriptor");
    
    	jfieldID mFdID = (*env)->GetFieldID(env, SerialPortClass, "mFd", "Ljava/io/FileDescriptor;");
    	jfieldID descriptorID = (*env)->GetFieldID(env, FileDescriptorClass, "descriptor", "I");
    
    	jobject mFd = (*env)->GetObjectField(env, thiz, mFdID);
    	jint descriptor = (*env)->GetIntField(env, mFd, descriptorID);
    
    	LOGI("close(fd = %d)", descriptor);
    	close(descriptor);
    }
    Android.mk

    LOCAL_PATH := $(call my-dir)
    
    include $(CLEAR_VARS)
    
    LOCAL_MODULE    := serial_port
    LOCAL_SRC_FILES := SerialPort.c
    
    LOCAL_LDLIBS    := -llog
    include $(BUILD_SHARED_LIBRARY)

    然后,直接在目录下ndk-build一下,便可得到我们需要的lib库文件。看看怎么调用吧,首先在SerialPort.java中实现打开和关闭串口,引用了lib 库

    package com.huangcheng.serial;
    
    import java.io.File;
    import java.io.FileDescriptor;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    
    import android.util.Log;
    
    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");
    	}
    }
    然后他做了一个很聪明的控制串口打开和关闭的类Application.java,继承自android.app.Application 这样,他便可以在所有的Activity类中调用实现串口打开和关闭。
    /*
     * Copyright 2009 Cedric Priscal
     * 
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     * 
     * http://www.apache.org/licenses/LICENSE-2.0
     * 
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License. 
     */
    
    package com.huangcheng.serial;
    
    import java.io.File;
    import java.io.IOException;
    import java.security.InvalidParameterException;
    
    public class Application extends android.app.Application {
    
    	private SerialPort mSerialPort = null;
    
    	public SerialPort getSerialPort() throws SecurityException, IOException, InvalidParameterException {
    		if (mSerialPort == null) {
    			/* Open the serial port */
    			mSerialPort = new SerialPort(new File("/dev/ttyUSB0"),19200, 0);
    		}
    		return mSerialPort;
    	}
    
    	public void closeSerialPort() {
    		if (mSerialPort != null) {
    			mSerialPort.close();
    			mSerialPort = null;
    		}
    	}
    }
    最后写了一个类SerialPortActivity.java实现串口打开和关闭,串口数据通过Input/OutputStrean流来读取和发送,所有继承这个类的Activiy就可以实现串口读取或者发送。

    /*
     * Copyright 2009 Cedric Priscal
     * 
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     * 
     * http://www.apache.org/licenses/LICENSE-2.0
     * 
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License. 
     */
    
    package com.huangcheng.serial;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.security.InvalidParameterException;
    
    import com.huangcheng.zigbeeview.R;
    
    import android.app.Activity;
    import android.app.AlertDialog;
    import android.content.DialogInterface;
    import android.content.DialogInterface.OnClickListener;
    import android.os.Bundle;
    public abstract class SerialPortActivity extends Activity {
    
    	protected Application mApplication;
    	protected SerialPort mSerialPort;
    	protected OutputStream mOutputStream;
    	private InputStream mInputStream;
    	private ReadThread mReadThread;
    
    	private class ReadThread extends Thread {
    
    		@Override
    		public void run() {
    			super.run();
    			while(!isInterrupted()) {
    				int size;
    				try {
    					byte[] buffer = new byte[64];
    					if (mInputStream == null) return;
    					size = mInputStream.read(buffer);
    					if (size > 0) {
    						onDataReceived(buffer, size);
    					}
    				} catch (IOException e) {
    					e.printStackTrace();
    					return;
    				}
    			}
    		}
    	}
    
    	private void DisplayError(int resourceId) {
    		AlertDialog.Builder b = new AlertDialog.Builder(this);
    		b.setTitle("Error");
    		b.setMessage(resourceId);
    		b.setPositiveButton("OK", new OnClickListener() {
    			public void onClick(DialogInterface dialog, int which) {
    				SerialPortActivity.this.finish();
    			}
    		});
    		b.show();
    	}
    
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		mApplication = (Application) getApplication();
    		try {
    			mSerialPort = mApplication.getSerialPort();
    			mOutputStream = mSerialPort.getOutputStream();
    			mInputStream = mSerialPort.getInputStream();
    
    			/* Create a receiving thread */
    			mReadThread = new ReadThread();
    			mReadThread.start();
    		} catch (SecurityException e) {
    			DisplayError(R.string.error_security);
    		} catch (IOException e) {
    			DisplayError(R.string.error_unknown);
    		} catch (InvalidParameterException e) {
    			DisplayError(R.string.error_configuration);
    		}
    	}
    
    	protected abstract void onDataReceived(final byte[] buffer, final int size);
    
    	@Override
    	protected void onDestroy() {
    		if (mReadThread != null)
    			mReadThread.interrupt();
    		mApplication.closeSerialPort();
    		mSerialPort = null;
    		super.onDestroy();
    	}
    }

    最后,是一个测试Activity实现串口收发,ConsoleActivity.java
    /*
     * Copyright 2009 Cedric Priscal
     * 
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     * 
     * http://www.apache.org/licenses/LICENSE-2.0
     * 
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License. 
     */
    
    package com.huangcheng.serial;
    
    import java.io.IOException;
    
    import com.huangcheng.zigbeeview.R;
    
    import android.os.Bundle;
    import android.view.KeyEvent;
    import android.widget.EditText;
    import android.widget.TextView;
    import android.widget.TextView.OnEditorActionListener;
    
    public class ConsoleActivity extends SerialPortActivity {
    
    	EditText mReception;
    
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.console);
    
    //		setTitle("Loopback test");
    		mReception = (EditText) findViewById(R.id.EditTextReception);
    
    		EditText Emission = (EditText) findViewById(R.id.EditTextEmission);
    		Emission.setOnEditorActionListener(new OnEditorActionListener() {
    			public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
    				int i;
    				CharSequence t = v.getText();
    				char[] text = new char[t.length()];
    				for (i=0; i<t.length(); i++) {
    					text[i] = t.charAt(i);
    				}
    				try {
    					mOutputStream.write(new String(text).getBytes());
    					mOutputStream.write('\n');
    				} catch (IOException e) {
    					e.printStackTrace();
    				}
    				return false;
    			}
    		});
    	}
    
    	@Override
    	protected void onDataReceived(final byte[] buffer, final int size) {
    		runOnUiThread(new Runnable() {
    			public void run() {
    				if (mReception != null) {
    					mReception.append(new String(buffer, 0, size));
    				}
    			}
    		});
    	}
    }
    我会把android-serialport-api源码上传,大家可以根据我的这个博客自己简化一下,就可以直接移植到需要到程序上去了,绝对可用!


    展开全文
  • 51单片机与visualc++上位机串口通信实例包含上位机下位机的完整代码,对于单片机的串口通信,visual c++ mscomm的使用以及串行通信的参考
  • 一个串口通信实例

    2019-08-08 10:54:19
    /* 功能描述 通过串口向单片机发送一个信号,数码管显示该信号值 函数分析 数码管扫描 定时器设置定时 串口配置函数 */ #include <reg52.h> sbit ADDR3=P1^3; sbit ENLED=P1^4;...unsigned c...
    /*
    功能描述
    通过串口向单片机发送一个信号,数码管显示该信号值
    函数分析
    数码管扫描
    定时器设置定时
    串口配置函数
    */
    #include <reg52.h>
    sbit ADDR3=P1^3;
    sbit ENLED=P1^4;
    unsigned char TORH=0;
    unsigned char TORL=0;
    unsigned char refresh=1;
    unsigned char code ledchar[]={0XC0,0XF9,0XA4,0XB0,
    0X99,0X92,0X82,0XF8,0X80,0X90,0X88,0X83,0XC6,0XA1,0X86,0X8E};//数码管数值取值
    unsigned char leddd[6]={0xff,0xff,0xff,0xff,0xff,0xff};
    unsigned char ledsuff=0;
    void ledscan()
    {
    	static unsigned char i=0;
    	P0=0xff;
    	P1=(P1&0XF8)|i;
    	P0=leddd[i];
    	i++;
    	if(i>2)
    		i=0;
    }
    void config(unsigned int ms)
    {
    	unsigned long tmp;
    	tmp=11059200*ms/12000;
    	tmp=65536-tmp;
    	TORH=(unsigned char)(tmp>>8);
    	TORL=(unsigned char)(tmp);
    	TMOD&=0XF0;
    	TMOD|=0X01;
    	TH0=TORH;
    	TL0=TORL;
    	ET0=1;
    	TR0=1;
    }
    void configg(unsigned int baud)
    {
    	SCON=0X50; //配置串口为模式1
    	TMOD&=0X0F;	
    	TMOD|=0X20;	//配置T1为模式2	 即8位重装模式
    	TH1=256-(11059200/12/32)/baud;
    	TL1=TH1;   //这里设置定时器1主要是用来作为波特率发生器,故不使能中断
    	ET1=0;	   //禁止T1中断
    	ES=1;	   //使能串口中断
    	TR1=1;	   //启动T1
    }
    int main()
    {
    	//打开138
    	ADDR3=1;
    	ENLED=0;
    	EA=1;
    	config(2);//设置1ms中断
    	configg(9600);//设置9600波特率
    	while(1)
    	{
    		if(refresh)	//接收数据
    		{
    			 leddd[0]=ledchar[ledsuff&0x0f];
    			 leddd[1]=ledchar[ledsuff>>4];
    			 refresh=0;
    		}	
    	}
    }
     void InterruptUART() interrupt 4
     {
    	if(RI)	//接收完毕
    	{
    		RI=0;
    		ledsuff=SBUF;
    		SBUF=ledsuff;
    		refresh=1;
    	}
    	if(TI)	//发送完毕
    	{
    		TI=0;
    	}
     }
     void InterruptTimer() interrupt 1
     {
     	TH0=TORH;
    	TL0=TORL;
     	ledscan();
     }
    
    展开全文
  • Android串口通信:串口读写实例

    千次阅读 2017-05-26 10:58:01
    把之前在新浪博客里写的分享也备份移植到CSDN博客...在Android串口通信:基本知识梳理(http://gqdy365.iteye.com/admin/blogs/2188846)的基础上,我结合我项目中使用串口的实例,进行总结;  Android使用jni直接

    把之前在新浪博客里写的分享也备份移植到CSDN博客,之前本文博客地址是:http://blog.sina.com.cn/s/blog_14ed06d6c0102wqdl.html

    在Android串口通信:基本知识梳理(http://gqdy365.iteye.com/admin/blogs/2188846)的基础上,我结合我项目中使用串口的实例,进行总结; 

    Android使用jni直接进行串口设备的读写网上已经有开源项目了,本文是基于网上的开源项目在实际项目中的使用做的调整和优化; 
    Google串口开源项目见:https://code.google.com/p/android-serialport-api/ 

    下面是我项目中的相关代码及介绍: 

    1、SerialPort.cpp 

    Java代码  收藏代码
    1.   
    2. #include   
    3. #include   
    4. #include   
    5. #include <<span class="keyword" style="color: rgb(127, 0, 85); font-weight: bold;">assert.h>  
    6.   
    7. #include   
    8. #include   
    9. #include   
    10. #include   
    11. #include   
    12. #include   
    13. #include   
    14.   
    15. #include "android/log.h"  
    16. static const char *TAG = "serial_port";  
    17. #define LOGI(fmt, args...) __android_log_print(ANDROID_LOG_INFO,  TAG, fmt, ##args)  
    18. #define LOGD(fmt, args...) __android_log_print(ANDROID_LOG_DEBUG, TAG, fmt, ##args)  
    19. #define LOGE(fmt, args...) __android_log_print(ANDROID_LOG_ERROR, TAG, fmt, ##args)  
    20.   
    21. static speed_t getBaudrate(jint baudrate) {  
    22.     switch (baudrate) {  
    23.     case 0:  
    24.         return B0;  
    25.     case 50:  
    26.         return B50;  
    27.     case 75:  
    28.         return B75;  
    29.     case 110:  
    30.         return B110;  
    31.     case 134:  
    32.         return B134;  
    33.     case 150:  
    34.         return B150;  
    35.     case 200:  
    36.         return B200;  
    37.     case 300:  
    38.         return B300;  
    39.     case 600:  
    40.         return B600;  
    41.     case 1200:  
    42.         return B1200;  
    43.     case 1800:  
    44.         return B1800;  
    45.     case 2400:  
    46.         return B2400;  
    47.     case 4800:  
    48.         return B4800;  
    49.     case 9600:  
    50.         return B9600;  
    51.     case 19200:  
    52.         return B19200;  
    53.     case 38400:  
    54.         return B38400;  
    55.     case 57600:  
    56.         return B57600;  
    57.     case 115200:  
    58.         return B115200;  
    59.     case 230400:  
    60.         return B230400;  
    61.     case 460800:  
    62.         return B460800;  
    63.     case 500000:  
    64.         return B500000;  
    65.     case 576000:  
    66.         return B576000;  
    67.     case 921600:  
    68.         return B921600;  
    69.     case 1000000:  
    70.         return B1000000;  
    71.     case 1152000:  
    72.         return B1152000;  
    73.     case 1500000:  
    74.         return B1500000;  
    75.     case 2000000:  
    76.         return B2000000;  
    77.     case 2500000:  
    78.         return B2500000;  
    79.     case 3000000:  
    80.         return B3000000;  
    81.     case 3500000:  
    82.         return B3500000;  
    83.     case 4000000:  
    84.         return B4000000;  
    85.     default:  
    86.         return -1;  
    87.     }  
    88. }  
    89.   
    90.   
    91. JNIEXPORT jobject JNICALL native_open(JNIEnv *env, jobject thiz, jstring path,jint baudrate) {  
    92.     int fd;  
    93.     speed_t speed;  
    94.     jobject mFileDescriptor;  
    95.   
    96.     LOGD("init native Check arguments");  
    97.       
    98.     {  
    99.         speed = getBaudrate(baudrate);  
    100.         if (speed == -1) {  
    101.               
    102.             LOGE("Invalid baudrate");  
    103.             return NULL;  
    104.         }  
    105.     }  
    106.   
    107.     LOGD("init native Opening device!");  
    108.       
    109.     {  
    110.         jboolean iscopy;  
    111.         const char *path_utf = env->GetStringUTFChars(path, &iscopy);  
    112.         LOGD("Opening serial port %s", path_utf);  
    113. //      fd = open(path_utf, O_RDWR | O_DIRECT | O_SYNC);  
    114.         fd = open(path_utf, O_RDWR | O_NOCTTY | O_NONBLOCK | O_NDELAY);  
    115.         LOGD("open() fd = %d", fd);  
    116.         env->ReleaseStringUTFChars(path, path_utf);  
    117.         if (fd == -1) {  
    118.               
    119.             LOGE("Cannot open port %d",baudrate);  
    120.               
    121.             return NULL;  
    122.         }  
    123.     }  
    124.   
    125.     LOGD("init native Configure device!");  
    126.       
    127.     {  
    128.         struct termios cfg;  
    129.         if (tcgetattr(fd, &cfg)) {  
    130.             LOGE("Configure device tcgetattr() failed 1");  
    131.             close(fd);  
    132.             return NULL;  
    133.         }  
    134.   
    135.         cfmakeraw(&cfg);  
    136.         cfsetispeed(&cfg, speed);  
    137.         cfsetospeed(&cfg, speed);  
    138.   
    139.         if (tcsetattr(fd, TCSANOW, &cfg)) {  
    140.             LOGE("Configure device tcsetattr() failed 2");  
    141.             close(fd);  
    142.               
    143.             return NULL;  
    144.         }  
    145.     }  
    146.   
    147.       
    148.     {  
    149.         jclass cFileDescriptor = env->FindClass(";  

    展开全文
  • 代码注释清楚了,可以直接看。 #include "stm32f10x.h" ...//在此程序中,需要将bsp_usart.c中的NVIC中断部分注释掉否则报错 int main(void) { uint8_t ch; USART_Config(); //配置串口 LED_GPIO_Config(); /...
  • Visual C 串口通信工程开发实例导航(源代码),一共8章; 对于第3章和第7章: 在编译本章程序后,请将winio.dll、winio.vxd和winio.sys文件复制到可执行文件所在目录下, 否则WinIo库初始化函数initializeWinIO调用...
  • Android串口通信实例分析【附源码】

    千次阅读 2013-12-02 12:16:47
    Android 串口通信实例分析,用的时开源的android-serialport-api 这个是用android ndk实现的串口通信,我把他做了一个简化,适合于一般的程序的串口通信移植,欢迎拍砖~~~~~~~~~ 先说jni接口吧,原本文件...
  • | |_serial.c | |_serial.OPT | |_serial.PRJ
  • 本例采用C语言编译,运用系统自带的API函数来建立串口函数,比一般的控件串口通信函数移植性更加,本文本可直接复制代码到VS中使用
  • 书名:《C/C++串口通信典型应用实例编程实践》(电子工业出版社.曹卫杉) PDF扫描版,全书共分10章,共316页。 内容介绍 本书从工程应用的角度出发,对目前流行的三种不同类型的C/C++语言(包括C++ Builder、Visual ...
  • 资源名称:visual c 串口通信技术与工程实践内容简介: 本书详细介绍了利用Visual C 进行串口通信编程的各种方法和技巧,并力图通过生动的讲解和丰富的应用实例让读者进一步学习并提高掌握这一技术。 本书共分9章...
  • c++串口开发资料,包含串口工具开发、云台开发等
  • Visual C++_Turbo C串口通信编程实践 龚建新c++串口编程书 C++串口编程实例_计算机软件及应用_IT/计算机_专业资料。在windows程序设计与开发过程中,特别是涉及到开发嵌入式软硬件系统时,往往会涉及到串口编程
  • visual C++_Turbo C串口通信编程实践

    热门讨论 2010-07-30 09:14:24
    1.6体验DOS环境下Turbo C串口通信编程 第2章 VC多线程串口编程工具CSerialPort类 2.1 类功能及成员函数介绍 2.2 应用CSerialPort类编制基于对话框的应用程序 2.3 应用CSerialPort类编制基于单文档的应用程序 ...
  • 串口通信+TCP网络通信简单综合实例

    千次阅读 2017-07-21 18:43:35
    串口通信+TCP网络通信简单综合实例 串口通信加上TCP网络通信之后就可以简单实现本地设备的联网功能了,哈哈,话不多说,直接上代码。 总体上还是C/S模式,但是这个客户端加上了对串口的操作而已,思路很简单,只...
  • main.c 1 #include "stm32f10x.h" 2 #include"uart.h" 3 4 5 int main(void) 6 { 7 uart_init(115200); 8 while(1) 9 { 10 11 } 12 } uart.c 1 #inc...
  • 《Visual C++_Turbo+C串口通信编程实践》书本上所有实例的源代码,免费分享
  • Java串口通信使用的是RXTXcomm.jar下载地址: RXTXcomm.jar和相应的dll文件在项目中引入RXTXcomm.jar.还需要在C:\Windows\System32引入rxtxParallel.dll和rxtxSerial.dll两个文件.否则会报错;...
  • 书名:《Visual C++/Turbo C串口通信编程实践》(电子工业出版社.龚建伟.熊光明)。 内容简介 本书从编程实践的角度详细介绍了Windows环境下和DOS环境下的串口通信的基本方法,并根据当前串口与网络结合发展的趋势,...
  • STC89C52串口应用实例

    千次阅读 2017-01-14 18:33:42
    一般单片机的串口通信都需要通过MAX232 进行电平转换然后进行数据通信的,当然STC89C52RC 单 片机也不例外。图中的连接方式是常用的的一种零Modem 方式的最简单连接即3 线连接方式:只使用RXD、TXD 和GND 这三根连线...
  • 《Visual C++/Turbo C串口通信编程实践》(第2版)从编程实践角度详细介绍了PC计算机Windows环境下、DOS环境下以及单片机的串V1通信的基本方法,并根据当前串口与网络结合的发展趋势,给出了串口与TCP\IP网络、远程...
  • 《VisualC#.NET串口通信及测控应用典型实例》从工程应用的角度出发,通过8个典型应用实例,包括PC与PC、PC与单片机、PC与PLC、PC与远程I/O模块、PC与智能仪器、PC与无线数传模块、PC与USB数据采集模块等组成的测控...
  • linux串口通信参数宏详解实例

    千次阅读 2013-05-19 15:27:56
    常用的串口是RS-232-C接口(又称EIA RS-232-C)它是在1970年由美国电子工业协会(EIA)联合贝尔系统、调制解调器厂家及计算机终端生产厂家共同制定的用于串行通讯的标准。串口通讯指的是计算机依次以位(bit)为单位来...
  • 《Visual C++Turbo C串口通信编程实践》非常经典的一本书,适合初学者入门,适合入门者深入学习,里面有很多实例,非常好,值得大家研读一番。希望对您有帮助。
  • USART 串口通信配置步骤在上面的介绍中,可能有的朋友很不理解,不过没有关系,下面我们讲解如何使用库函数对 USART 进行配置。这个也是在编写程序中必须要了解的。具体步骤如下:(USART 相关库函数在 stm32f10x_...
  • 压缩包内含在STC89C52上能运行的IC卡识别及串口通信实例程序,含中文手册,含新手教程,1分下载分意思一下啦^_^
  • 1.3 PC与PC串口通信实例 1.3.1 两台PC串口通信 1.3.2 一台PC双串口互通信 第2章 PC与单片机串口通信 2.1 典型单片机开发板简介 2.1.1 单片机测控系统的组成 2.1.2 单片机开发板B的功能 2.1.3 单片机开发板B的主要...
  • 1.3 PC与PC串口通信实例 1.3.1 两台PC串口通信 1.3.2 一台PC双串口互通信 第2章 PC与单片机串口通信 2.1 典型单片机开发板简介 2.1.1 单片机测控系统的组成 2.1.2 单片机开发板B的功能 2.1.3 单片机开发板B的主要...

空空如也

空空如也

1 2 3 4 5 ... 8
收藏数 150
精华内容 60
关键字:

c串口通信实例