Com порт с

Содержание

Com порт с не хватало, по вашему коду

Свойства блока данных:
— Длина блока 8 б.
— Дальше 4 значения по 2 б

C# com-порт получение информации, обработка старт-бита, стоп-бита?

Прошу помощи в осознании, а может и в решении интересующего меня вопроса.

Поначалу обрисую сущность поставленного передо мной задания, предупрежу сходу в программировании я, так сказать, очень юный и это в некий степени мой 1-ый проект, который я желаю воплотить на платформе visual studio.

Задачка:
Есть некое устройство, которое соединяется с компьютером по RS-485 и передает данные 38400 бит/сек, устройство может передавать пакеты с дискретностью 25 Гц или 50Гц.

Командно-информационный пакет, передаваемый устройством, состоит из 6 блоков, сначала каждого пакета передается маркер начала пакета «0xFF, 0xFF», затем идут 6 блоков данных в конце пакета передается 2-х байтовое поле .В конце идет бит четности (формируется при выполнении операции «Исключающее ИЛИ «четное число логических единиц в байте должно соответствовать биту чётности 0 ) и 2 стоповых бита.

— Длина одного пакета 52 байта.
— Время паузы между двумя пакетами менее 2-х бит.

Характеристики блока данных:
— Длина блока 8 байт.
— Далее 4 значения по 2 байта

Собственно вопрос, который меня интересует: как это все правильно организовать.

Сперва я кинулся искать как работать с COM-портом, наткнулся на пространство имен:

using System.IO; using System.IO.Ports;

Ну, и сперва, как мудрый ВАСЯ, определяю доступные порты в системе и вывожу их в combobox.

private void Form1_Load(object sender, EventArgs e) < //чтение портов доступных в системе string[] ports = SerialPort.GetPortNames(); //Очистка содержимого бокса comboBox1.Items.Clear(); //Добавление найденных портов в бокс comboBox1.Items.AddRange(ports); >

Далее, по кнопке старт я запускаю само чтение данных приходящих с устройства. Вот тут для меня начинается дремучий лес.

private void button1_Click(object sender, EventArgs e) < //выбранный порт Object selectedItem = comboBox1.SelectedItem; //Создаю объект port1 с параметрами. //selectedItem.ToString() - порт к которому подключено устройство. //9600 скорость передачи данных в порт, как я понял 9600 бод - 38400 бит/сек. //Parity.None бит четности установил в отсутствие так как пока не сильно понимаю что с ним делать об этом далее. //416 бит данных т.е. 8*52 = 416. //один стоп бит SerialPort port1 = new SerialPort(selectedItem.ToString(), 9600, Parity.None, 416, StopBits.One); //Открываю порт. port1.Open(); //тут я писал разного рода код для вывода полученных данных в текстовое поле но получал один бред. >

Теперь вопрос:
Как я понимаю эту проблему — в порт записываются данные, переданные устройством, а мне их необходимо считать.
Как мне правильно дождаться начала пакета «0xFF,0xFF», чтобы после это принимать оставшуюся часть пакета, или прием стоит начать после получения конца предыдущего пакета?

Если у кого-то есть подобные коды обработки ожидания начала или конца пакетов и нет желания объяснять, просьба скинуть участки кода буду разбираться сам.

После правильного начала приема пакетов мне их необходимо рассортировать, ничего лучше чем засунуть принятый пакет в переменную последовательности байт я не нашел, точнее это можно сказать единственное, что улеглось в моей голове.

private void button1_Click(object sender, EventArgs e) < Object selectedItem = comboBox1.SelectedItem; SerialPort port1 = new SerialPort(selectedItem.ToString(), 9600, Parity.None, 416, StopBits.One); port1.Open(); //создаю массив размером 52 т.е на запись 52 байт переданного с устройства пакетов byte[] data1 = new byte[52]; //Ну и запускаю команду чтения в массив data1 port.Read(data1, 0, data1.Length); int databyte = port.ReadByte(); >

Но приходит мне какая то ересь.
Правильно ли я понимаю этот процесс чтения из com-порта?

Просьба пнуть, ткнуть, дать леща или помочь в решении данного задания кому как будет угодно.

Кто знает что почитать конкретно по этому вопросу, где доступно написано или есть подобные решения просьба скинуть почитать что бы лучше разбираться.

Пока как то так. Буду признателен любой помощи, подсказке, куску кода.

  • Вопрос задан более трёх годов назад
  • 53939 просмотров

Комментировать
Решения вопроса 3

ПОДКЛЮЧАЕМ SERIAL COM PORT — C++ WINAPI ЧАСТЬ #8

Если я правильно понял ваш вопрос, то ваше устройство шлёт постоянно данные и вам нужно только читать.
Все что вам нужно, это создать подключение к порту и подписаться на событие обновления. При возникновении события вы получите массив данных с порта, этот массив вы сохраняете в буфер или разбираете на лету (как вам удобнее). Напишу вам маленький пример:

