天嵌 ARM开发社区

 找回密码
 注册
查看: 10291|回复: 15

E9 Android 打开串口/dev/ttySAC3发送数据错误

[复制链接]
jisuanji1996 发表于 2014-5-27 09:16:16 | 显示全部楼层 |阅读模式
E9 Android 打开串口/dev/ttySAC3,通过升压模块,接到台式机的串口上,在Windows客户端使用串口调试助手打开接受数据。每一次在E9上面调用JNI接口函数OpenDoor发送的数据,在串口调试助手都只是能够接受到十六进制的00,下面是我使用的JNI接口函数。
/*
* Copyright 2009-2011 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.
*/

#include <termios.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <jni.h>

#include "SerialPort.h"

#include "android/log.h"
static const char *TAG="serial_port";
#define LOGI(fmt, args...) __android_log_print(ANDROID_LOG_INFO,  TAG, fmt, ##args)
#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)

char data[] = "1212121212121212";
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;
        }
}

// 串口操作句柄
int fd =  -1;

/*
* Class:     android_serialport_SerialPort
* Method:    open
* Signature: (Ljava/lang/String;II)Ljava/io/FileDescriptor;
*/
int  Java_com_example_androidserialportapi_SerialPort_open (JNIEnv *env, jobject thiz, jstring path, jint baudrate, jint flags)
{
        speed_t speed;
        jobject mFileDescriptor;

        /* Check arguments */
        {
                speed = getBaudrate(9600);
                if (speed == -1) {
                        /* TODO: throw an exception */
                        LOGE("Invalid baudrate");
                        return -1;
                }
        }

        /* Opening device */
        {
                jboolean iscopy;
                const char *path_utf = (*env)->GetStringUTFChars(env, path, &iscopy);
                //LOGD("Opening serial port %s with flags 0x%x", path_utf, O_RDWR|O_NOCTTY|O_NDELAY);
                fd = open(path_utf, O_RDWR|O_NOCTTY|O_NDELAY);
                LOGD("open() fd = %d", fd);
                (*env)->ReleaseStringUTFChars(env, path, path_utf);
                if (fd == -1)
                {
                        /* Throw an exception */
                        LOGE("Cannot open port");
                        /* TODO: throw an exception */
                        return -1;
                }
        }

        /* Configure device */
        {
                /*恢复串口为阻塞状态*/
         if(fcntl(fd, F_SETFL, 0)<0)
                 LOGE("fcntl failed!\n");
         else
                 LOGE("fcntl=%d\n",fcntl(fd, F_SETFL,0));

                struct termios cfg;
                LOGD("Configuring serial port");
                if (tcgetattr(fd, &cfg))
                {
                        LOGE("tcgetattr() failed");
                        close(fd);
                        /* TODO: throw an exception */
                        return -1;
                }

                bzero( &cfg, sizeof( cfg ) );
                cfsetispeed(&cfg, speed);
                cfsetospeed(&cfg, speed);

                /*步骤一,设置字符大小*/
                cfg.c_cflag  |=  CLOCAL | CREAD;
                cfg.c_cflag &= ~CSIZE;

                cfg.c_cflag &= ~PARENB;                // 没有奇偶校验
                cfg.c_cflag |= CS8;                        // 设置数据位为8
                cfg.c_cflag &= ~CSTOPB;                // 将停止位设置为一个比特

                /*设置等待时间和最小接收字符*/
                cfg.c_cc[VTIME]  = 10;
                cfg.c_cc[VMIN] = 0;
                /*处理未接收字符*/
                tcflush(fd,TCIFLUSH);

                if (tcsetattr(fd, TCSANOW, &cfg))
                {
                        LOGE("tcsetattr() failed");
                        close(fd);
                        /* TODO: throw an exception */
                        return -1;
                }

        }

        return 0;
}

/*
* Class:     cedric_serial_SerialPort
* Method:    close
* Signature: ()V
*/
void  Java_com_example_androidserialportapi_SerialPort_close (JNIEnv *env, jobject thiz)
{
        if( fd != -1 )
                close(fd);
}


// 打开继电器
void  Java_com_example_androidserialportapi_SerialPort_OpenDoor (JNIEnv *env, jobject thiz)
{
        if( fd != -1 )
        {
                write( fd, data, strlen(data) );
        }
}


// 关闭继电器
void  Java_com_example_androidserialportapi_SerialPort_CloseDoor (JNIEnv *env, jobject thiz)
{
        if( fd != -1 )
        {
                write( fd, data, strlen(data) );
        }
}

麻烦大神帮忙看一下出什么问题了
TQ-lkp 发表于 2014-5-27 09:22:45 | 显示全部楼层
直接在app层发送命令不就行了吗,为什么还要在jni层加函数?
 楼主| jisuanji1996 发表于 2014-5-27 09:37:47 | 显示全部楼层
TQ-lkp 发表于 2014-5-27 09:22
直接在app层发送命令不就行了吗,为什么还要在jni层加函数?

有现成的apk程序不?我先试试
 楼主| jisuanji1996 发表于 2014-5-27 09:49:26 | 显示全部楼层
TQ-lkp 发表于 2014-5-27 09:22
直接在app层发送命令不就行了吗,为什么还要在jni层加函数?

我前几天已经通过360手机助手安装了几个串口调试工具,都不行,在Windwos串口调试助手上面一点信息都收不到, 上面的程序是我根据AndroidsrialDemo开源程序修改的,原来的程序也是这样 ,在Windwos串口调试助手上面可以收到数据,但是数据不正确。
daqingyzb 发表于 2014-5-27 09:51:13 | 显示全部楼层
比特率应该是115200而不是9600
daqingyzb 发表于 2014-5-27 09:52:38 | 显示全部楼层
说错了,我用的是115200
你只要在两边的波特率都一样就行了
daqingyzb 发表于 2014-5-27 09:53:57 | 显示全部楼层
想知道你的jni是怎么编译的
 楼主| jisuanji1996 发表于 2014-5-27 09:58:00 | 显示全部楼层
daqingyzb 发表于 2014-5-27 09:51
比特率应该是115200而不是9600

不行的  还是 只能够接受到 00
 楼主| jisuanji1996 发表于 2014-5-27 10:13:34 | 显示全部楼层
本帖最后由 jisuanji1996 于 2014-5-27 13:34 编辑
daqingyzb 发表于 2014-5-27 09:53
想知道你的jni是怎么编译的

http://download.csdn.net/download/jscumt/7406267这是工程的源代码
 楼主| jisuanji1996 发表于 2014-5-27 11:04:02 | 显示全部楼层
TQ-lkp 发表于 2014-5-27 09:22
直接在app层发送命令不就行了吗,为什么还要在jni层加函数?

是这样吗?
                                try {
                                       
                                        File file = new File("file:///dev/ttySAC3");
                                        OutputStream oStream = new FileOutputStream( file );
                                        String dataString = "123456789";
                                        oStream.write( dataString.getBytes() );
                                        oStream.close();
                                       
                                } catch (FileNotFoundException e) {
                                        // TODO Auto-generated catch block
                                        e.printStackTrace();
                                } catch (IOException e) {
                                        // TODO Auto-generated catch block
                                        e.printStackTrace();
                                }
 楼主| jisuanji1996 发表于 2014-5-27 11:09:08 | 显示全部楼层
daqingyzb 发表于 2014-5-27 09:52
说错了,我用的是115200
你只要在两边的波特率都一样就行了

能说一下 你是怎么实现的吗?
TQ-lkp 发表于 2014-5-27 11:32:32 | 显示全部楼层
jisuanji1996 发表于 2014-5-27 11:04
是这样吗?
                                try {
                                       

就是这样子的
 楼主| jisuanji1996 发表于 2014-5-27 11:48:45 | 显示全部楼层

/dev/ttySAC3 用的是 扩展接口 30(UART4_RXD) 和31(UART4_TXD) 吗? 我怎么现在连数据都收不到的
 楼主| jisuanji1996 发表于 2014-5-27 12:48:35 | 显示全部楼层

http://download.csdn.net/detail/jscumt/7407101
  我的程序,麻烦帮我看一下 是哪里出现了问题, 谢谢!
 楼主| jisuanji1996 发表于 2014-6-5 10:03:35 | 显示全部楼层
原来是串口设置有问题 找本Linux串口相关编程的书籍改一下就好了
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

i.MX8系列ARM cortex A53 M4 工控板上一条 /1 下一条

Archiver|手机版|小黑屋|天嵌 嵌入式开发社区 ( 粤ICP备11094220号 )

GMT+8, 2024-5-18 08:00 , Processed in 1.031244 second(s), 18 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表