Считывание данных с СОМ порта

Подключаем наши девайсы к компьютеру. Обсуждаются: порты, протоколы, драйвера, языки программирования и т.д.
Ответить
Открыл глаза
Сообщения: 40
Зарегистрирован: Пт фев 15, 2008 23:08:25

Сообщение Серёга_ »

Собрал простой передатчик на базе ATmega8, который череp каждую секунду передаёт данные, целостность тракта и правильность передачи информации проверял программой Terminal v1.9b - всё работает, информация принимается верно. Проблема в том, что программа написанная мной на С++ для билдера не раобтает и не хочет принимать сообщения. Вот текст программы:

void __fastcall TForm1::Button1Click(TObject *Sender)
{
HANDLE hCom = CreateFile("Com1",GENERIC_READ | GENERIC_WRITE,0,NULL, OPEN_EXISTING, 0, NULL);
if( hCom == INVALID_HANDLE_VALUE )
{
Edit1->Text = "Error";
CloseHandle(hCom);
}

else
{
DCB dcb;
GetCommState(hCom, &dcb);
dcb.BaudRate = CBR_2400;
dcb.fParity = false;
dcb.ByteSize = 8;
dcb.Parity = 1;
dcb.StopBits = 1;
SetCommState(hCom,&dcb);
DWORD feedback = 0;
char buf[20];
ReadFile(hCom, buf, sizeof(buf), &feedback, NULL);
Edit1->Text = buf[0];
Edit2->Text = buf[1];
Edit3->Text = buf[2];
Edit4->Text = buf[3];
Edit5->Text = buf[4];
Edit6->Text = buf[5];
Edit7->Text = buf[6];
Edit8->Text = buf[7];
Edit9->Text = buf[8];
Edit10->Text = buf[9];

}
CloseHandle(hCom);

}


программа по нажатию кнопки Button1 должна произодить считывание данных с сом порта и выводить эти данные текстовые поля Edit. При нажатии на кнопку поля заполняются различными символами, которые не меняются вне зависимости от того - включен передатчик или нет. В чём может быть дело?

На всякий случай, настройки UART со стороны контроллера:
UCSRC|=(1<<UCSZ1)|(1<<UCSZ0);
UBRRH = 0;
UBRRL=25;// задание скорости
UCSRB|=(1<<RXEN)|(1<<TXEN)|(1<<RXCIE);//разрешение приёма
Реклама
Открыл глаза
Сообщения: 40
Зарегистрирован: Пт фев 15, 2008 23:08:25

Сообщение Серёга_ »

Если кому понадобится в будующем - рабочий пример программы и прошивки контроллера можно скачать здесь: http://www.eldev.hut2.ru/tmeter.html
Реклама
Потрогал лапой паяльник
Сообщения: 331
Зарегистрирован: Вс мар 30, 2008 14:31:51

Сообщение PB_EXPERT »

Сейчас вообще-то популярны USB термометры
Открыл глаза
Сообщения: 40
Зарегистрирован: Пт фев 15, 2008 23:08:25

Сообщение Серёга_ »

Не спорю, но интересно было разобраться с СОМ портом.
Реклама
Эиком - электронные компоненты и радиодетали
lix
Опытный кот
Сообщения: 703
Зарегистрирован: Вс янв 17, 2010 15:32:19
Откуда: Курган

Сообщение lix »

сразу после функции readfile вставьте функцию GetLastError(). посмотрите что она возвращает, если не 0 то смотрите msdn по поводу этой ошибки. да и *commstate аналогично.
Реклама
Вымогатель припоя
Сообщения: 630
Зарегистрирован: Пн июн 14, 2010 13:07:29
Откуда: Жуковский

Сообщение a_skr »

