Работа с 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,
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[1] = 90;
data[2] = (byte)num;
data[3] = crc8(data, 3);
rs_port.Write(data, 0, 4);
// Отправляем запрос, ждем 100 мс и смотрим что пришло в ответ
Как создавать скрипты в Windows | удобный конструктор с графическим интерфейсом
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;
// Если не пришло вообще никакого ответа,
// возвращаем отрицательное значение
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
Уроки C# / Как сделать первое Windows приложение
Разработка
электроники на заказ
Источник: embeddedsoft.ru
Блог
Мы обратили внимание, что проблема связи с компьютером через последовательный порт (COM-порт) часто обсуждается на различных форумах.
Наша команда Мониторбанка написала несколько программ для связи с ПК, поэтому и решили написать эту небольшую статью-мануал. В этой статье мы опишем интерфейс USART, которым оснащено большинство микроконтроллеров.
Основной темой будет создание приложения для ПК, которое может взаимодействовать с микроконтроллером через последовательный порт. Приложение предназначено для систем, использующих USART. Такое решение позволяет передавать данные не только через RS232, но также через USB и конвертер FT232, bluetooth, IrDA и другие интерфейсы с использованием виртуального COM-порта.
Интерфейс USART
USART — универсальный синхронный и асинхронный приемник и передатчик |
Как уже упоминалось, USART — это интерфейс связи, доступный в большинстве популярных микроконтроллеров. В некоторых из них можно даже найти несколько USART, работающих независимо.
Для работы мы будем использовать ATmega16, но программы должны быть легко перенесены на другие связанные процессоры. Сигналы TxD (передача данных) и RxD (прием данных) используются для передачи данных через USART.
Характерной особенностью USART в асинхронном режиме является отсутствие тактового сигнала. |
Скорость передачи данных определена для соединения заранее. Это делается путем ввода соответствующего значения в UBRR (регистр скорости передачи USART), рассчитанного на основе тактовой частоты микроконтроллера.
Кстати, существуют стандартные скорости передачи: 2400, 4800, 9600 и т.д. Для обеспечения передачи с ошибкой 0,00%, тактовая частота микроконтроллера должна быть заранее известна и стабильна, но также должна быть кратна 1,8432 МГц. Выбор другой частоты снизит точность.
Но по-прежнему допустимы ошибки менее 2%. |
В таблице данных Atmel вы можете найти подробное описание используемого интерфейса, включая формулу для расчета скорости передачи и таблицу с популярными тактовыми частотами, скоростями передачи, соответствующими значениям регистра UBRR и соответствующими ошибками.
Фрейм данных в передаче UART выглядит следующим образом:
Он включает в себя стартовый бит для оповещения о начале следующего кадра (от 5 до 9 битов данных) и бит четности для проверки ошибок при приеме. Он может работать в трех режимах — без управления (no), сумма всегда четная (even), сумма всегда нечетная (odd).
Каждый кадр закрывается одним- двумя стоповыми битами . Наиболее распространенная конфигурация — 8 бит данных, без контроля четности и 1 стоповый бит. |
Популярной конфигурацией, в которой работает интерфейс USART, является подключение к порту RS232 компьютера. Для этого необходимо преобразовать логические состояния, что можно сделать с помощью популярной микросхемы MAX232 .
Ниже представлена схема подключения UC к RS:
Другие, частые конфигурации — это USART, работающий с FT232RL и подключенный к USB-порту, модуль Bluetooth, например, BTM-222 (помните о напряжении питания 3,3 В), или соединение двух микроконтроллеров друг с другом. Но мы не будем о них писать. Схемы подключения без проблем можно найти в Интернете. Перейдем к программе со стороны ПК.
Среда разработки
Главный критерий выбора среды разработки — наличие выделенных библиотек для поддержки последовательных портов.
Альтернатива, которая заключается в прямом использовании Win32 API, трудна, неинтуитивна и иногда плохо читается. |
Поэтому нет смысла усложнять себе жизнь. Кроме того, многие среды определенно облегчают создание простых, в использовании, приложений. Это определенно хорошее изменение для кривых консольных программ.
Курсовая работа. Разработка консольного приложения для Windows на языке программирования С
Единственный в мире Музей Смайликов
Самая яркая достопримечательность Крыма
Скачать 193.47 Kb.
МИНИСТЕРСТВО НАУКИ И ВЫСШЕГО ОБРАЗОВАНИЯ Российской Федерации
Федеральное государственное бюджетное образовательное учреждение высшего образования
«ТЮМЕНСКИЙ ИНДУСТРИАЛЬНЫЙ университет»
ИНСТИТУТ ГЕОЛОГИИ И НЕФТЕГАЗОДОБЫЧИ
КАФЕДРА КИБЕРНЕТИЧЕСКИХ СИСТЕМ
ПОЯСНИТЕЛЬНАЯ ЗАПИСКА
к курсовой работе
по дисциплине «Программирование и алгоритмизация»
Тема: «Разработка консольного приложения для Windows на языке программирования С++»
студент группы: АТПбз-19-4
Шабаев А.В.
Проверил:
доцент Сенкевич Л.Б.
Назначение и область применения …………………………………………. 3
Входные и выходные данные… …………………………………………….. 3
Выбор состава технических и программных средств ………………………….. 5
Спецификация программы ………………………………………………….. 5
Описание работы программы ……………………………………………….6
Список использованной литературы…………………………………. ………22
Постановка задачи
Составить программу, которая содержит текущую информацию о книгах в библиотеке.
- номер УДК;
- фамилию и инициалы автора;
- название;
- год издания;
- количество экземпляров данной книги в библиотеке.
- начальное формирование данных обо всех книгах в библиотеке в виде двоичного дерева;
- добавление данных о книгах, вновь поступивших в библиотеку;
- удаление данных о списываемых книгах;
- по запросу выдаются сведения о наличии книг в библиотеке, упорядоченные по годам издания.
Назначение и область применения
Программа предназначена для начального формирования, добавления, удаления и просмотра данных о книгах в библиотеке.
Программа применяется для структурирования и упорядочивания данных, а также быстрого поиска необходимых записей.
Входные и выходные данные
- Номер УДК – может состоять из цифр и других знаков, таких как дефис, двоеточие и т.д. Представлен массивом типа char.
- Фамилия и инициалы автора – может состоять из символов, в том числе пробелов. Представлены массивом типа char.
- Название — может состоять из символов, в том числе пробелов. Представлено массивом типа char.
- Год издания – целое число. В коде программы можно задать ограничение на его диапазон. Представлено типом int.
- Количество экземпляров – целое неотрицательное число. В коде программы можно задать ограничение на его диапазон. Представлено типом int.
- В начале указано целое число – количество книг в файле
- Далее идут записи о каждой книге в порядке «Номер УДК – Название – Автор – Год – Количество экземпляров». Каждая запись начинается с новой строки.
Описание алгоритма
- Создание удобного интерфейса пользователя.
- Хранение данных в подходящей для задания структуре.
- Создание методов добавления и удаления записи в двоичное дерево.
- Вывод результатов работы на экран.
Сравнение книг (при добавлении и удалении) происходит сначала по году издания, затем по автору и названию. Такой алгоритм позволяет формировать дерево так, чтобы выводить книги упорядоченными по году издания без дополнительной сортировки.
Выбор состава технических и программных средств
Задача выполнялась в Microsoft Visual Studio 2015— продукте компании Microsoft, включающем интегрированную среду разработки программного обеспечения и ряд других инструментальных средств. Visual Studio позволяет разрабатывать широкий ряд приложений, в том числе и консольные.
Разработка в Visual Studio удобна, так как эта среда включает в себя редактор исходного кода с поддержкой технологии IntelliSense (дописывает название функции при вводе начальных букв), что ускоряет написание кода. Также в данной среде легко обнаруживать и исправлять ошибки как на этапе компиляции, так и во время исполнения программы.
Спецификация программы
Book.h | Заголовочный файл | Содержит описание структуры книги |
Library.h | Заголовочный файл | Содержит описание класса библиотеки |
Library.cpp | Файл исходного кода | Содержит реализацию методов класса библиотеки |
Start.cpp | Файл исходного кода | Содержит стартовую точку программы, служит для отображения меню и вызова функций библиотеки |
Описание работы программы
При запуске программы пользователь попадает в главное меню (рис.1)
Выбор функции осуществляется введением её номера и нажатием клавиши Enter.
Первая доступная функция – заполнение библиотеки из файла. После её выбора на консоли появляется возможность ввести путь к файлу с информацией (рис.2). В примере пользователем был введён путь D:DocumentsBooksDebugInitialLibrary.txt.
После задания пути и нажатия клавиши Enter, программа выполнит загрузку данных из файла в память. В качестве результата на консоли отобразится количество прочитанных записей (рис.3) и предложение нажать enter для возвращения в главное меню:
В случае же, если файл не был найден или по какой-то причине его не удалось открыть, то отобразится предупреждение об этом (рис.4):
Рис.4 Сообщение об ошибке при открытии файла
Чтобы увидеть результат своих действий и посмотреть список книг в библиотеке, нужно вызвать функцию номер 4. Результат отобразится в следующем виде (рис.5):
Рис.5 Список книг в библиотеке
Можно видеть, что книги упорядочены по году издания, как и требуется в задании. Это возможно без дополнительной сортировки благодаря структуре двоичного дерева.
Теперь добавим новую книгу с консоли. Для этого нужно вызывать вторую функцию меню и следовать подсказкам в консоли (рис.6):
В данном примере пользователь добавляет книгу с номером УДК «123-456», автора «Мышкин.Д.К.», с названием «История России», 1999 года издания в количестве 5 штук. Результатом выполнения после нажатия клавиши enter будет сообщение об успешном добавлении (рис.7):
Рис.7 Успешное добавление
После вставки книга займет нужное место в дереве и сортировка при выводе сохранится (рис.8):
Рис.8 Стрелка (добавлена в Paint) указывает на вставленную запись
Если же книга с такими же автором, названием и годом уже есть в базе, то добавления не произойдет, о чём пользователь будет уведомлён (рис.9):
Рис.9 Защита от дублирования
Для удаления книги нужно вызвать третью функцию меню и следовать подсказкам консоли (рис.10):
Рис.10 Удаление книги
Если такая книга есть в библиотеке, то она будет удалена, а пользователю показано сообщение об успешной операции (рис.11):
Рис.11 Успешное удаление
Удаление так же не нарушает структуру двоичного дерева и, соответственно, сортировку (рис.12):
Рис.12 Вывод после удаления «Океанов и гидросфер»
Если же такой книги не было, то пользователь получит соответствующее предупреждение (рис.13):
Рис.13 Сообщение об отсутствии книги
При вводе числовых данных (год издания, количество книг) в функциях добавления и удаления выполняется валидация пользовательского ввода. Если введенная информация не является целым числом в заданном в коде диапазоне, то пользователь получит предупреждение об этом и просьбу повторить ввод (рис.14):
Рис.14 Валидация пользовательского ввода. В красной рамке – попытка неверного ввода, в зеленой – корректный ввод. (Рамки добавлены в Paint)
Программа продолжает работу, пока пользователь не выберет функцию выхода в меню.
Листинг программы
Book.h
#include
//Максимально допустимый размер строки
const int SIZE_LIMIT = 256;
//Структура для представления книги и хранения её в двоичном дереве
//Номер УДК (может содержать не только цифры)
char UDK_Number[SIZE_LIMIT];
//Фамилия и инициалы автора
char Name[SIZE_LIMIT];
//Год издания
int PublishYear;
//Количество экземпляров в библиотеке
int Count;
//Левый сын в двоичном дереве
Book *left;
//Правый сын в двоичном дереве
Book *right;
Book()< >
Book(char*author, char*udk, char*name, int year, int count)
Library.h
#include»Book.h»
//Класс для представления библиотеки в виде двоичного дерева
//Конструктор пустой библиотеки
Library();
//Деструктор библиотеки
Library();
//Добавить новую книгу
//Вернет истину, если книга добавлена и ложь, если такая уже есть в библиотеке
bool insert(char*author, char*udk, char*name, int year, int count);
//Удалить книгу по автору, названию и году
//Вернет истину, если книга удалена и ложь, если такой в библиотеке нет
bool deleteBook(char*author, char*name, int year);
//Заполнить библиотеку из файла
//Возвращает количество считанных книг
//В случае ошибки чтения возвращает -1
int fillFromFile(char*fileName);
//Показать все книги
void destroy_tree(Book *leaf);
//Добавить новую книгу после указанного узла
Book* insert(Book* newBook, Book *inserted);
//Найти книгу после узла
Book *search(Book *book, Book *leaf);
//Сравнить две книги для вставки (поиска) в дерево
int compareBooks(Book*book1, Book*book2);
//Показать книги, начиная от узла
void show(Book *book);
//Удалить книгу, начиная с узла
Book* deleteBook(Book* book, Book*deleted);
//Копировать информацию о книге
void Library::copyData(Book*dest, Book*source);
//Найти минимальный узел в поддереве
Book* Library::FindMin(Book *root);
Book *root;
Library.cpp
using namespace std;
//Создать пустую библиотеку
>
//Удалить все книги из библиотеки
>
//Последовательное рекурсивное удаление всех узлов дерева
void Library::destroy_tree(Book *leaf)
>
//Добавление новой книги в библиотеку
bool Library::insert(char*author, char*udk, char*name, int year, int count) Book*book = new Book(author, udk, name, year, count);
bool inserted = false;
//Начинаем вставку новой книги с корня
insert(book, root, inserted);
>
//Добавление книги в поддерево узла
Book* Library::insert(Book* newBook, Book *inserted) //Если узел пустой, ставим туда книгу
leaf->left = leaf->right = NULL;
>
int comparing = compareBooks(newBook, leaf);
//Если ключ новой книги меньше, чем узла, то ищем место для вставки слева
if (comparing left = insert(newBook, leaf->left, inserted);
//Иначе ищем место для вставки справа
else if (comparing > 0)
leaf->right = insert(newBook, leaf->right, inserted);
//Если такая книга уже есть, то не вставляем
return leaf;
>
//Поиск книги в поддереве с корнем в узле
Book *Library::search(Book*book, Book* leaf) if (leaf != NULL) //Если сравнение успешно, то книга найдена
if (!compareBooks(book, book))
//Если книга «меньше» листа, то ищем её слева
if (compareBooks(book, leaf) left);
return search(book, leaf->right);
>
//Не нашли книгу в библиотеке
>
/*Сравнить две книги для вставки (поиска) в дерево
Две книги одинаковы, если у них совпадает автор, название и год издания
Функция вернет 0, если книги «равны»
Значение меньше нуля, если первая книга «меньше»
Значение больше нуля, если первая книга «больше»
int Library::compareBooks(Book*book1, Book*book2)
//Сначала сравниваем книги по годам, так как это даст нужную структуру вывода
if (book1->PublishYear != book2->PublishYear)
return book1->PublishYear — book2->PublishYear;
//Затем сравниваем авторов
int authors = strcmp(book1->Author, book2->Author);
return authors;
//Если и авторы совпадают, то проверяем название
return strcmp(book1->Name, book2->Name);
>
//Удаление книги из библиотеки
bool Library::deleteBook(char*author, char*name, int year)
bool deleted = false;
//Создаем временную структуру книги для удобства сравнения
book.PublishYear = year;
root = deleteBook(
>
//Удаление книги, начиная поиск с узла
Book* Library::deleteBook(Book*book, Book* deleted)
//Книга не найдена
if (compareBooks(book, node) left = deleteBook(book, node->left, deleted);
else if (compareBooks(book, node) > 0) < // Книга в правом поддереве
node->right = deleteBook(book, node->right, deleted);
// Первый случай: у удаляемого узла нет потомков
if (node->left == NULL node->right == NULL)
delete node; //очищаем память
else if (node->left == NULL)
Book *temp = node; // Запоминаем, чтобы потом удалить
node = node->right; //Заменяем потомком
// Случай три: только левый потомок
else if (node->right == NULL)
Book *temp = node; // Запоминаем, чтобы потом удалить
node = node->left; //Заменяем потомком
// Случай 4: оба потомка
// Ищем минимального потомка в правом поддереве
Book *temp = FindMin(node->right);
// Дублируем потомка на место удаляемого узла
copyData(node, temp);
// Удаляем дубликат
node->right = deleteBook(temp, node->right, deleted);
>
//Копирование информацию о книге
void Library::copyData(Book*dest, Book*source)
>
//Поиск минимального листа в поддереве
Book* Library::FindMin(Book *node)
if (node->left != NULL)
return FindMin(node->left); // left tree is smaller
>
//Вывод всех книг в библиотеке
//Так как при сравнении книг первым сравнивается год, то вывод будет отсортирован по нему
>
//Вывод всех книг в библиотеке, начиная от узла
if (book == NULL) return;
cout UDK_Number PublishYear Count Author Name right);
>
//Заполнить библиотеку из текстового файла
int count;
//Всего книг в файле
int totalCount;
ifstream myfile;
myfile.open(fileName);
//Проверяем, что файл открыт
myfile.get();
for (int i = 0; i > year;
myfile.get();
//Вставляем считанную книгу
insert(author, udk, name, year, count);
>
myfile.close();
Start.cpp
using namespace std;
//Считать целое число с проверкой на попадание в интервал
int getInt(char*message, int min, int max)
bool valid = false;
int total = library->fillFromFile(fileName);
if (total insert(author, udk, name, year, count))
cout deleteBook(author, name, year))
Источник: topuch.com