鱼C论坛

 找回密码
 立即注册
查看: 1014|回复: 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
  1. // 代码中存在一些问题,需要进行修改以实现从输入端口输入字符,然后在接收端口上显示字符

  2. #include <termios.h>
  3. #include <stdio.h>
  4. #include <unistd.h>
  5. #include <stdlib.h>
  6. #include <fcntl.h>
  7. #include <sys/signal.h>
  8. #include <pthread.h>

  9. #define BAUDRATE B115200
  10. #define COM1 "/dev/pts/3" // 输入端口
  11. #define COM2 "/dev/pts/4" // 接收端口
  12. #define ENDMINITERM1 27
  13. #define ENDMINITERM2 3
  14. #define FALSE 0
  15. #define TRUE 1

  16. volatile int STOP = FALSE;
  17. volatile int fd;

  18. void child_handler(int s) {
  19.     printf("停止!!!\n");
  20.     STOP = TRUE;
  21. }

  22. void* keyboard(void* data) {
  23.     char c;
  24.     printf("请输入字符:\n");
  25.     while (!STOP) {
  26.         c = getchar(); // 从输入端口读取字符
  27.         if (c == ENDMINITERM1 || c == ENDMINITERM2) {
  28.             printf("终止\n");
  29.             STOP = TRUE;
  30.             break;
  31.         }
  32.         write(fd, &c, 1); // 将字符写入接收端口
  33.     }
  34.     return NULL;
  35. }

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

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

  48.     if (argc > 1)
  49.         fd = open(COM1, O_RDWR);
  50.     else
  51.         fd = open(COM2, O_RDWR);

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

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

  59.     pthread_create(&th_a, NULL, keyboard, 0);
  60.     pthread_create(&th_b, NULL, receive, 0);
  61.     pthread_join(th_a, &retval);
  62.     pthread_join(th_b, &retval);

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

  64.     exit(0);
  65. }
复制代码

这段代码的目的是从输入端口读取字符并将其写入接收端口,然后从接收端口读取字符并在控制台上显示。在 keyboard 函数中,使用 getchar 从输入端口读取字符,然后将字符写入接收端口。在 receive 函数中,从接收端口读取字符并在控制台上显示。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

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

回帖奖励 +80 鱼币

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

  2. #include <termios.h>
  3. #include <stdio.h>
  4. #include <unistd.h>
  5. #include <stdlib.h>
  6. #include <fcntl.h>
  7. #include <sys/signal.h>
  8. #include <pthread.h>

  9. #define BAUDRATE B115200
  10. #define COM1 "/dev/pts/3" // 输入端口
  11. #define COM2 "/dev/pts/4" // 接收端口
  12. #define ENDMINITERM1 27
  13. #define ENDMINITERM2 3
  14. #define FALSE 0
  15. #define TRUE 1

  16. volatile int STOP = FALSE;
  17. volatile int fd;

  18. void child_handler(int s) {
  19.     printf("停止!!!\n");
  20.     STOP = TRUE;
  21. }

  22. void* keyboard(void* data) {
  23.     char c;
  24.     printf("请输入字符:\n");
  25.     while (!STOP) {
  26.         c = getchar(); // 从输入端口读取字符
  27.         if (c == ENDMINITERM1 || c == ENDMINITERM2) {
  28.             printf("终止\n");
  29.             STOP = TRUE;
  30.             break;
  31.         }
  32.         write(fd, &c, 1); // 将字符写入接收端口
  33.     }
  34.     return NULL;
  35. }

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

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

  48.     if (argc > 1)
  49.         fd = open(COM1, O_RDWR);
  50.     else
  51.         fd = open(COM2, O_RDWR);

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

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

  59.     pthread_create(&th_a, NULL, keyboard, 0);
  60.     pthread_create(&th_b, NULL, receive, 0);
  61.     pthread_join(th_a, &retval);
  62.     pthread_join(th_b, &retval);

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

  64.     exit(0);
  65. }
