gpt4 book ai didi

c# - 使用 C# 和 C 语言的 USB 到串行(来回)通信

转载 作者:行者123 更新时间:2023-11-30 20:52:44 28 4
gpt4 key购买 nike

这是我第一次发布查询。我需要帮助。感谢您的帮助。

我同意我已经把我的概率作为一个长篇故事。但很抱歉,我不知道如何缩短它,我的目的是提供有关我的问题的完整信息。

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

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

带串行端口的笔记本电脑上的发送文件:

#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 端口的笔记本电脑上接收文件:

#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 端口的笔记本电脑上发送文件:

#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;
}

带串口的笔记本电脑接收文件:

#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 个程序的行为是,发送方发送一个字符并接收每个字符的确认。我已经采用了这种方法,因为其他方法无法正常工作(从某种意义上说,没有发送完整的数据,发送的数据量是不可判断的,因为每个时间都会不同)。当我使用这种方法时,效果很好。

使用 C# 语言:下面两个程序是使用 visual studio 用 C# 编写的。我已经使用 SerilaPort 类,它的属性和方法进行通信。使用这个,我能够成功地在双方传输文本和 xml 文件。还有带有 .jpg 扩展名的图像文件,可以从 USB 传输到串行端而不会丢失任何数据(成功传输),但是如果我从串行传输到usb 端,可以接收一些数据丢失的图像,即使数据丢失也可以看到图像。

带串行端口的笔记本电脑上的发送文件:

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接口(interface)的笔记本电脑上的接收文件:

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);
}
}
}

请帮帮我。

提前致谢。

最佳答案

传输速度:

串口简单,速度不快。我假设您使用的是 230kbps,这已经超出了许多硬件的处理能力。压缩只是可能有用的东西,但压缩已经压缩的数据(如 .mp3)不会有太大帮助。

数据丢失:

串口很简单,但不够健壮。数据丢失很常见,对此您唯一能做的就是使用协议(protocol)来检测传入帧上的错误,并能够在出现错误时重试发送。

结论:

改用 TCP/IP。

关于c# - 使用 C# 和 C 语言的 USB 到串行(来回)通信,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20653528/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com