认真学习的jerry 发表于 2023-11-16 13:51:13

通过终端模拟虚拟串口进行读写

#include <termios.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/signal.h>
#include <pthread.h>

#define BAUDRATE B115200
#define COM1 "/dev/pts/3"
#define COM2 "/dev/pts/4"
#define ENDMINITERM1 27
#define ENDMINITERM2 3
#define FALSE 0
#define TRUE 1

volatile int STOP=FALSE;
volatile int fd;


void child_handler(int s)
{
        printf("stop!!!\n");
           STOP=TRUE;
}

void* keyboard(void * data)
{
           
            char c;
        for (;;){
               
                scanf("%c",&c);
              printf("getchar is :%d",c);
              if( (c==ENDMINITERM1) || (c==ENDMINITERM2)){
                        printf("break\n");
                      STOP=TRUE;
                      break ;
                      }
        }

            return NULL;
}


void* receive(void * data)
{
        int c;
        printf("read modem\n");

        while (STOP==FALSE)
        {
                    read(fd,&c,1);
                    write(1,&c,1);
        }

        printf("exit from reading modem\n");
        return NULL;
}

void* send(void * data)
{
        int c='0';
        printf("send data\n");

        while (STOP==FALSE)
        {
                    c++;
                    c %= 255;
                    write(fd,&c,1);
                    usleep(100000);
        }

        return NULL;
}

int main(int argc,char** argv)
{

        struct termios oldtio,newtio;
        struct sigaction sa;
        int ok;
        pthread_t th_a, th_b, th_c;
        void * retval;

        if( argc > 1)
                    fd = open(COM1, O_RDWR );
        else
                fd = open(COM2, O_RDWR );

        if (fd <0) {
                    perror(COM1);
                    exit(-1);
        }
        printf("\nOpen COM Port Successfull\n");
        tcgetattr(fd,&oldtio);


      tcflush(fd,TCIOFLUSH);
      cfsetispeed(&newtio,BAUDRATE);
      cfsetospeed(&newtio,BAUDRATE);

      newtio.c_cflag &= ~CSIZE;
      newtio.c_cflag |= CS8;

      newtio.c_cflag &= ~PARENB;
      newtio.c_iflag &= ~INPCK;

      newtio.c_cflag &= ~CSTOPB;
        newtio.c_cc=1;
        newtio.c_cc=0;



        tcflush(fd, TCIFLUSH);
      if(tcsetattr(fd,TCSANOW,&newtio) != 0)   {
                perror("\n");
                return 0;
      }

        sa.sa_handler = child_handler;
        sa.sa_flags = 0;
        sigaction(SIGCHLD,&sa,NULL);
        pthread_create(&th_a, NULL, keyboard, 0);
        pthread_create(&th_b, NULL, receive, 0);
        pthread_create(&th_c, NULL, send, 0);
        pthread_join(th_a, &retval);
        pthread_join(th_b, &retval);
        pthread_join(th_c, &retval);

        tcsetattr(fd,TCSANOW,&oldtio);
        close(fd);

        exit(0);
}
/*求大佬们改成手动从输入端口输入字符然后在接收端上显示字符,我是小白多写点注释,谢谢谢谢*/

isdkz 发表于 2023-11-16 13:51:29

// 代码中存在一些问题,需要进行修改以实现从输入端口输入字符,然后在接收端口上显示字符

#include <termios.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/signal.h>
#include <pthread.h>

#define BAUDRATE B115200
#define COM1 "/dev/pts/3" // 输入端口
#define COM2 "/dev/pts/4" // 接收端口
#define ENDMINITERM1 27
#define ENDMINITERM2 3
#define FALSE 0
#define TRUE 1

volatile int STOP = FALSE;
volatile int fd;

void child_handler(int s) {
    printf("停止!!!\n");
    STOP = TRUE;
}

void* keyboard(void* data) {
    char c;
    printf("请输入字符:\n");
    while (!STOP) {
      c = getchar(); // 从输入端口读取字符
      if (c == ENDMINITERM1 || c == ENDMINITERM2) {
            printf("终止\n");
            STOP = TRUE;
            break;
      }
      write(fd, &c, 1); // 将字符写入接收端口
    }
    return NULL;
}