复制代码

这段代码的目的是从输入端口读取字符并将其写入接收端口,然后从接收端口读取字符并在控制台上显示。在 keyboard 函数中,使用 getchar 从输入端口读取字符,然后将字符写入接收端口。在 receive 函数中,从接收端口读取字符并在控制台上显示。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-11-16 13:52:23 | 显示全部楼层
这段代码是一个简单的串口通讯示例,但有一些问题需要修复。首先,你需要在接收端和发送端之间建立虚拟串口连接,以便进行通信。其次,需要修改键盘输入的部分,使其能够手动从输入端口输入字符。下面是修改后的代码:
  1. #include <termios.h>
  2. #include <stdio.h>
  3. #include <unistd.h>
  4. #include <stdlib.h>
  5. #include <fcntl.h>
  6. #include <sys/signal.h>
  7. #include <pthread.h>
  8. #define BAUDRATE B115200
  9. #define COM1 "/dev/pts/3"
  10. #define COM2 "/dev/pts/4"
  11. #define ENDMINITERM1 27
  12. #define ENDMINITERM2 3  
  13. #define FALSE 0
  14. #define TRUE 1
  15. volatile int STOP=FALSE;
  16. volatile int fd;
  17. void child_handler(int s) {
  18.     printf("stop!!!\n");
  19.     STOP=TRUE;
  20. }
  21. void* receive(void * data) {
  22.     char c;
  23.     printf("read modem\n");
  24.     while (STOP==FALSE) {
  25.         read(fd,&c,1);
  26.         write(1,&c,1);
  27.     }
  28.     printf("exit from reading modem\n");
  29.     return NULL;
  30. }
  31. void* send(void * data) {
  32.     char c;
  33.     printf("send data\n");
  34.     while (STOP==FALSE) {
  35.         c = getchar();  // 从输入端口手动输入字符
  36.         write(fd,&c,1);
  37.     }
  38.     return NULL;
  39. }
  40. int main(int argc,char** argv) {
  41.     struct termios oldtio,newtio;
  42.     int ok;
  43.     pthread_t th_b, th_c;
  44.     void * retval;
  45.     if( argc > 1)
  46.         fd = open(COM1, O_RDWR );
  47.     else  
  48.         fd = open(COM2, O_RDWR );
  49.     if (fd < 0) {
  50.         perror(COM1);
  51.         exit(-1);
  52.     }
  53.     printf("\nOpen COM Port Successfull\n");
  54.     tcgetattr(fd,&oldtio);
  55.     tcflush(fd,TCIOFLUSH);
  56.     cfsetispeed(&newtio,BAUDRATE);
  57.     cfsetospeed(&newtio,BAUDRATE);
  58.     newtio.c_cflag &= ~CSIZE;
  59.     newtio.c_cflag |= CS8;
  60.     newtio.c_cflag &= ~PARENB;
  61.     newtio.c_iflag &= ~INPCK;  
  62.     newtio.c_cflag &= ~CSTOPB;
  63.     newtio.c_cc[VMIN]=1;
  64.     newtio.c_cc[VTIME]=0;
  65.     tcflush(fd, TCIFLUSH);
  66.     if(tcsetattr(fd,TCSANOW,&newtio) != 0) {
  67.         perror("\n");
  68.         return 0;
  69.     }
  70.     pthread_create(&th_b, NULL, receive, 0);
  71.     pthread_create(&th_c, NULL, send, 0);
  72.     pthread_join(th_b, &retval);
  73.     pthread_join(th_c, &retval);
  74.     tcsetattr(fd,TCSANOW,&oldtio);
  75.     close(fd);
  76.     exit(0);
  77. }
复制代码

这个修改后的代码允许你在输入端口手动输入字符,然后在接收端显示字符。希望对你有所帮助。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-4-21 15:36

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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