в свое время набросал класс для работы с COM-портом (использовался в проектах на Builder'е), может, поможет:

comport.h:

Код: Выделить всё

#ifndef COMPORT_H
#define COMPORT_H

#include <vcl.h>

//---------------------------------------------------------------------------
class COMPORT {
private:
  DCB dcb;
  HANDLE hComm;
  DWORD dwEvtMask;
  OVERLAPPED o;
  DWORD dwBytes;
  COMSTAT csStat;
//  BYTE szBuffer[256];
  DWORD dwError;

public:
  bool Opened;

  COMPORT();
  ~COMPORT();
  void Open();
  void Close();
  int Read(char *buf, int len);
  bool Write(char *buf, int len);
};
//-----------------------------------------------------------------------------
#endif

comport.cpp:

Код: Выделить всё

#include <assert.h>
#include "ComPort.h"

#define min(a,b) ((a<b)?a:b)
//---------------------------------------------------------------------------
COMPORT::COMPORT()
{
  Opened = false;
}
//---------------------------------------------------------------------------
COMPORT::~COMPORT()
{
  if(Opened) Close();
}
//---------------------------------------------------------------------------
void COMPORT::Open()
{
  if(Opened) return;

  hComm = CreateFile("COM1",
    GENERIC_READ | GENERIC_WRITE,
    0,    /* comm devices must be opened w/exclusive-access */
    NULL, /* no security attrs */
    OPEN_EXISTING, /* comm devices must use OPEN_EXISTING */
    FILE_FLAG_OVERLAPPED,         // file attributes
    NULL  /* hTemplate must be NULL for comm devices */
  );

  if(hComm == INVALID_HANDLE_VALUE){
    MessageBox(::GetActiveWindow(),"Невозможно открыть COM порт","Ошибка!",MB_OK);
    return;
  }

  if(!SetupComm(hComm, 256, 256)){  // allocate transmit & receive buffer
    MessageBox(::GetActiveWindow(),"Невозможно установить размеры буфферов","Ошибка!",MB_OK);
    return;
  }

  GetCommState(hComm, &dcb);
//  dcb.BaudRate = 9600;
  dcb.BaudRate = 115200;
  dcb.ByteSize = 8;
  dcb.Parity = NOPARITY;
  dcb.StopBits = ONESTOPBIT;

  if(!SetCommState(hComm, &dcb)){
    MessageBox(::GetActiveWindow(),"Невозможно установить парметры порта","Ошибка!",MB_OK);
    return;
  }

  SetCommMask(hComm, EV_BREAK | EV_RXCHAR);

  o.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  assert(o.hEvent);

  Opened=true;
  return;
}
//---------------------------------------------------------------------------
void COMPORT::Close()
{
  if(!Opened) return;
  CloseHandle(hComm);
  Opened = false;
}
//---------------------------------------------------------------------------
int COMPORT::Read(char *buf, int len)
{
  if(!Opened || len<1) return 0;
  WaitCommEvent(hComm, &dwEvtMask, &o); // Windows 98/XP
  if(!(dwEvtMask & EV_RXCHAR)) return 0;
  ClearCommError(hComm, &dwError, &csStat);
  ResetEvent(o.hEvent);
  len = min((unsigned long)len, csStat.cbInQue);
  if(!ReadFile(hComm, (BYTE*)buf, len, &dwBytes, &o)) return 0;
  if(csStat.cbInQue == 0) return 0;
  return len;
}
//---------------------------------------------------------------------------
bool COMPORT::Write(char *buf, int len)
{
  if(!WriteFile(hComm, (LPCVOID)buf, len, &dwBytes, &o)) return false;
  return true;
}
//---------------------------------------------------------------------------

Реклама
Потрогал лапой паяльник
Сообщения: 390
Зарегистрирован: Чт сен 24, 2009 17:22:51
Откуда: UK

Сообщение FUZZY_ »

ReadFile(hCom, buf, sizeof(buf), &feedback, NULL);


sizeof(buf) - это то что вы запросили ститать Это не значит что будет считано

ReadFile создает свои потоки для чтения и со своими буферами . если возникают условия, оговореные в настройках порта,
то возможна передача из внутренего буфера запрошеного количества байт, в противном случае в buf будет кусок принимаемого сообщения или ничего. Быстрее чем 1/18 с процес работать не будет (XP,W7).

На этом форуме где-то год назад я выкладывал рабочие примеры для BCB 6 C++
Ответить

Вернуться в «Интеграция с ПК»