串口读取示例

24 篇文章 0 订阅
17 篇文章 0 订阅

波特率必须设置,采用系统默认的会产生问题

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <assert.h>
#include <termios.h>
#include <sys/time.h>
#include <time.h>
#include <sys/types.h>
#include <errno.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#define BAUD 9600
#define SERVERPORT 8500
#define MAX_FD_NUM 32
static int ret = -1;
static int fdSerial = -1;
static int fdServer = -1;


int uart_set(int fdSerial,int nSpeed, int nBits, char nEvent, int nStop)
{
     struct termios newtio,oldtio;
     if  ( tcgetattr( fdSerial,&oldtio)  !=  0) {
      perror("SetupSerial 1");
      printf("tcgetattr( fdSerial,&oldtio) -> %d\n",tcgetattr( fdSerial,&oldtio));
      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;
     }
     switch( nEvent )
     {
     case 'o':
     case 'O':
      newtio.c_cflag |= PARENB;
      newtio.c_cflag |= PARODD;
      newtio.c_iflag |= (INPCK | ISTRIP);
      break;
     case 'e':
     case 'E':
      newtio.c_iflag |= (INPCK | ISTRIP);
      newtio.c_cflag |= PARENB;
      newtio.c_cflag &= ~PARODD;
      break;
     case 'n':
     case 'N':
      newtio.c_cflag &= ~PARENB;
      break;
     default:
      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 115200:
      cfsetispeed(&newtio, B115200);
      cfsetospeed(&newtio, B115200);
      break;
     case 460800:
      cfsetispeed(&newtio, B460800);
      cfsetospeed(&newtio, B460800);
      break;
     default:
      cfsetispeed(&newtio, B9600);
      cfsetospeed(&newtio, B9600);
     break;
     }
     if( nStop == 1 )
      newtio.c_cflag &=  ~CSTOPB;
     else if ( nStop == 2 )
      newtio.c_cflag |=  CSTOPB;
     newtio.c_cc[VTIME]  = 0;
     newtio.c_cc[VMIN] = 0;
     tcflush(fdSerial,TCIFLUSH);

if((tcsetattr(fdSerial,TCSANOW,&newtio))!=0)
     {
      perror("com set error");
      return -1;
     }
     printf("set done!\n");
     return 0;
}

int uart_close(int fdSerial)
{
    assert(fdSerial);
    close(fdSerial);
    return 0;
}

int uart_open(int fdSerial,const char *pathname)
{
    fdSerial = open(pathname, O_RDWR|O_NOCTTY);
    uart_set(fdSerial,BAUD,8,0,0);
    if (-1 == fdSerial)
    {
        perror("Can't Open Serial Port");
        return(-1);
    }
    else
        printf("open %s success!\n",pathname);
    if(isatty(STDIN_FILENO)==0)
        printf("standard input is not a terminal device\n");
    else
        printf("isatty success!\n");
    return fdSerial;
}

int send_data(int  fdSerial, char *send_buffer,int length)
{
    length=write(fdSerial,send_buffer,length*sizeof(unsigned char));
    return length;
}

int recv_data(int fdSerial, char* recv_buffer,int length)
{
    length=read(fdSerial,recv_buffer,length);
    return length;
}

float a[3],w[3],Angle[3],h[3],Q[4];
void ParseData(char chr)
{
    static char chrBuf[100];
    static unsigned char chrCnt=0;
    signed short sData[4];
    unsigned char i;

    time_t now;
    chrBuf[chrCnt++]=chr;
    //直到接收一整包 11个字节
    if (chrCnt<11) return;
    //如果一包的数据是串的,数据前移动,直到接受到一个完整的包为止
    if ((chrBuf[0]!=0x55)||((chrBuf[1]&0x50)!=0x50)) {/*printf("Error:%x %x\r\n",chrBuf[0],chrBuf[1]);*/memcpy(&chrBuf[0],&chrBuf[1],10);chrCnt--;return;}
    //16进制--->10进制
    memcpy(&sData[0],&chrBuf[2],8);
    switch(chrBuf[1])
    {
            case 0x51:
                for (i=0;i<3;i++) a[i] = (float)sData[i]/32768.0*16.0;
                time(&now);
                printf("\r\nT:%s a:%6.3f %6.3f %6.3f ",asctime(localtime(&now)),a[0],a[1],a[2]);
                break;
            case 0x52:
                for (i=0;i<3;i++) w[i] = (float)sData[i]/32768.0*2000.0;
                printf("w:%7.3f %7.3f %7.3f ",w[0],w[1],w[2]);
                break;
            case 0x53:
                for (i=0;i<3;i++) Angle[i] = (float)sData[i]/32768.0*180.0;
                printf("A:%4.3f,B:%4.3f,C:%4.3f \n",Angle[0],Angle[1],Angle[2]);
                break;
            case 0x54:
                for (i=0;i<3;i++) h[i] = (float)sData[i];
                printf("h:%4.0f %4.0f %4.0f ",h[0],h[1],h[2]);
                break;
            case 0x59:
                for (i=0;i<4;i++) Q[i] = (float)sData[i]/32768.0;
                printf("q0:%4.5f,q1:%4.5f,q2:%4.5f,q3:%4.5f\n",Q[0],Q[1],Q[2],Q[3]);
                break;
    }
    chrCnt=0;
}

