Linux/Android系統開發 串口參數配置源碼 serial.c/serial.cpp

該驅動適用於採用linux和android系統平臺的C/C++開發。

用於配置串口相關參數:端口選擇、阻塞非阻塞、波特率、停止位、數據位、校驗位等。

注:需要系統開啓串口操作權限,否則配置失敗。

本驅動在MTK8735平臺上驗證測試,其它平臺修改串口端口名稱即可。

源代碼:

serial.h

//
// Created by taxiang&xuezi on 2018/4/2.
//

#ifndef NDKAPPECG_SERIAL_H
#define NDKAPPECG_SERIAL_H

#ifdef  SERIAL_GLOBALS
#define SERIAL_EXT
#else
#define SERIAL_EXT extern
#endif

#define SERIAL_DBG    1

SERIAL_EXT s32 uart_open(s32 fd,s32 port,s8 block);
SERIAL_EXT s32 uart_set(s32 fd, s32 nSpeed, s32 nBits, s8 nEvent, s32 nStop);
#endif //NDKAPPECG_SERIAL_H


serial.c/serial.cpp

//
// Created by taxiang&xuezi on 2018/4/2.
//

#define SERIAL_GLOBALS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <errno.h>
#include <fcntl.h>
#include <termios.h>
#include <time.h>
#include <unistd.h>
#include <sys/stat.h>


#ifdef SERIAL_DBG
#define SERIAL_PRINT0(X)   printf(X);
#define SERIAL_PRINT1(X,A)  printf (X,A);
#define SERIAL_PRINT2(X,A,B)  printf (X,A,B);
#define SERIAL_PRINT3(X,A,B,C)  printf (X,A,B,C);
#define SERIAL_PRINT4(X,A,B,C,D)  printf (X,A,B,C,D);
#else
#define SERIAL_PRINT0(X)
#define SERIAL_PRINT1(X,A)
#define SERIAL_PRINT2(X,A,B)
#define SERIAL_PRINT3(X,A,B,C)
#define SERIAL_PRINT4(X,A,B,C)
#endif

/*******************************************************************************
* 函數名稱: s32 uart_open(s32 fd,s32 port,s8 block)
* 函數功能: 打開串口
* 輸入參數:
* 輸出參數:
* 返回值  :
*******************************************************************************/
s32 uart_open(s32 fd,s32 port,s8 block)
{
    s8 *dev[]={"/dev/ttyMT0","/dev/ttyMT1","/dev/ttyMT2","/dev/ttyMT3"};

    fd = open(dev[port], O_RDWR|O_NOCTTY|O_NONBLOCK);//nblock
    if(fd == -1){
        SERIAL_PRINT3("%s [%s:%d]\n", strerror(errno), __FILE__, __LINE__);
        return -1;
    }

    if(block == 0){//nblock
//        if(fcntl(fd, F_SETFL, FNDELAY)<0){
//            SERIAL_PRINT3("%s [%s:%d]\n", strerror(errno), __FILE__, __LINE__);
//            return -1;
//        }
    }else{//block
        if(fcntl(fd, F_SETFL, 0)<0){
            SERIAL_PRINT3("%s [%s:%d]\n", strerror(errno), __FILE__, __LINE__);
            return -1;
        }
    }

//    if(isatty(STDIN_FILENO)==0){
//        SERIAL_PRINT3("%s [%s:%d]\n", strerror(errno), __FILE__, __LINE__);
//        return -1;
//    }
//    SERIAL_PRINT0("uart open done\n");

    return fd;
}

/*******************************************************************************
* 函數名稱: s32 uart_set(s32 fd, s32 nSpeed, s32 nBits, s8 nEvent, s32 nStop)
* 函數功能: 配置串口
* 輸入參數:
* 輸出參數:
* 返回值  :
*******************************************************************************/
s32 uart_set(s32 fd, s32 nSpeed, s32 nBits, s8 nEvent, s32 nStop)
{
    struct termios newtio;
    struct termios oldtio;

    if(tcgetattr(fd,&oldtio) != 0){
        SERIAL_PRINT3("%s [%s:%d]\n", strerror(errno), __FILE__, __LINE__);
        return -1;
    }

    bzero(&newtio,sizeof(newtio));
    newtio.c_cflag |= CLOCAL |CREAD;

    /***********數據位選擇****************/
    newtio.c_cflag &= ~CSIZE;
    switch(nBits){
        case 7:
        newtio.c_cflag |= CS7;
        break;
        case 8:
        newtio.c_cflag |= CS8;
        break;
        default :
        newtio.c_cflag |= CS8;
        break;
    }
    /***********校驗位選擇****************/
    switch(nEvent){
        case 'n':
        case 'N':
        newtio.c_cflag &= ~PARENB;
        newtio.c_iflag &= ~INPCK;
        break;
        case 'o':
        case 'O':
        newtio.c_cflag |= PARENB;
        newtio.c_cflag |= PARODD;
        newtio.c_iflag |= INPCK;
        break;
        case 'e':
        case 'E':
        newtio.c_cflag |= PARENB;
        newtio.c_cflag &= ~PARODD;
        newtio.c_iflag |= INPCK;
        break;
        case 's':
        case 'S':
        newtio.c_cflag |= PARENB;
        newtio.c_cflag &= ~CSTOPB;
        newtio.c_iflag |= INPCK;
        default :
        newtio.c_cflag &= ~PARENB;
        newtio.c_iflag &= ~INPCK;
        break;
    }
    /***********波特率選擇****************/
    switch(nSpeed){
        case 2400:
        cfsetispeed(&newtio,B2400);
        cfsetospeed(&newtio,B2400);
        break;
        case 4800:
        cfsetispeed(&newtio,B4800);
        cfsetospeed(&newtio,B4800);
        break;
        case 9600:
        cfsetispeed(&newtio,B9600);
        cfsetospeed(&newtio,B9600);
        break;
        case 57600:
        cfsetispeed(&newtio,B57600);
        cfsetospeed(&newtio,B57600);
        break;
        case 115200:
        cfsetispeed(&newtio,B115200);
        cfsetospeed(&newtio,B115200);
        break;
        case 230400:
        cfsetispeed(&newtio,B230400);
        cfsetospeed(&newtio,B230400);
        break;
        case 460800:
        cfsetispeed(&newtio,B460800);
        cfsetospeed(&newtio,B460800);
        break;
        case 500000:
        cfsetispeed(&newtio,B500000);
        cfsetospeed(&newtio,B500000);
        break;
        case 576000:
        cfsetispeed(&newtio,B576000);
        cfsetospeed(&newtio,B576000);
        break;
        case 921600:
        cfsetispeed(&newtio,B921600);
        cfsetospeed(&newtio,B921600);
        break;
        case 2000000:
        cfsetispeed(&newtio,B2000000);
        cfsetospeed(&newtio,B2000000);
        break;
        default:
        cfsetispeed(&newtio,B9600);
        cfsetospeed(&newtio,B9600);
        break;
    }
    /***********停止位選擇****************/
    switch(nStop){
        case 1:
        newtio.c_cflag &= ~CSTOPB;
        break;
        case 2:
        newtio.c_cflag |= CSTOPB;
        break;
        default:
        newtio.c_cflag &= ~CSTOPB;
        break;
    }

    //VTIME和VMIN僅在阻塞模式下有效
    newtio.c_cc[VTIME] = 0;
    newtio.c_cc[VMIN] = 1;

    tcflush(fd,TCIFLUSH);
    if((tcsetattr(fd,TCSANOW,&newtio)) != 0){
        SERIAL_PRINT3("%s [%s:%d]\n", strerror(errno), __FILE__, __LINE__);
        return -1;
    }
    SERIAL_PRINT4("uart set done:%d %d %C %d\n",nSpeed,nBits,nEvent,nStop);

    return 0;
}

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章