.NET Framework
Porty szeregowe
Szukaj…
Podstawowa operacja
var serialPort = new SerialPort("COM1", 9600, Parity.Even, 8, StopBits.One);
serialPort.Open();
serialPort.WriteLine("Test data");
string response = serialPort.ReadLine();
Console.WriteLine(response);
serialPort.Close();
Wyświetl dostępne nazwy portów
string[] portNames = SerialPort.GetPortNames();
Odczyt asynchroniczny
void SetupAsyncRead(SerialPort serialPort)
{
serialPort.DataReceived += (sender, e) => {
byte[] buffer = new byte[4096];
switch (e.EventType)
{
case SerialData.Chars:
var port = (SerialPort)sender;
int bytesToRead = port.BytesToRead;
if (bytesToRead > buffer.Length)
Array.Resize(ref buffer, bytesToRead);
int bytesRead = port.Read(buffer, 0, bytesToRead);
// Process the read buffer here
// ...
break;
case SerialData.Eof:
// Terminate the service here
// ...
break;
}
};
Usługa synchronicznego echa tekstu
using System.IO.Ports;
namespace TextEchoService
{
class Program
{
static void Main(string[] args)
{
var serialPort = new SerialPort("COM1", 9600, Parity.Even, 8, StopBits.One);
serialPort.Open();
string message = "";
while (message != "quit")
{
message = serialPort.ReadLine();
serialPort.WriteLine(message);
}
serialPort.Close();
}
}
}
Asynchroniczny odbiornik wiadomości
using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Text;
using System.Threading;
namespace AsyncReceiver
{
class Program
{
const byte STX = 0x02;
const byte ETX = 0x03;
const byte ACK = 0x06;
const byte NAK = 0x15;
static ManualResetEvent terminateService = new ManualResetEvent(false);
static readonly object eventLock = new object();
static List<byte> unprocessedBuffer = null;
static void Main(string[] args)
{
try
{
var serialPort = new SerialPort("COM11", 9600, Parity.Even, 8, StopBits.One);
serialPort.DataReceived += DataReceivedHandler;
serialPort.ErrorReceived += ErrorReceivedHandler;
serialPort.Open();
terminateService.WaitOne();
serialPort.Close();
}
catch (Exception e)
{
Console.WriteLine("Exception occurred: {0}", e.Message);
}
Console.ReadKey();
}
static void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
lock (eventLock)
{
byte[] buffer = new byte[4096];
switch (e.EventType)
{
case SerialData.Chars:
var port = (SerialPort)sender;
int bytesToRead = port.BytesToRead;
if (bytesToRead > buffer.Length)
Array.Resize(ref buffer, bytesToRead);
int bytesRead = port.Read(buffer, 0, bytesToRead);
ProcessBuffer(buffer, bytesRead);
break;
case SerialData.Eof:
terminateService.Set();
break;
}
}
}
static void ErrorReceivedHandler(object sender, SerialErrorReceivedEventArgs e)
{
lock (eventLock)
if (e.EventType == SerialError.TXFull)
{
Console.WriteLine("Error: TXFull. Can't handle this!");
terminateService.Set();
}
else
{
Console.WriteLine("Error: {0}. Resetting everything", e.EventType);
var port = (SerialPort)sender;
port.DiscardInBuffer();
port.DiscardOutBuffer();
unprocessedBuffer = null;
port.Write(new byte[] { NAK }, 0, 1);
}
}
static void ProcessBuffer(byte[] buffer, int length)
{
List<byte> message = unprocessedBuffer;
for (int i = 0; i < length; i++)
if (buffer[i] == ETX)
{
if (message != null)
{
Console.WriteLine("MessageReceived: {0}",
Encoding.ASCII.GetString(message.ToArray()));
message = null;
}
}
else if (buffer[i] == STX)
message = null;
else if (message != null)
message.Add(buffer[i]);
unprocessedBuffer = message;
}
}
}
Ten program czeka na wiadomości zawarte w bajtach STX
i ETX
i wysyła tekst między nimi. Cała reszta jest odrzucana. Po przepełnieniu bufora zapisu, zatrzymuje się. W przypadku innych błędów resetuje bufory wejściowe i wyjściowe i czeka na dalsze komunikaty.
Kod ilustruje:
- Odczytywanie asynchronicznego portu szeregowego (patrz użycie
SerialPort.DataReceived
). - Przetwarzanie błędu portu szeregowego (patrz użycie
SerialPort.ErrorReceived
). - Implementacja protokołu nietekstowego.
- Częściowe czytanie wiadomości.
- Zdarzenie
SerialPort.DataReceived
może nastąpić wcześniej niż nadejdzie cała wiadomość (doETX
). Cała wiadomość może również nie być dostępna w buforze wejściowym (SerialPort.Read (..., ..., port.BytesToRead) czyta tylko część wiadomości). W takim przypadku przechowujemy otrzymaną część (unprocessedBuffer
) i czekamy na dalsze dane.
- Zdarzenie
- Radzenie sobie z kilkoma wiadomościami przychodzącymi za jednym razem.
- Zdarzenie
SerialPort.DataReceived
może nastąpić dopiero po wysłaniu kilku wiadomości przez drugi koniec.
- Zdarzenie
Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow