首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >用C#和C语言进行USB到串行通信

用C#和C语言进行USB到串行通信
EN

Stack Overflow用户
提问于 2013-12-18 08:57:24
回答 2查看 3.3K关注 0票数 2

这是我第一次发布我的查询。我需要帮助。任何帮助都是非常感谢的。

因为我同意我已经把我的预言说成是长话短说。但很抱歉,我没有弄明白如何使它短,我的意图是提供完整的信息,我的计划。

问题:我必须在windows平台上使用USB到串行适配器在两台笔记本电脑之间进行通信.我写了两个程序,一个发送程序,一个接收程序。程序用C语言和C#编程语言编写。

使用C语言:我能够成功地使用下面提到的C程序进行通信.但问题是速度。只要超过150 It,大约需要1小时(60分钟)。任何人请帮助我提高这个程序的性能,或者你可以建议我其他的方法,这是健壮和高性能的。我还提到了一些评论和自我理解的程序。

带有串行端口的膝上型计算机上的发送方文件:

代码语言:javascript
代码运行次数:0
运行
复制
#include <stdio.h>
#include <bios.h>
#include <conio.h>
#define COM1       0
#define DATA_READY 0x100
#define TRUE       1
#define FALSE      0
#define SETTINGS ( 0xE0 | 0x03 | 0x00 | 0x00)

int main(void)
{
   int in, out, status, DONE = FALSE,i=0;
   char c;
   FILE *fp,*fp1;
   unsigned long count = 0,shiftcount = 0;

   clrscr();

   fp = fopen("C:/TC/pic.jpg","rb"); //opened for reading actual content
   fp1 = fopen("C:/TC/pic.jpg","rb"); //opened for reading the size of file

   fseek(fp1,0L,2);
   count = ftell(fp1) + 1; // file size

   bioscom(0, SETTINGS, COM1); // initializing the port

   printf("No. of Characters = %lu\n",count);

// since bioscom function can send or receive only 8bits at a time, am sending file size in
    4 rounds so that we can send at max of 4GB file.

   bioscom(1,count,COM1); // sneding 1st lower 8bits 

   bioscom(1,count>>8,COM1); // sending 2nd set of lower 8bits

   bioscom(1,count>>16,COM1); // sending 3rd set of lower 8bits

   bioscom(1,count>>24,COM1); // sending upper 8 bits

   cprintf("... BIOSCOM [ESC] to exit ...\n");
   while (!DONE)
   {
      status = bioscom(3, 0, COM1);// get the status of port
      //printf("%d",status);
      if (status & DATA_READY) //checks if data is ready
      {
        out = bioscom(2, 0, COM1); // receives the ack
        if(!feof(fp))
        {
            c = fgetc(fp); //read character by character from file
            bioscom(1,c,COM1);//send character to receiver
            putch(c);//display
        }
     }

//to interrupt
     if (kbhit())
     {
        if ((in = getch()) == '\x1B')
           DONE = TRUE;
     }
   }
   fclose(fp);
   return 0;
}

通过USB端口在笔记本电脑上接收文件:

代码语言:javascript
代码运行次数:0
运行
复制
#include <stdio.h>
#include <bios.h>
#include <conio.h>

#define COM4       3
#define DATA_READY 0x100
#define TRUE       1
#define FALSE      0

#define SETTINGS ( 0xE0 | 0x03 | 0x00 | 0x00)

int main(void)
{
   int in, out, status;
   char c;
   FILE *fp;
   unsigned long shiftcount1=0,shiftcount2=0,shiftcount3=0,shiftcount4=0;
   unsigned long count = 0, DONE = 1;

   clrscr();

   fp = fopen("C:/TC/pic1.jpg","wb");// file opened for writing

   bioscom(0, SETTINGS, COM4);//initialize tyhe port
   cprintf("... BIOSCOM [ESC] to exit ...\n");
//receives all the 32 bits of file size sent from sender
   shiftcount1 = bioscom(2,0,COM4);
   shiftcount2 = bioscom(2,0,COM4);
   shiftcount3 = bioscom(2,0,COM4);
   shiftcount4 = bioscom(2,0,COM4);

//send an ack
   bioscom(1,'x',COM4);

   count = shiftcount1 | (shiftcount2<<8) | (shiftcount3<<16) | (shiftcount4<<24);

   printf("shift4 = %lu\tshift3 = %lu\tshift2 = %lu\tshift1 = %lu\n",shiftcount4,shiftcount3,shiftcount2,shiftcount1);
   printf("File Size = %lu\n",count);

//loop till the size of the file
   while (DONE < count)
   {
      status = bioscom(3, 0, COM4);// check the status
     // printf("%d",status);
      if (status & DATA_READY)//check for data ready at the port
      {
        out = bioscom(2, 0, COM4);//receive the data
        DONE++;
        fputc(out,fp);
        putch(out);
        bioscom(1,'x',COM4);//send an ack
      }


     if (kbhit())
     {
        if ((in = getch()) == '\x1B')
        break;
     }
   }
   fclose(fp);
   return 0;
}

带有USB端口的膝上型计算机上的发送文件:

代码语言:javascript
代码运行次数:0
运行
复制
#include <stdio.h>
#include <bios.h>
#include <conio.h>
#include<dos.h>
#include<stdlib.h>
#include<time.h>

#define RTS 0x02
#define COM1       0
#define COM4       3
#define CURRCOM   COM4
#define DATA_READY 0x100
#define TRUE       1
#define FALSE      0

#define SETTINGS ( 0xE0 | 0x03 | 0x00 | 0x00)

int main(void)
{
   int in, out, status, DONE = FALSE,nextfile = 1;
   char c;
   FILE *fp,*fp1;
   unsigned long count = 0,shiftcount = 0;
   clock_t start,end;

   start = clock();

   clrscr();

   fp = fopen("C:/TC/pic.jpg","rb");
   fp1 = fopen("C:/TC/pic.jpg","rb");

   fseek(fp1,0L,2);
   count = ftell(fp1) + 1;

   bioscom(0, SETTINGS, CURRCOM);

  /*  while(!feof(fp1))
    {
    c = fgetc(fp1);
    count++;
    } */


   printf("No. of Cheracters = %lu\n",count);


    bioscom(1,count,CURRCOM);

    bioscom(1,count>>8,CURRCOM);

    bioscom(1,count>>16,CURRCOM);

    bioscom(1,count>>24,CURRCOM);

   cprintf("\n... BIOSCOM [ESC] to exit ...\n");
   while (!DONE)
   {
      status = bioscom(3, 0, CURRCOM);
      if (status & DATA_READY)
      {
        out = bioscom(2,0,CURRCOM);

        if(!feof(fp))
        {
            c = fgetc(fp);
            bioscom(1,c,CURRCOM);
            putch(c);
        }
      }

     if (kbhit())
     {
        if ((in = getch()) == '\x1B')
           DONE = TRUE;
     }
   }
   fclose(fp);

   end = clock();
   printf("\nTotal time = %d\n",(end - start)/CLK_TCK);

   return 0;
}

带有串口的膝上型计算机上的接收器文件:

代码语言:javascript
代码运行次数:0
运行
复制
#include <stdio.h>
#include <bios.h>
#include <conio.h>
#include<time.h>

#define COM1       0
#define DATA_READY 0x100
#define TRUE       1
#define FALSE      0

#define SETTINGS ( 0xE0 | 0x03 | 0x00 | 0x00)

int main(void)
{
   int in, out, status;
   char c;
   FILE *fp;
   int y = 0,esc;
   unsigned long count=0,shiftcount1 = 0,shiftcount2 = 0,shiftcount3 = 0,shiftcount4 = 0, DONE = 1;

   clock_t start,end;

   start = clock();

   clrscr();

   fp = fopen("C:/TC/pic1.jpg","wb");

   bioscom(0, SETTINGS, COM1);
   cprintf("... BIOSCOM [ESC] to exit ...\n");

   shiftcount1 = bioscom(2,0,COM1);
   shiftcount2 = bioscom(2,0,COM1);
   shiftcount3 = bioscom(2,0,COM1);
   shiftcount4 = bioscom(2,0,COM1);

   bioscom(1,'x',COM1);

   count = shiftcount1 | (shiftcount2<<8) | (shiftcount3<<16) | (shiftcount4<<24);

   printf("shift4 = %lu\tshift3 = %lu\tshift2 = %lu\t shift1 = %lu\n",shiftcount4,shiftcount3,shiftcount2,shiftcount1);
   printf("file size = %lu\n",count);

   while (DONE < count)
   {
      status = bioscom(3, 0, COM1);
      //printf("%d",status);
      if (status & DATA_READY)
      {
        out = bioscom(2, 0, COM1);
        DONE++;
        fputc(out,fp);
        putch(out);
        bioscom(1,'x',COM1);
      }


     if (kbhit())
     {
        if ((in = getch()) == '\x1B')
           break;
     }
   }
   fclose(fp);

   end = clock();
   printf("\nTotal time = %f\n",(end - start)/CLK_TCK);

   return 0;
}

以上4个程序作为发送者发送一个字符并接收每个字符的ack。我采用了这种方法,因为其他方法没有很好地工作(在这个意义上,没有发送完整的数据,发送的数据量是无法判断的,因为它会因类型不同而不同)。当我使用这种方法时,效果很好。

