Работа с COM-портом в compact framework C#

 

.net rs232

Работа с COM-портом в C# очень проста, для реализации используется класс  System.IO.Ports.SerialPort. Как всегда в начале надо проинициализировать COM-порт вызовом конструктора

System.IO.Ports.SerialPort("COM1",9600,System.IO.Ports.Parity.None,

    8,System.IO.Ports.StopBits.One);

Этой функцией задаем COM1 первый ком порт, скорость обмена 9600, отсутствие паритета, 8 бит в посылке, один стоп бит, т.е. наиболее популярные значения.

Затем порт готов к использованию.

public class RsExchange

{
    System.IO.Ports.SerialPort rs_port;
    public void InitRs()                           
   {
        rs_port = new System.IO.Ports.SerialPort("COM1", 9600,
            System.IO.Ports.Parity.None,
            8,
            System.IO.Ports.StopBits.One);

if (rs_port.IsOpen == true)
             rs_port.Close();

rs_port.Open();
    }
}

Функция запрос-ответ


//
Отправка команды управления (выставление дискретных выходов)
public int SetCmd (int num)                
{         
    byte[] data = new byte[4];
    data[0] = 64;       // '@'
    data[1] = 90;
    data[2] = (byte)num;
    data[3] = crc8(data, 3);
    rs_port.Write(data, 0, 4);  
       //  Отправляем запрос, ждем 100 мс и смотрим что пришло в ответ

System.Threading.Thread.Sleep(100);

if (rs_port.BytesToRead > 0)
    {
        byte[] answer = new byte[(int)rs_port.BytesToRead];   
        //  Читаем буфер для анализа ответа на команду управления
        rs_port.Read(answer, 0, rs_port.BytesToRead);
        return 0;
    }
   
    return -1;
     //  Если не пришло вообще никакого ответа,
     //   возвращаем отрицательное значение
}       


В этой функции представлен пример отправки-приема данных из одного проекта. Сначала мы отправляем запрос на девайс, затем получаем ответ (аналогично с modbus, только проще).

byte[] data = new byte[4]; - заготовка для отправки данных на девайс

Заполняем массив данными.
data[0] = 64; // '@'

data[1] = 90;
data[2] = (byte)num;

Последний байт - crc8 от посылки, функция crc8 описана в программе. CRC8 часто используется в работе с COM-портом, она позволяет исключать неправильные посылки на линии, часто возникающие из-за помех. 

           data[3] = crc8(data, 3);

Теперь отправляем данные на девайс

            rs_port.Write(data, 0, 4);  

Ждем какое-то время пока сформируется ответ
            System.Threading.Thread.Sleep(100);

И смотрим, пришел ли ответ (может не быть ответа совсем, если девайс, например, не подключен)
            if (rs_port.BytesToRead > 0)

Если ответ пришел, то считываем все данные с порта в массив и возвращаем 0. Если ничего не пришло, возвращаем -1.
                byte[] answer = new byte[(int)rs_port.BytesToRead];   

                rs_port.Read(answer, 0, rs_port.BytesToRead);
                return 0;

Вобщем-то в C# нет никаких проблем реализовать работу с COM-портом, если не требует сверхбыстродействия и моментальной реакции на приходящие по порту элементы. В своей программе я использовал 100 мс задержку до получения ответа, предполагая что ответ либо придет полностью, либо нет. В этом случае девайс должен точно отвечать за время, меньшее 100мс, иначе система не будет работать вообще. С другой стороны, если неизвестно время ответа девайса или нужно быстродействие, то можно использовать получение данных по событию "пришел новый символ" и каждый раз пополнять массив данных. Реализация этого метода немного сложнее, но незначительно. В любом случае я бы не рекомендовал использовать COM-порт (как и все производные UART-интерфейса) стационарного компьютера для синхронизации по времени чего-либо, хороших результатов это не даст, т.к. сама операционная система в большинстве случае не real-time, что не дает возможности прогнозирования времени отклика COM-порта на команду, да и сам язык C# не самый лучший выбор для быстродействующих приложений (в сравнении даже с C++ и уж тем более классическим C). Но у C# есть определенный плюс - сборка exe-файла является кроссплатформенной, т.е. это исполняемый файл я запускал и на win64, и на win32, и даже на WinCE 6.0. Проект даже не надо пересобирать, что логично. Но приятно, когда создается код для встраиваемой платформы на основе WinCE, а отлаживать возможно на стационарном x86, не переделывая потом даже exe-файл под другую архитектуру, что необходимо Qt.

 

Ссылка на файл с программой

Program.cs