Ввод/вывод СОМ порта

  • Автор темы innovator
  • Дата начала
I

innovator

Гость
#1
[codebox]//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "UMain.h"
#include "UFLog.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
HANDLE hCom;
COMMTIMEOUTS ct;
int addres = 16;
char *buf_out,
cnt=0,
*buf_in;
DWORD bc;

//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}


void __fastcall TForm1::FormShow(TObject *Sender)
{
FLog->ShowModal(); // открытие формы заставки. Чтобы ShowModal(); работало надо в свойстве Visible главной формы и формы заставки выставить значение false!
}
//---------------------------------------------------------------------------

void __fastcall TForm1::ButtonStartClick(TObject *Sender)
{
// коментарии по книге "Последовательные интерфейсы ПК. Практика программирования" (Агуров, 2004)
ct.ReadIntervalTimeout=10; // задаёт допустимый интервал ожидания в миллисекундах между получением двух символов
ct.ReadTotalTimeoutMultiplier=0; // множитель в миллисекундах
ct.ReadTotalTimeoutConstant=0; // задаёт константу, добовляемую к произведению, получае мую при вычислении времени из ReadTotalTimeoutMultiplier
ct.WriteTotalTimeoutMultiplier=0; // анологично для чтения
ct.WriteTotalTimeoutConstant=0; // аналогично для чтения
hCom = CreateFile ("COM1", // название порта
GENERIC_READ|GENERIC_WRITE, // порт используется как для чтения, так и для записи
0, // общий доступ к порту запрещён
NULL, // атрибуты защиты не используются и устанавливаются в NULL
OPEN_EXISTING, // открыть ресурс если он существует, или вернуть ошибку если не существует
FILE_FLAG_OVERLAPPED, // FILE_ATTRIBUTE_NORMAL- синхроный режим, FILE_FLAG_OVERLAPPED - асинхронный режим
NULL); // последний параметр обязательно NULL

if (hCom == INVALID_HANDLE_VALUE) // если при открытии порта была ошибка, то
Panel1->Caption = "ERROR COM"; // вывести на панель
else
{
DCB dcb = {0}; // инициализация DCB
if (!GetCommState(hCom, &dcb)) // если проинициализировался с ошибкой, то
{Panel1->Font->Size=30; Panel1->Caption = "ERROR BCD";} // вывести на панель
else
{
dcb.BaudRate = 38400; // скорость соединеия
dcb.ByteSize = 8; // размер слова
dcb.Parity = EVENPARITY; // проверка на чётность
dcb.StopBits = TWOSTOPBITS; // два стоповых бита
if(!SetCommState(hCom, &dcb)) // если BCD не про инициализировалась, то
{Panel1->Font->Size=20; Panel1->Caption = "ERROR Setup BCD";}
else
{
SetCommTimeouts(hCom, &ct); // установка таймаутов
PurgeComm(hCom, PURGE_TXCLEAR | PURGE_RXCLEAR); // очистка приёмника и передатчика
SetupComm(hCom, 256, 256); // Устанавливает размер в байтах очередей приёма и передачи рекомендуемые
buf_out = &addres;
Timer1->Enabled=true; // запуск таймера после инициализации порта
}
}
}
}
//---------------------------------------------------------------------------

void __fastcall TForm1::ButtonStopClick(TObject *Sender)
{
Timer1->Enabled = false; // остановка таймера
//buf_in=(char*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, strlen(buf_out)+1);
cnt=0; // обнуление считчика ошибки чтения
Label1->Caption = " ";
CloseHandle(hCom); // закрытие порта
}
//---------------------------------------------------------------------------


void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
if ((WriteFile(hCom, // передач деструктора порта
buf_out, // буфер данных
strlen(buf_out), // размер буфера данных
&bc, // число переданых байт
NULL)) // параметры ассинхронной передачи
== 0) // если передача не удалась, то
Label1->Caption = "Error Write";
else {
if ((ReadFile(hCom, // передач деструктора порта
buf_in, // буфер для принятых данных
strlen(buf_in), // размер буфера для принятых данных
&bc, // число принятых байт
NULL)) // параметры ассинхронной передачи
== 0) // если приём не удался, то
{
++cnt;
Label1->Caption = "Error Read: " + cnt;
}
else // если всё хорошо, то
{
Panel1->Caption = *buf_in; // вывести на экран значение
}
}
}
//---------------------------------------------------------------------------[/codebox]

Здравствуйте формучане. Есть вопросик по этому коду. Функция передачи данных WriteFile возвращает 0 (признак ошибки передачи), хотелось бы услышать Ваши ответы почему. Есть такая мысль что из-за того, что тип буфера buf_out char, а тип передаваемого адреса int. Может и из-за конфигурации?
Заранее благгодарен.
На всякий случай приложил файл.
 

Вложения

I

innovator

Гость
#3
Например прописать a=GetLastError(); ?
И ещё такая мысль: А может запись в порт возвращать 0, т.к нету ответа от устройства подключённого к порту, Или кабель не подключён?
А функцию сейчас попробую.
 
I

innovator

Гость
#5
Прописал так:
Код:
int addres = 16, cnt=0, n;
LPDWORD a;
LPCOMSTAT b;
unsigned char buf_out[1],
buf_in[2];
DWORD	 bc;
buf_out[0] = addres;
if ((WriteFile(hCom,									  // передач деструктора порта
buf_out,										 // буфер данных
strlen(buf_out),								 // размер буфера данных
&bc,											 // число переданых байт
NULL))										  // параметры ассинхронной передачи
== 0)										 // если передача не удалась, то
{n=ClearCommError(hCom, a, b); Label1->Caption = "Error Write" + IntToStr(n);}
и выдал n=1. Я не знаю что такое MSDN, посмотрел в Агуров. Написано что переполнение буфера либо раньше принят сигнал EOF.
 
I

innovator

Гость
#7
Те так вот сказать по коду не можешь, что не так? С английским худо у меня. А на русской версии про Сом не нашёл.