使用C#语言:下面两个程序是使用visual用C#编写的。我使用了SerilaPort类、它的属性和通信方法。利用此,可以将successfully.Also图像文件的两侧的.jpg图像文件与.jpg扩展通信,可以在没有任何数据丢失(成功传输)的情况下从USB传输到串行端,但是如果我从串行传输到usb端,就可以接收到一些数据丢失的图像,即使是数据丢失也能看到图像。

带有串口的膝上型计算机上的发送方文件:

代码语言:javascript
代码运行次数:0
运行
复制
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Ports;
using System.IO;
using System.Threading;

namespace Communication
{
    class Program
    {
        static void Main(string[] args)
        {

            string name;
            string message;
            StringComparer stringComparer = StringComparer.OrdinalIgnoreCase;
            //Thread readThread = new Thread(Read);


            FileStream fs = new FileStream("C:/text.xml", FileMode.Open);

            //StreamReader sr = new StreamReader(fs);

            BinaryReader br = new BinaryReader(fs);

            // Create a new SerialPort object with default settings.
            SerialPort _serialPort = new SerialPort();

            // Allow the user to set the appropriate properties.
            _serialPort.PortName = "COM1";
            _serialPort.BaudRate = 115200;
            _serialPort.Parity = Parity.None;
            _serialPort.DataBits = 8;
            _serialPort.StopBits = StopBits.One;
            _serialPort.Handshake = Handshake.None;

            // Set the read/write timeouts
            _serialPort.ReadTimeout = 500;
            _serialPort.WriteTimeout = 500;

            _serialPort.Open(); 
            bool _continue = true;
            //readThread.Start();

            int len = (int)fs.Length;
            char[] data = new char[len+1];

            br.Read(data, 0, len);

            for (int i = 0; i < len+1; i++)
            {
                _serialPort.Write(data, i, 1);
                //Console.Write(data,i,1);
            }

            br.Close();
            fs.Close();
            _serialPort.Close();

        }
    }
}

带有USB端口的膝上型计算机接收器文件:

代码语言:javascript
代码运行次数:0
运行
复制
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Ports;
using System.IO;
using System.Threading;
using System.Collections;

namespace Communication
{
    class Program
    {
        static void Main(string[] args)
        {
            SerialComm comm = new SerialComm();
            comm.Init();
            comm.ReadSerial();
            comm.WriteToFile();
            comm.ResClose();
            Console.ReadKey();
        }
    }


    class SerialComm
    {
        FileStream fs = null;
        BinaryWriter file = null;
        ArrayList al = null;

        public Boolean Init()
        {
            if (fs == null)
            {
                fs = new FileStream("C:/text1.txt", FileMode.OpenOrCreate);
            }

            if (file == null)
            {
                file = new BinaryWriter(fs);
            }
            if (al == null)
            {
                al = new ArrayList();
            }

            return true;
        }

        public void ResClose()
        {
            file.Close();
            fs.Close();
        }


        public Boolean ReadSerial()
        {
            SerialPort port;
            StreamWriter sw;
            ConsoleKeyInfo ck;

            port = new SerialPort();

            port.PortName = "COM4";
            port.BaudRate = 115200;
            port.DataBits = 8;
            port.Parity = Parity.None;
            port.StopBits = StopBits.One;
            port.Handshake = Handshake.None;

            port.Open();

            port.BaseStream.Flush();
            port.DiscardInBuffer();
            int c = 1;
            while (c != 0)
            {
                c = port.ReadByte();
                al.Add((byte)c);
            }
            return true;
        }

        public void WriteToFile()
        {
            int i = 0;
            byte[] message = al.ToArray(typeof(byte)) as byte[];
            file.Write(message, 0, message.Length - 1);
        }
   }
}

请帮帮我。

提前谢谢。

EN

回答 2

Stack Overflow用户

发布于 2013-12-18 09:20:19

传输速度:

串行端口简单,不快。我假设您使用的是230 many,这已经超出了许多硬件所能处理的范围。压缩是唯一可能有帮助的事情,但是压缩已经压缩的数据(如.mp3)不会有多大帮助。

数据丢失:

串行端口简单,不健壮。数据丢失是很常见的,您唯一能做的就是有协议来检测传入帧上的错误,并且有能力在出现错误时重试发送。

结论:

使用TCP/IP代替。

票数 3
EN

Stack Overflow用户

发布于 2013-12-18 09:20:27

这个问题太长了。我只发现了一个真正的问题,那就是性能问题。

只需使用以太网或WiFi。“串口”(您可能指的是RS-232)的速度是。0.1Mbit/秒被RS-232标准认为是快速的。时钟为1200 Mbit/3600秒,即0.3 Mbit/秒。太快了。事实上,我很惊讶您实现了这一点,您的C#程序显式地将速度设置为0.1Mbit/秒。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20653528

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档