鱼C论坛

 找回密码
 立即注册
查看: 691|回复: 2

[已解决]通过终端模拟虚拟串口进行读写

[复制链接]
发表于 2023-11-16 13:51:13 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
#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[VMIN]=1;
        newtio.c_cc[VTIME]=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);
}
/*求大佬们改成手动从输入端口输入字符然后在接收端上显示字符,我是小白多写点注释,谢谢谢谢*/
最佳答案
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 函数中,从接收端口读取字符并在控制台上显示。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-11-16 13:51:29 | 显示全部楼层    本楼为最佳答案   

回帖奖励 +80 鱼币

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

#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 函数中,从接收端口读取字符并在控制台上显示。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 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 1volatile 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[VMIN]=1;    newtio.c_cc[VTIME]=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); }
这个修改后的代码允许你在输入端口手动输入字符,然后在接收端显示字符。希望对你有所帮助。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-2-3 07:15

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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