歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Android串口通信實例分析【附源碼】

Android串口通信實例分析【附源碼】

日期:2017/3/1 10:21:52   编辑:Linux編程

Android 串口通信實例分析,用的時開源的android-serialport-api

這個是用android ndk實現的串口通信,我把他做了一個簡化,適合於一般的程序的串口通信移植,歡迎拍磚~~~~~~~~~

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

Serialport.c

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <sys/types.h>
  5. #include <sys/stat.h>
  6. #include <fcntl.h>
  7. #include <termios.h>
  8. #include <errno.h>
  9. #include <jni.h>
  10. #include <android/log.h>
  11. #define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "", __VA_ARGS__))//在logcat上打印信息用
  12. //#define LOGD(fmt, args...) __android_log_print(ANDROID_LOG_DEBUG, TAG, fmt, ##args)
  13. //#define LOGE(fmt, args...) __android_log_print(ANDROID_LOG_ERROR, TAG, fmt, ##args)
  14. static speed_t getBaudrate(jint baudrate)
  15. {
  16. switch(baudrate) {
  17. case 0: return B0;
  18. case 50: return B50;
  19. case 75: return B75;
  20. case 110: return B110;
  21. case 134: return B134;
  22. case 150: return B150;
  23. case 200: return B200;
  24. case 300: return B300;
  25. case 600: return B600;
  26. case 1200: return B1200;
  27. case 1800: return B1800;
  28. case 2400: return B2400;
  29. case 4800: return B4800;
  30. case 9600: return B9600;
  31. case 19200: return B19200;
  32. case 38400: return B38400;
  33. case 57600: return B57600;
  34. case 115200: return B115200;
  35. case 230400: return B230400;
  36. case 460800: return B460800;
  37. case 500000: return B500000;
  38. case 576000: return B576000;
  39. case 921600: return B921600;
  40. case 1000000: return B1000000;
  41. case 1152000: return B1152000;
  42. case 1500000: return B1500000;
  43. case 2000000: return B2000000;
  44. case 2500000: return B2500000;
  45. case 3000000: return B3000000;
  46. case 3500000: return B3500000;
  47. case 4000000: return B4000000;
  48. default: return -1;
  49. }
  50. }
  51. /*
  52. * Class: com.huangcheng.serial.SerialPort
  53. * Method: open
  54. * Signature: (Ljava/lang/String;II)Ljava/io/FileDescriptor;
  55. *
  56. * 用於打開串口,配置串口參數,包括的參數有path(需要打開的串口設備文件路徑),baudrate(波特率),flags(打開串口的參數,如O_NONBLOCK之類的,可以隨不同情況設置)
  57. * 其串口數據的讀取是用FileDescriptor來實現的
  58. *
  59. */
  60. JNIEXPORT jobject JNICALL Java_com_huangcheng_serial_SerialPort_open
  61. (JNIEnv *env, jclass thiz, jstring path, jint baudrate, jint flags)
  62. {
  63. int fd;
  64. speed_t speed;
  65. jobject mFileDescriptor;
  66. /* Check arguments */
  67. {
  68. speed = getBaudrate(baudrate);
  69. if (speed == -1) {
  70. /* TODO: throw an exception */
  71. LOGI("Invalid baudrate");
  72. return NULL;
  73. }
  74. }
  75. /* Opening device */
  76. {
  77. jboolean iscopy;
  78. const char *path_utf = (*env)->GetStringUTFChars(env, path, &iscopy);
  79. LOGI("Opening serial port %s with flags 0x%x", path_utf, O_RDWR | flags);
  80. fd = open(path_utf, O_RDWR | flags);
  81. LOGI("open() fd = %d", fd);
  82. (*env)->ReleaseStringUTFChars(env, path, path_utf);
  83. if (fd == -1)
  84. {
  85. /* Throw an exception */
  86. LOGI("Cannot open port");
  87. /* TODO: throw an exception */
  88. return NULL;
  89. }
  90. }
  91. /* Configure device */
  92. {
  93. struct termios cfg;
  94. LOGI("Configuring serial port");
  95. if (tcgetattr(fd, &cfg))
  96. {
  97. LOGI("tcgetattr() failed");
  98. close(fd);
  99. /* TODO: throw an exception */
  100. return NULL;
  101. }
  102. cfmakeraw(&cfg);
  103. cfsetispeed(&cfg, speed);
  104. cfsetospeed(&cfg, speed);
  105. if (tcsetattr(fd, TCSANOW, &cfg))
  106. {
  107. LOGI("tcsetattr() failed");
  108. close(fd);
  109. /* TODO: throw an exception */
  110. return NULL;
  111. }
  112. }
  113. /* Create a corresponding file descriptor */
  114. {
  115. jclass cFileDescriptor = (*env)->FindClass(env, "java/io/FileDescriptor");
  116. jmethodID iFileDescriptor = (*env)->GetMethodID(env, cFileDescriptor, "<init>", "()V");
  117. jfieldID descriptorID = (*env)->GetFieldID(env, cFileDescriptor, "descriptor", "I");
  118. mFileDescriptor = (*env)->NewObject(env, cFileDescriptor, iFileDescriptor);
  119. (*env)->SetIntField(env, mFileDescriptor, descriptorID, (jint)fd);
  120. }
  121. return mFileDescriptor;
  122. }
  123. /*
  124. * Class: com.huangcheng.serial.SerialPort
  125. * Method: close
  126. * Signature: ()V
  127. *
  128. * 用於串口關閉
  129. */
  130. JNIEXPORT void JNICALL Java_com_huangcheng_serial_SerialPort_close
  131. (JNIEnv *env, jobject thiz)
  132. {
  133. jclass SerialPortClass = (*env)->GetObjectClass(env, thiz);
  134. jclass FileDescriptorClass = (*env)->FindClass(env, "java/io/FileDescriptor");
  135. jfieldID mFdID = (*env)->GetFieldID(env, SerialPortClass, "mFd", "Ljava/io/FileDescriptor;");
  136. jfieldID descriptorID = (*env)->GetFieldID(env, FileDescriptorClass, "descriptor", "I");
  137. jobject mFd = (*env)->GetObjectField(env, thiz, mFdID);
  138. jint descriptor = (*env)->GetIntField(env, mFd, descriptorID);
  139. LOGI("close(fd = %d)", descriptor);
  140. close(descriptor);
  141. }
Copyright © Linux教程網 All Rights Reserved