void* receive(void* data) {
    char c;
    printf("接收数据\n");
    while (!STOP) {
      read(fd, &c, 1); // 从接收端口读取字符
      write(1, &c, 1); // 将字符显示在控制台上
    }
    printf("退出接收数据\n");
    return NULL;
}

int main(int argc, char** argv) {
    // ...(省略部分代码)

    if (argc > 1)
      fd = open(COM1, O_RDWR);
    else
      fd = open(COM2, O_RDWR);

    if (fd < 0) {
      perror(COM1);
      exit(-1);
    }
    printf("\n打开COM端口成功\n");
    tcgetattr(fd, &oldtio);

    // ...(省略部分代码)

    pthread_create(&th_a, NULL, keyboard, 0);
    pthread_create(&th_b, NULL, receive, 0);
    pthread_join(th_a, &retval);
    pthread_join(th_b, &retval);

    // ...(省略部分代码)

    exit(0);
}

这段代码的目的是从输入端口读取字符并将其写入接收端口,然后从接收端口读取字符并在控制台上显示。在 keyboard 函数中,使用 getchar 从输入端口读取字符,然后将字符写入接收端口。在 receive 函数中,从接收端口读取字符并在控制台上显示。

Mike_python小 发表于 2023-11-16 13:52:23

这段代码是一个简单的串口通讯示例,但有一些问题需要修复。首先,你需要在接收端和发送端之间建立虚拟串口连接,以便进行通信。其次,需要修改键盘输入的部分,使其能够手动从输入端口输入字符。下面是修改后的代码:


#include <termios.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/signal.h>
#include <pthread.h>

#define BAUDRATE B115200
#define COM1 "/dev/pts/3"
#define COM2 "/dev/pts/4"
#define ENDMINITERM1 27
#define ENDMINITERM2 3
#define FALSE 0
#define TRUE 1

volatile int STOP=FALSE;
volatile int fd;

void child_handler(int s) {
    printf("stop!!!\n");
    STOP=TRUE;
}

void* receive(void * data) {
    char c;
    printf("read modem\n");

    while (STOP==FALSE) {
      read(fd,&c,1);
      write(1,&c,1);
    }

    printf("exit from reading modem\n");
    return NULL;
}

void* send(void * data) {
    char c;
    printf("send data\n");

    while (STOP==FALSE) {
      c = getchar();// 从输入端口手动输入字符
      write(fd,&c,1);
    }

    return NULL;
}

int main(int argc,char** argv) {
    struct termios oldtio,newtio;
    int ok;
    pthread_t th_b, th_c;
    void * retval;

    if( argc > 1)
      fd = open(COM1, O_RDWR );
    else
      fd = open(COM2, O_RDWR );

    if (fd < 0) {
      perror(COM1);
      exit(-1);
    }
    printf("\nOpen COM Port Successfull\n");
    tcgetattr(fd,&oldtio);

    tcflush(fd,TCIOFLUSH);
    cfsetispeed(&newtio,BAUDRATE);
    cfsetospeed(&newtio,BAUDRATE);

    newtio.c_cflag &= ~CSIZE;
    newtio.c_cflag |= CS8;

    newtio.c_cflag &= ~PARENB;
    newtio.c_iflag &= ~INPCK;
    newtio.c_cflag &= ~CSTOPB;
    newtio.c_cc=1;
    newtio.c_cc=0;

    tcflush(fd, TCIFLUSH);
    if(tcsetattr(fd,TCSANOW,&newtio) != 0) {
      perror("\n");
      return 0;
    }

    pthread_create(&th_b, NULL, receive, 0);
    pthread_create(&th_c, NULL, send, 0);
    pthread_join(th_b, &retval);
    pthread_join(th_c, &retval);

    tcsetattr(fd,TCSANOW,&oldtio);
    close(fd);

    exit(0);
}


这个修改后的代码允许你在输入端口手动输入字符,然后在接收端显示字符。希望对你有所帮助。
页: [1]
查看完整版本: 通过终端模拟虚拟串口进行读写