// Наследуем наш клас от SerialPort для более красивого кода public class MySerialPort : SerialPort < private const int DataSize = 54; // я так и не понял, какой размер данных нужен. Укажите правильное число в байтах private readonly byte[] _bufer = new byte[DataSize]; private int _stepIndex; private bool _startRead; public MySerialPort(string port) : base() < // все папаметры вы должны указать в соответствии с вашим устройством //base.PortName = COM1; base.BaudRate = 115200; base.DataBits = 8; base.StopBits = StopBits.Two; base.Parity = Parity.None; base.ReadTimeout = 1000; // тут подписываемся на событие прихода данных в порт // для вашей задачи это должно подойт идеально base.DataReceived += SerialPort_DataReceived; >// открываем порт передав туда имя public void Open(string portName) < if (base.IsOpen) < base.Close(); >base.PortName = portName; base.Open(); > // эта функция вызвется каждый раз, когда в порт чтото будет передано от вашего устройства void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e) < var port = (SerialPort)sender; try < // узнаем сколько байт пришло int buferSize = port.BytesToRead; for (int i = 0; i < buferSize; ++i) < // читаем по одному байту byte bt = (byte)port.ReadByte(); // если встретили начало кадра (0xFF) - начинаем запись в _bufer if (0xFF == bt) < _stepIndex = 0; _startRead = true; // раскоментировать если надо сохранять этот байт //_bufer[_stepIndex] = bt; //++_stepIndex; >// дописываем в буфер все остальное if (_startRead) < _bufer[_stepIndex] = bt; ++_stepIndex; >// когда буфер наполнлся данными if (_stepIndex == DataSize && _startRead) < // по идее тут должны быть все ваши данные. // .. что то делаем . // var item = _bufer[7]; _startRead = false; >> > catch <> > >

использовать это нужно так:

var port = new MySerialPort(); port.Open("COM5");

Это код прототипа, всего лишь техника работы которая может помочь вам.
Ответ написан более трёх лет назад
Нравится 7 2 комментария

Альберт @6ETuK Автор вопроса
Большое спасибо за предоставленный код, вот именно реализации функции:

void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)

мне и не хватало, по вашему коду все встало на свои места еще раз спасибо!
Рад помочь

Армянское Радио @gbg Куратор тега Программирование
Любые ответы на любые вопросы

Установка и настройка виртуальных COM портов

Первое. Отделить мух от котлет. Есть физическая часть протокола — это скорость в бодах, стартовые — стоповые биты и четность. Этим занимается железо порта и на высокий уровень это не пролезает. От программиста требуется задать эти параметры при открытии порта —

new SerialPort(selectedItem.ToString(), 9600, Parity.None, 416, StopBits.One);

9600 — скорость, Parity.None — четность, StopBits.One — количество стоповых бит.
Вот тут все нужно выставить по спецификации.
Контроллер UART сам будет ждать стартовый бит, считать бит четности и так далее. Если честность не сойдется, программа получит ошибку чтения. Служебные биты (старт, стоп, четность) программисту не передаются.

Теперь о шине RS485. Это полудуплексный интерфейс — одновременно можно либо передавать, либо слушать. Если ваша задача состоит только в том, чтобы слушать, у вас почти нет проблем.

Вам нужно верно настроить порт, открыть его и читать как обычный файл. Временную буферизацию вам обеспечит ОС — то, что приходит в порт сначала попадает в небольшой буфер, а только после этого идет в приложение, поэтому с чтением особо спешить не стоит, но и растягивать удовольствие не желательно.

Увы, на C# я не пишу (и считаю, что общаться со внешними устройствами лучше на C++, дабы приход дворника (сборщика мусора) не обломал весь недо-рилтайм), поэтому мои примеры кода вам просто так не подойдут.

Идея такая — читаем из порта все, что в нем есть и складываем к себе в буфер. Это в идеале можно делать в отдельном потоке.
Затем буфер нужно обработать. Это можно сделать тремя способами — регулярным выражением, конечным автоматом и «в лоб».

Начните с написания программы, которая просто читает поток и выводит его на монитор в hex.

Работа с последовательным портом в windows и linux

Часто бывает необходимо, чтобы работа с устройством поддерживалась как в windows, так и в linux. В моем случае нужно было обеспечить работу com-порта в приложении, написанном на с/с++ с использованием кроссплатформенной библиотеки QT. Штатной поддержки программирования портов в QT нет (да и ни к чему это). Поэтому в win32 для работы с портом будем использовать средства WinAPI.

В linux системах же, как известно для работы с устройствами используются специальные файлы.

Итак, взяв на вооружение всем знакомый gcc и его windows-аналог mingw, напишем нехитрый код.

Код будет довольно таки искусственным, т.к. ставится цель не более, чем показать принципы работы с com-портами в двух операционках. Для управления компилятором будем использовать директивы определения компилятора и ОС (__MINGW32__ и __linux). Com-портом в нашем случае является устройство dev/ttyS0 и COM1.

Инициализация

#ifdef __MINGW32__
HANDLE hSerial = CreateFile(«COM1»,GENERIC_READ | GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL);
if (hSerial == INVALID_HANDLE_VALUE) printf(«Error opening port\r\n»);
return -1;
>
#endif

#ifdef __linux
int fd = open(«/dev/ttyS0», O_RDWR | O_NOCTTY );
if (fd

Похожие статьи

  • Com порт на компьютере

    Этот порт отличает последовательная передача данных по одной линии. Последовательная передача означает, что биты информации передаются по линии один за…

  • Com 3 порт

    Отличительной особенностью последовательного порта является его способ организации передачи данных . В этом плане последовательный порт существенно…

  • Com порт rs

    Разглядим плюсы и недочеты HP ProBook 6560b исходя из убеждений обычного мещанина Русские Блоги Последовательный порт, COM-порт, порт UART, TTL, RS-232,…

Оставить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Что будем искать? Например,Человек

Мы в социальных сетях