int client_request(int s)
{
    static char ibuf[1024];
    int nbytes = recv(s, ibuf, sizeof(ibuf), 0);
    if (nbytes > 0) {
        ibuf[nbytes] = '\0';
        if (strcmp(ibuf, "get_dist") == 0) {
            sprintf(ibuf, "%f,%f,%f,%f\r", Q[0],-Q[1],-Q[2],-Q[3]);
            write(s, ibuf, strlen(ibuf));
        }
    }
    return nbytes;
}

int open_serial()
{
    fdSerial = uart_open(fdSerial,"/dev/ttyUSB0");/*串口号/dev/ttySn,USB口号/dev/ttyUSBn */
    if(fdSerial == -1)
    {
        fprintf(stderr,"uart_open error\n");
        exit(EXIT_FAILURE);
    }
    return fdSerial;
}

int main(void)
{
    int maxfd = 0;
    int loopIndex = 0;
    fd_set all_fds;
    fd_set select_fds;
    FD_ZERO(&all_fds);
    FD_ZERO(&select_fds);
    char r_buf[1024];
    bzero(r_buf,1024);
    //open Serial
    open_serial();
    struct timeval tv;
    tv.tv_sec = 1;
    tv.tv_usec = 0;
    struct sockaddr_in server_address;
    struct sockaddr_storage their_addr;
    fdServer = socket(AF_INET,SOCK_STREAM,0);
    if(fdServer<0){perror("server construct ");return -1;}
    server_address.sin_family = AF_INET;
    server_address.sin_addr.s_addr = htonl(INADDR_ANY);
    server_address.sin_port=htons(SERVERPORT);
    //addr reuse
    int opt = 1;
    setsockopt(fdServer, SOL_SOCKET, SO_REUSEADDR, (const void *)&opt, sizeof(opt));
    if (bind(fdServer, (struct sockaddr*)&server_address, sizeof(server_address)) < 0) {
        perror("bind:");
        return -1;
    }
    if (listen(fdServer, 10) < 0) {
        perror("listen:");
        return -1;
    }
    //add serverfd 2 allfdsets
    FD_SET(fdServer, &all_fds);
    if (maxfd < fdServer) maxfd = fdServer;
    while(1)
    {
        ret = recv_data(fdSerial,r_buf,22);
        if(ret == -1)
            exit(EXIT_FAILURE);
        int i = 0;
        for (i = 0;i < ret;i++) ParseData(r_buf[i]);
        select_fds = all_fds;
        ret = select(maxfd + 1, &select_fds, NULL, NULL, &tv);
        if(ret < 0){perror("select"); return EXIT_FAILURE;}
        else if(ret == 0){tv.tv_sec = 0;tv.tv_usec = 20;continue;}
        for(loopIndex = fdServer; loopIndex < maxfd + 1; loopIndex++)
        {
            if(FD_ISSET(loopIndex, &select_fds)){
                if(loopIndex == fdServer){
                    socklen_t addrlen = sizeof(their_addr);
                    int newfd = accept(fdServer, (struct sockaddr *)&their_addr, &addrlen);
                    printf("%d conn", newfd);
                    if(newfd == -1){
                        perror("accept:");
                    }else if(newfd >= MAX_FD_NUM){
                        fprintf(stderr, "beyond MAX_FD_NUM");
                        close(newfd);
                    }else {
                        FD_SET(newfd, &all_fds);
                        if (newfd > maxfd) {
                            maxfd = newfd;
                        }
                    }
                }else {
                    int r = client_request(loopIndex);
                    if (r <= 0) {
                        if (r == 0) {
                            ;
                        } else {
                            perror("recv");
                        }
                        close(loopIndex);
                        FD_CLR(loopIndex, &all_fds);
                        if (loopIndex == maxfd) {
                            maxfd--;
                        }
                    }
                }
            }
        }
    }
    
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值