android串口设置电平高低,android 串口通讯1
android 串口通讯,如果是做驱动的人应该很容易写一个C语言的JNI,在Linux中串口也是很常用的一个硬件接口,正好我们做android定制型产品的,都会经常用到它。抛开UI,自己写个测试程序做串口的读写还是很容易的,这次在android开发,那么我们就按照android的标准来,网上也有很多人介绍android串口要怎么写,其实都差不多,只是我这个是用写C的人的思维来写的,相对比较容易让人
android 串口通讯,如果是做驱动的人应该很容易写一个C语言的JNI,在Linux中串口也是很常用的一个硬件接口,正好我们做android定制型产品的,都会经常用到它。抛开UI,自己写个测试程序做串口的读写还是很容易的,这次在android开发,那么我们就按照android的标准来,网上也有很多人介绍android串口要怎么写,其实都差不多,只是我这个是用写C的人的思维来写的,相对比较容易让人明白点。
首先要搭建NDK的环境,我用Linux的环境,本来我们都是放在android系统去编译代码的,但很多人都是做UI的做UI ,做驱动的做驱动,都是分开的,所以我还是采取分开的写法来。
NDK一般都可以去这个网站上下载:
下好后随便放到用户空间吧,然后修改 vim ~/.profile
把下面的这个
# ---- NDK----
ndk=/home/wfliao/android-ndk-r9b
PATH=$PATH:$ndk
export ndk
添加进去,然后source .profile 下。没起作用那就重启系统就可以了。我下的是 android-ndk-r9b,我放在 /home/wfliao/android-ndk-r9b下,所以你们只要想对应修改这个路径就可以了。
然后就是开始写JNI啦,我的eclipse写的测试代码一般放在workspace,所以我就直接执行mkdir -p /home/wfliao/workspace/uart/jni
建了一个jni的目录,然后在这个目录分别mkdir几个文件:Android.mk Application.mk com_android_uart_Uartjni.c com_android_uart_Uartjni.h
内容分别如下:
1:Android.mk
#
# 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.
#
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := uart
LOCAL_SRC_FILES := com_android_uart_Uartjni.c
LOCAL_LDLIBS := -llog
include $(BUILD_SHARED_LIBRARY)
2:Application.mk(我最小是支持 android-8 的)
APP_PLATFORM := android-8
3:com_android_uart_Uartjni.c
#include
#include
#include
#include
#include
#include "com_android_uart_Uartjni.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "android/log.h"
#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "", __VA_ARGS__))
#undef TCSAFLUSH
#define TCSAFLUSH TCSETSF
#ifndef _TERMIOS_H_
#define _TERMIOS_H_
#endif
//定义全局变量
int fd;
int ttyS6gpioFd;
int ttyS7gpioFd;
//---------------------------
//当需要从ttyS6读一维码扫描数据的时候需要把em13_gpio_state写低电平,一旦退出设备的时候设置为高电平
//当需要从ttyS7写数据的时候需要把uart485_gpio_state写高电平,一旦退出设备的时候设置为低电平,或者写完也是设置低
const char *uart485 = "/sys/class/power_supply/battery/device/uart485_gpio_state";
const char *em13 = "/sys/class/power_supply/battery/device/em13_gpio_state";
const char *ttyS6buf = "/dev/ttyS6";
const char *ttyS7buf = "/dev/ttyS7";
int ttyS6andS7=0; //如果是6 怎是设置ttyS6,如果是7则是设置ttyS7
const char dat0 = '0';
const char dat1 = '1';
//实现本地方法 openUart
//str=> "/dev/ttyS6","/dev/ttyS7", "/dev/rfid_rc522_dev"
JNIEXPORT jint JNICALL Java_com_android_uart_Uartjni_openUart(JNIEnv *env,jobject mc, jstring str)
{
const char *bufchar;
bufchar=(*env)->GetStringUTFChars(env,str,NULL);
if(!strcmp(ttyS6buf,bufchar))
{
ttyS6gpioFd = open(em13, O_RDWR);
if(ttyS6gpioFd > 0)
ttyS6andS7 = 6;
else
ttyS6andS7 = 0;
}
else if(!strcmp(ttyS7buf,bufchar))
{
ttyS7gpioFd = open(uart485, O_RDWR);
if(ttyS7gpioFd > 0)
ttyS6andS7 = 7;
else
ttyS6andS7 = 0;
}
else
{
ttyS6andS7 = 0;
}
LOGI("--jni ttyS6andS7 = %d--",ttyS6andS7) ;
fd=open(bufchar,O_RDWR|O_NOCTTY|O_NDELAY);
LOGI("jni opne %s device ",bufchar) ;
(*env)->ReleaseStringUTFChars(env, str, bufchar);
return fd;
}
JNIEXPORT void JNICALL Java_com_android_uart_Uartjni_closeUart(JNIEnv *env,jobject mc)
{
if(ttyS6andS7 == 6)
{
//--------------------关闭ttyS6的前,设置em13_gpio_state=1
write(ttyS6gpioFd, &dat1, sizeof(dat1));
LOGI("jni receive ttyS6, write to %c data to em13_gpio_state !",dat1) ;
close(ttyS6gpioFd);
}
if(ttyS6andS7 == 7)
close(ttyS7gpioFd);
close(fd);
LOGI("jni close devices !") ;
}
JNIEXPORT jint JNICALL Java_com_android_uart_Uartjni_setUart(JNIEnv *env,jobject mc,jint baudrate)
{
struct termios newtio,oldtio;
int speed_arr[]={B1200,B2400,B4800,B9600,B19200,B38400,B57600,B115200,B230400,B921600};
int speed_int[]={ 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200, 230400, 921600};
int i;
LOGI("jni setUart devices baud rate !") ;
for(i =0 ; i < sizeof(speed_int)/sizeof(int); i++)
{
if(baudrate == speed_int[i])
{
LOGI("jni setUart devices %d baud rate !",speed_int[i]) ;
tcgetattr(fd,&oldtio);
tcgetattr(fd,&newtio);
cfsetispeed(&newtio,speed_arr[i]);
cfsetospeed(&newtio,speed_arr[i]);
newtio.c_lflag=0;
newtio.c_cflag = speed_arr[i] | CS8 | CREAD | CLOCAL;
newtio.c_iflag= BRKINT | IGNPAR | IGNCR | IXON | IXOFF | IXANY ;
newtio.c_oflag=02;
newtio.c_line=0;
newtio.c_cc[7]=255;
newtio.c_cc[4]=0;
newtio.c_cc[5]=0;
if(tcsetattr(fd,TCSANOW,&newtio)<0)
{
LOGI("ttySx tcsetattr fail !");
//exit(1);
close(fd); //关闭
goto setend;
}
return fd;
}
}
setend:
LOGI("jni not setUart devices baud rate end!") ;
return -1;
}
JNIEXPORT jint JNICALL Java_com_android_uart_Uartjni_sendMsgUart(JNIEnv *env,jobject mc,jstring str)
{
int len;
const char *buf;
buf=(*env)->GetStringUTFChars(env,str,NULL);
len= (*env)->GetStringLength(env,str );
write(fd,buf,len);
LOGI("jni write to %s data to devices !",buf) ;
(*env)->ReleaseStringUTFChars(env, str, buf);
}
//连续发送一个数组的16进制数据
JNIEXPORT jint JNICALL Java_com_android_uart_Uartjni_sendHexUart(JNIEnv *env,jobject mc,jintArray arr)
{
int *buf;
char sendbuf[]={0x8A,0x01,0x01,0x11,0x9B};
int len,h;
LOGI("jni write to HEX data to devices !") ;
buf=(*env)->GetIntArrayElements(env,arr,NULL);
len = (*env)->GetArrayLength(env,arr);
for(h =0; h<5; h++)
{
sendbuf[h]= (char) buf[h];
LOGI("java write send HEX => 5 bytes %x !",buf[h]) ;
}
//--------------------写ttyS7前,设置uart485_gpio_state=1
write(ttyS7gpioFd, &dat1, sizeof(dat1));
LOGI("jni write to %c data to uart485_gpio_state !",dat1) ;
sleep(1);
LOGI("jni write 5 bytes to ttyS7 start !");
write(fd,sendbuf,sizeof(sendbuf));
LOGI("jni write 5 bytes to ttyS7 end !" );
for(h =0; h<5; h++)
{
LOGI("java write new HEX => 5 bytes %x !",sendbuf[h]) ;
}
//--------------------写ttyS7后,设置uart485_gpio_state=0
LOGI("jni write to %c data to uart485_gpio_state !",dat0) ;
write(ttyS7gpioFd, &dat0, sizeof(dat0));
(*env)->ReleaseIntArrayElements(env, arr, buf,0);
LOGI("jni write to data to devices !") ;
}
//加工后 485发送函数
JNIEXPORT jint JNICALL Java_com_android_uart_Uartjni_send485HexUart(JNIEnv *env,jobject mc,jint number)
{
LOGI("jni write to HEX data to devices !") ;
char hexStr[16];
char buf[]={0x8A,0x01,0x01,0x11,0x9B};
int n = number;
char Hextable[]="0123456789ABCDEF";
char swaphex[16],hex[16];
int i=0, k,index;
//整型数转换成16进制数
while(n){
swaphex[i++]=Hextable[n%16];
n /= 16;
}
swaphex[i]=0;
for(k=0;k
{
hex[k]=swaphex[i-1-k];
}
hex[k]=0;
memset(hexStr,0,sizeof(hexStr));
strcpy(hexStr,hex);
sscanf(hexStr, "%x",&index);
LOGI("jni :java write %d and jni change hex => %x!",number,index) ;
for(k =0; k<5; k++)
{
LOGI("jni write old 5 bytes %x !",buf[k]) ;
}
buf[2]= index;
LOGI("jni write box lock addr(%x) to third bytes!",index) ;
//锁的地址除于8,如果商是什么就直接赋值给第2个字节,如果是0,则直接赋值0x01;
index=index / 8;
if(index == 0)
{
buf[1]= 0x01;
LOGI("jni write the board addr(%x) to second bytes !",buf[1]) ;
}
else
{
buf[1]= index + 1;
LOGI("jni write the board addr(%x) to second bytes !",index) ;
}
//产生前4个字节的checksum,然后得到第5个字节的数据
int eof4x= buf[0]^buf[1]^buf[2]^buf[3];
LOGI("jni write fifth bytes (checksum = %x )!",eof4x) ;
buf[4]=eof4x;
//--------------------写ttyS7前,设置uart485_gpio_state=1
write(ttyS7gpioFd, &dat1, sizeof(dat1));
LOGI("jni write to %c data to uart485_gpio_state !",dat1) ;
sleep(1);
LOGI("jni write 5 bytes to ttyS7 start !") ;
write(fd,buf,sizeof(buf));
LOGI("jni write 5 bytes to ttyS7 end !" );
for(k =0; k<5; k++)
{
LOGI("jni write new HEX => 5 bytes %x !",buf[k]) ;
}
//--------------------写ttyS7后,设置uart485_gpio_state=0
LOGI("jni write to %c data to uart485_gpio_state !",dat0) ;
write(ttyS7gpioFd, &dat0, sizeof(dat0));
}
JNIEXPORT jstring JNICALL Java_com_android_uart_Uartjni_receiveMsgUart(JNIEnv *env,jobject mc)
{
int len=0,ret;
char buffer[128]="";
char card[16];
fd_set rdfd;
memset(buffer,0,sizeof(buffer));
//--------------------接收ttyS6的一维码扫描前,设置em13_gpio_state=0
if(ttyS6andS7 == 6)
{
write(ttyS6gpioFd, &dat0, sizeof(dat0));
//LOGI("jni receive ttyS6, write to %c data to em13_gpio_state !",dat0) ;
}
FD_SET(fd, &rdfd);/* 把句柄加入读监视集合 */
struct timeval timeout={1,0}; //select等待1秒,1秒轮询,要非阻塞就置0
ret = select(fd + 1, &rdfd, NULL, NULL, &timeout); /* 注意是最大值加1 */
if(ret < 0)
{
LOGI("call select fail"); /* select函数出错 */
return NULL ;
}
else if(ret == 0)
{
LOGI("selet timeout "); /* 在设定的timeval 时间内,socket的状态没有发生变化 */
return NULL ;
}
else
{
if (ttyS6andS7 != 0) //如果这个变量都不等于O的,那么肯定是ttyS6跟S7啦!
{
if(FD_ISSET(fd, &rdfd)) /* 先判断一下 fd 这个被监视的句柄是否真的变成可读的了 */
{
FD_ZERO(&rdfd); //清空集合
/* 读取ttySxfd 句柄里的数据 */
len=read(fd, buffer, sizeof(buffer));
//LOGI("len = %d, buffer[0]=%c, buffer[1]=%c",len,buffer[0],buffer[1]);
if (len > 0)
{
LOGI("jni read data from ttySx !") ;
return (*env)->NewStringUTF(env,buffer);
}
else
return NULL;
}
return NULL ;
}
else
{
if(FD_ISSET(fd, &rdfd))
{
FD_ZERO(&rdfd); //清空集合
/* 读取 rc522fd 句柄里的数据 */
len=read(fd, buffer, sizeof(buffer));
if (len > 0)
{
sprintf(card,"%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X",buffer[0],buffer[1],buffer[2],buffer[3],buffer[4],buffer[5],buffer[6],buffer[7],buffer[8],buffer[9],buffer[10],buffer[11],buffer[12],buffer[13],buffer[14],buffer[15]);
LOGI("jni read data from rc522_dev !") ;
return (*env)->NewStringUTF(env,card);
}
else
return NULL;
}
return NULL ;
}
}
}
4:com_android_uart_Uartjni.h
/* DO NOT EDIT THIS FILE - it is machine generated */
/* Header for class tw_com_dmatek_dma210xp_uart_Uartjni */
#include
#ifndef _Included_com_android_uart_Uartjni
#define _Included_com_android_uart_Uartjni
#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT jint JNICALL Java_com_android_uart_Uartjni_openUart
(JNIEnv *, jobject, jstring);
JNIEXPORT void JNICALL Java_com_android_uart_Uartjni_closeUart
(JNIEnv *, jobject);
JNIEXPORT jint JNICALL Java_com_android_uart_Uartjni_setUart
(JNIEnv *, jobject,jint);
JNIEXPORT jint JNICALL Java_com_android_uart_Uartjni_sendMsgUart
(JNIEnv *, jobject, jstring);
JNIEXPORT jint JNICALL Java_com_android_uart_Uartjni_sendHexUart
(JNIEnv *, jobject, jintArray);
JNIEXPORT jint JNICALL Java_com_android_uart_Uartjni_send485HexUart
(JNIEnv *, jobject, jint);
JNIEXPORT jstring JNICALL Java_com_android_uart_Uartjni_receiveMsgUart
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
最后得说明下,我不但在这个JNI中有串口还有对RFID的操作,而且又添加了串口对485的写操作。所以看起来就比较奇怪了。但有些有中文说明,所以我就不再写分析了。
JNI 要注意数据类型的转换。这个是非常重要的。
更多推荐
所有评论(0)