Цитата(Andrey Pesoshin @ Oct 19 2012, 15:58)

Про скорости - входной сигнал опрашивается не чаще раза в 1 мс (f <= 1000 Гц), при этом первый фронт на одной из линий хотелось бы поймать максимально быстро.
А разве можно управлять линиями последовательного порта ПК на манер GPIO (а как?)? Это что-то вроде
bitbang mode у FT232RL?
управлять можно. только вот с 1 мс может не получиться.
с УСБ переходником особенно. там циклы на шине вроде как не сильно чаше идут.
а нормальный компорт опрашивать-то можно и гораздо чаще, вполне удавалось захватывать статусными линиями последовательного порта SPI подобный интерфейс - клоки и данные, потом программно определять перепад на клоках и по нему захватывать данные, причём клоки были несколько кГц.
но никто не гарантирует что в какой-нибудь момент времени операционная система захочет сделать что-нибудь своё, ну там диск например подефрагментировать, и на несколько мс процессор у задачи отберут. с этим можно бороться повышением приоритета и перекидыванием на другие ядра процессора, но всё равно существует довольно ненулевая вероятность пропустить фронты при таком программном поллинге особенно если частота килогерц.
можно еще почитать про функцию
WaitCommEvent, с ней потерять потерять фронт возможно будет сложнее по сравнению с тупо полиингом.
для windows:
Код
#include "ComPort.h"
void main(){
ComPort port("COM1", 9600);
port.Rts(1); //rts -> 1;
port.Dtr(0); //dtr -> 0;
if (port.Cts()){};
}
ComPort.h:
CODE
#ifndef __COMPORT_H_
#define __COMPORT_H_
#include <windows.h>
class ComPort{
private:
HANDLE hCom;
int opened;
char * luaBuff;
int lastReadNum;
public:
~ComPort();
ComPort();
ComPort(const char * comPortStr,int speed, int byteSize = 8, int parity = 0, int stopBit = 0);
int Init(const char * comPortStr,int speed, int byteSize = 8, int parity = 0, int stopBit = 0);
int SetBaudRate(int speed);
void Close ();
int Read(char * c,int num);
const char * Read(int num = 1024);
int LastReadNum();
int Status();
int Writef(char * str, ...);
int Write(char *c, int num);
int Write(char *c);
int Write(char c);
int Rts(int level);
int Dtr(int level);
int Cts();
int Dsr();
int Ri();
int Dcd();
void ClearTxBuff();
void ClearRxBuff();
int RxBuffNum();
};
#endif
ComPort.cpp:
CODE
#include "comPort.h"
#include <stdarg.h>
#include <stdio.h>
void ComPort::ClearTxBuff(){
PurgeComm(hCom,PURGE_TXCLEAR);
}
void ComPort::ClearRxBuff(){
PurgeComm(hCom,PURGE_RXCLEAR);
}
int ComPort::SetBaudRate(int speed){
DCB dcb;
GetCommState( hCom, &dcb );
dcb.BaudRate = speed ;
if ( !SetCommState( hCom, &dcb ) ){
// CloseHandle(hCom);
return 1; //SetCommState error
}
return 0;
}
int ComPort::Status(){
unsigned int stat;
GetCommModemStatus(hCom, (LPDWORD)&stat);
return stat;
}
int ComPort::Cts(){
return Status() & MS_CTS_ON ? 1 : 0;
}
int ComPort::Dsr(){
return Status() & MS_DSR_ON ? 1 : 0;
}
int ComPort::Ri(){
return Status() & MS_RING_ON ? 1 : 0;
}
int ComPort::Dcd(){
return Status() & MS_RLSD_ON ? 1 : 0;
}
int ComPort::Rts(int level){
DCB dcb;
GetCommState( hCom, &dcb );
dcb.fRtsControl = level ? RTS_CONTROL_ENABLE : RTS_CONTROL_DISABLE;
if ( !SetCommState( hCom, &dcb ) ){
// CloseHandle(hCom);
return 1; //SetCommState error
}
return 0;
}
int ComPort::Dtr(int level){
DCB dcb;
GetCommState( hCom, &dcb );
dcb.fDtrControl = level ? DTR_CONTROL_ENABLE : DTR_CONTROL_DISABLE;
if ( !SetCommState( hCom, &dcb ) ){
// CloseHandle(hCom);
return 1; //SetCommState error
}
return 0;
}
ComPort::~ComPort(){
Close();
delete[] luaBuff;
}
ComPort::ComPort(){
lastReadNum = 0;
opened = 0;
luaBuff = new char[2]; luaBuff[0]=0; luaBuff[1]=0;
}
ComPort::ComPort(const char * comPortStr,int speed, int byteSize, int parity, int stopBit){
lastReadNum = 0;
opened = 0;
luaBuff = new char[2]; luaBuff[0]=0; luaBuff[1]=0;
Init(comPortStr,speed,byteSize,parity,stopBit);
}
/* Initialize Communication port */
int ComPort::Init(const char * comPortStr,int speed, int byteSize, int parity, int stopBit){
DCB dcb;
COMMTIMEOUTS CommTimeOuts ;
if ( ( hCom = CreateFile (comPortStr, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL ) )
== INVALID_HANDLE_VALUE ) {
return 1; // error
}
CommTimeOuts.ReadIntervalTimeout = MAXDWORD;
CommTimeOuts.ReadTotalTimeoutMultiplier = 0;
CommTimeOuts.ReadTotalTimeoutConstant = 0;
CommTimeOuts.WriteTotalTimeoutMultiplier = 0;
CommTimeOuts.WriteTotalTimeoutConstant = 0;
if ( !SetCommTimeouts( hCom, &CommTimeOuts )){
CloseHandle(hCom);
return 2; // SetCommTimeouts error
}
dcb.DCBlength = sizeof ( DCB ) ;
dcb.BaudRate = speed ;
dcb.fBinary = TRUE ;
dcb.fParity = 0;
dcb.fOutxCtsFlow = 0; // CTS output flow control
dcb.fOutxDsrFlow = 0; // DSR output flow control
dcb.fDtrControl = 0;//DTR_CONTROL_ENABLE; // DTR flow control type
dcb.fDsrSensitivity = 0; // DSR sensitivity
dcb.fTXContinueOnXoff = 0; // XOFF continues Tx
dcb.fOutX = 0; // XON/XOFF output flow control
dcb.fInX = 0; // XON/XOFF input flow control
dcb.fErrorChar = 0; // enable error replacement
dcb.fNull = 0; // enable null stripping
dcb.fRtsControl = 0;//RTS_CONTROL_ENABLE; // RTS flow control
dcb.fAbortOnError = 0; // abort reads/writes on error
dcb.XonLim = 0; // transmit XON threshold
dcb.XoffLim = 0; // transmit XOFF threshold
dcb.ByteSize = byteSize; // number of bits/byte, 4-8
dcb.Parity = parity; // 0-4=no,odd,even,mark,space
dcb.StopBits = stopBit; // 0,1,2 = 1, 1.5, 2
dcb.XonChar = 0; // Tx and Rx XON character
dcb.XoffChar = 0; // Tx and Rx XOFF character
dcb.ErrorChar = 0; // error replacement character
dcb.EofChar = 0; // end of input character
dcb.EvtChar = 0; // received event character
if ( !SetCommState( hCom, &dcb ) ){
CloseHandle(hCom);
return 3; //SetCommState error
}
opened = 1;
return(0);
}
/* Close Communication port */
void ComPort::Close (){
if (opened!=1) return;
opened = 0;
CloseHandle( hCom );
}
int ComPort::RxBuffNum(){
COMSTAT stat;
unsigned long err;
ClearCommError(hCom, &err, &stat);
return stat.cbInQue;
}
int ComPort::Read(char * c,int num){
DWORD length = 0;
if( !ReadFile(hCom, c, num, &length, NULL) ) return 0;
return length;
}
const char * ComPort::Read(int num){
delete luaBuff;
luaBuff = new char[num];
memset(luaBuff, 0, num);
lastReadNum = Read(luaBuff, num);
return luaBuff;
}
int ComPort::LastReadNum(){
return lastReadNum;
}
/*
Send a character
*/
int ComPort::Write(char *c, int num){
DWORD length = 0;
WriteFile(hCom, c, num, &length, NULL);
return length;
}
int ComPort::Write(char c){
DWORD length;
return WriteFile(hCom, &c, 1, &length, NULL);
}
int ComPort::Write(char * c){
DWORD length;
int num = 0;
while (c[num]) num += 1;
return WriteFile(hCom, c, num, &length, NULL);
}
int ComPort::Writef(char * str, ...){
char tmpStr[1024];
va_list args;
va_start (args, str);
vsprintf_s (tmpStr, 1024, str, args);
va_end (args);
return Write(tmpStr);
}