pesoshin 0 18 октября, 2012 Опубликовано 18 октября, 2012 · Жалоба Доброго времени суток! Возможно ли использовать стандартный персональный компьютер в качестве GPIO-контроллера? Хочу подключить к нему всего 4 линии, на 2 из них подать высокий логический уровень, и 2 другие в программе опрашивать на наличие сигнала. Нужен ли в данном случае нестандартный контроллер (покупной, разрабатываемый) или он уже есть в составе ПК (если да, как к нему подключиться)? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kovigor 6 18 октября, 2012 Опубликовано 18 октября, 2012 · Жалоба Возможно ли использовать стандартный персональный компьютер в качестве GPIO-контроллера? Хочу подключить к нему всего 4 линии, на 2 из них подать высокий логический уровень, и 2 другие в программе опрашивать на наличие сигнала. Нужен ли в данном случае нестандартный контроллер (покупной, разрабатываемый) или он уже есть в составе ПК (если да, как к нему подключиться)? Все зависит от скорости. У обычного LPT-порта есть целых пять (если не ошибаюсь) линий, способных работать на ввод. Пример такого решения - всем известный AvReal. А вот статья, одна из нескольких, как минимум: http://www.pcports.ru/articles/2.php Еще способ, сравнительно простой - использовать обычную PCI-ную сетевую карточку. У таких карточек есть загрузочное ПЗУ или хотя бы панелька для него, вот к ней и можно подключиться: http://fpga-faq.narod.ru/ Ну и, наконец, можно сделать простейший адаптер на МК, подключаемый к COM - порту. И к этому адаптеру подключить ваши линии (это, если скорости небольшие, наиболее предпочтительный вариант) ... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
pesoshin 0 18 октября, 2012 Опубликовано 18 октября, 2012 · Жалоба Все зависит от скорости. У обычного LPT-порта есть целых пять (если не ошибаюсь) линий, способных работать на ввод. Пример такого решения - всем известный AvReal. А вот статья, одна из нескольких, как минимум: http://www.pcports.ru/articles/2.php Еще способ, сравнительно простой - использовать обычную PCI-ную сетевую карточку. У таких карточек есть загрузочное ПЗУ или хотя бы панелька для него, вот к ней и можно подключиться: http://fpga-faq.narod.ru/ Ну и, наконец, можно сделать простейший адаптер на МК, подключаемый к COM - порту. И к этому адаптеру подключить ваши линии (это, если скорости небольшие, наиболее предпочтительный вариант) ... спасибо за ответ! Видимо, действительно, штатной возможности у ПК нет (на electronics.stackexchange.com ответили то же самое). Наверно остановлюсь на МК или покупном чем-нибудь вроде http://www.mccdaq.com/pci-data-acquisition...O24-Series.aspx Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_pv 78 18 октября, 2012 Опубликовано 18 октября, 2012 · Жалоба спасибо за ответ! Видимо, действительно, штатной возможности у ПК нет такая штатная возможность есть у последовательных портов. или переходников USB -> serial, если на плате нет. там помимо RX,TX есть на выход две линии RTS и DTR, правда с уровнями +-12В. и 4 линии на вход CTS, DSR, DCD и RI, которые обычно от 3-5 вольтовых TTL лог уровней тоже срабатывают. порог на уровне около +1.4В EIA-232 Input Threshold Low 1.2 V EIA-232 Input Threshold High 1.6 V скорости-то какие нужны? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kovigor 6 18 октября, 2012 Опубликовано 18 октября, 2012 · Жалоба такая штатная возможность есть у последовательных портов. или переходников USB -> serial, если на плате нет. C USB надежность никудышняя выйдет. Хотя, смотря, для чего это надо. Можно (и лучше) такое сделать с настоящим COM - портом, только вот нужно ли ? Не проще ли будет сделать простейший адаптер на МК с RS232C и подключить его к COM-порту не через левое колено, а как полагается ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_pv 78 18 октября, 2012 Опубликовано 18 октября, 2012 · Жалоба C USB надежность никудышняя выйдет. Хотя, смотря, для чего это надо. Можно (и лучше) такое сделать с настоящим COM - портом, только вот нужно ли ? Не проще ли будет сделать простейший адаптер на МК с RS232C и подключить его к COM-порту не через левое колено, а как полагается ? насчёт надёжности, не знаю, особых проблем при использовании переходниками USB->COM вроде не возникало, единственное что было это кривые драйвера для XP64, когда незакрытый порт периодически вызывал синий экран при закрытии программы. да еще нежелание работать вместе нескольких одинаковых тексасовских демо плат, где usb->com тексасовские же, не могли нормально номера портов поделить между собой, и то только на ноутбуке, то есть работало оно почему-то при включении в определённой последовательности и только в определённые порты, причина опять же в кривых драйверах. ну и еще со скоростью переключения контрольно-статусных io порта через usb переходник тоже беда. но если нужна только пара IO без каких-либо жестких требований по времени, то зачем плодить лишние сущности в виде МК. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kovigor 6 19 октября, 2012 Опубликовано 19 октября, 2012 · Жалоба но если нужна только пара IO без каких-либо жестких требований по времени, то зачем плодить лишние сущности в виде МК. Уж лучше в виде MK, подключаемого к настоящему COM - порту, чем в виде USB-переходника ... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
pesoshin 0 19 октября, 2012 Опубликовано 19 октября, 2012 · Жалоба такая штатная возможность есть у последовательных портов. или переходников USB -> serial, если на плате нет. там помимо RX,TX есть на выход две линии RTS и DTR, правда с уровнями +-12В. и 4 линии на вход CTS, DSR, DCD и RI, которые обычно от 3-5 вольтовых TTL лог уровней тоже срабатывают. порог на уровне около +1.4В EIA-232 Input Threshold Low 1.2 V EIA-232 Input Threshold High 1.6 V скорости-то какие нужны? Про скорости - входной сигнал опрашивается не чаще раза в 1 мс (f <= 1000 Гц), при этом первый фронт на одной из линий хотелось бы поймать максимально быстро. А разве можно управлять линиями последовательного порта ПК на манер GPIO (а как?)? Это что-то вроде bitbang mode у FT232RL? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_pv 78 19 октября, 2012 Опубликовано 19 октября, 2012 · Жалоба Про скорости - входной сигнал опрашивается не чаще раза в 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: #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: #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); } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kovigor 6 19 октября, 2012 Опубликовано 19 октября, 2012 · Жалоба Про скорости - входной сигнал опрашивается не чаще раза в 1 мс (f <= 1000 Гц), при этом первый фронт на одной из линий хотелось бы поймать максимально быстро. А требование управлять объектом непосредственно от PC чем-то реально обусловлено ? Или только тем, что вы не владеете программированием для МК ? Почему бы не управлять объектом именно от МК, в реальном времени, а уже задания (или уставки) для МК формировать и передавать с PC, не cвязывая себя жесткими временными ограничениями ? Можете рассказать о задаче более подробно ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
iosifk 3 19 октября, 2012 Опубликовано 19 октября, 2012 · Жалоба Доброго времени суток! Возможно ли использовать стандартный персональный компьютер в качестве GPIO-контроллера? Хочу подключить к нему всего 4 линии, на 2 из них подать высокий логический уровень, и 2 другие в программе опрашивать на наличие сигнала. Нужен ли в данном случае нестандартный контроллер (покупной, разрабатываемый) или он уже есть в составе ПК (если да, как к нему подключиться)? DLP2232 на FTDI2232. Вот только USB - это для несерьезных вещей... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
pesoshin 0 19 октября, 2012 Опубликовано 19 октября, 2012 · Жалоба _pv спасибо за действительно интересный подход kovigor необходимости нет, да и об управлении объектом речь не идет. Внешний объект - два концевых выключателя, которые в процессе эксперимента то включают, то выключают. Интерфейс на ПК - 2 линии, чтобы их "входы" запитать, 2 линии, чтобы посмотреть, есть ли сигналы с "выходов", вся остальная логика - графика, логика эксперимента на ПК. Если интересно, могу в личку скинуть о чем идет речь :-) Мне кажется, что ответ на свой вопрос я уже более чем получил, спасибо всем :-) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kovigor 6 19 октября, 2012 Опубликовано 19 октября, 2012 · Жалоба Если интересно, могу в личку скинуть о чем идет речь :-) Мне кажется, что ответ на свой вопрос я уже более чем получил, спасибо всем :-) Скиньте. Интересно. И еще вот что интересно: на чем вы остановились ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться