|
|
 |
Ответов
|
Oct 18 2012, 13:41
|
Гуру
     
Группа: Свой
Сообщений: 5 273
Регистрация: 30-03-10
Пользователь №: 56 295

|
Цитата(Andrey Pesoshin @ Oct 18 2012, 16:16)  Возможно ли использовать стандартный персональный компьютер в качестве GPIO-контроллера? Хочу подключить к нему всего 4 линии, на 2 из них подать высокий логический уровень, и 2 другие в программе опрашивать на наличие сигнала. Нужен ли в данном случае нестандартный контроллер (покупной, разрабатываемый) или он уже есть в составе ПК (если да, как к нему подключиться)? Все зависит от скорости. У обычного LPT-порта есть целых пять (если не ошибаюсь) линий, способных работать на ввод. Пример такого решения - всем известный AvReal. А вот статья, одна из нескольких, как минимум: http://www.pcports.ru/articles/2.phpЕще способ, сравнительно простой - использовать обычную PCI-ную сетевую карточку. У таких карточек есть загрузочное ПЗУ или хотя бы панелька для него, вот к ней и можно подключиться: http://fpga-faq.narod.ru/Ну и, наконец, можно сделать простейший адаптер на МК, подключаемый к COM - порту. И к этому адаптеру подключить ваши линии (это, если скорости небольшие, наиболее предпочтительный вариант) ...
|
|
|
|
|
Oct 18 2012, 17:41
|
Участник

Группа: Участник
Сообщений: 51
Регистрация: 5-07-10
Пользователь №: 58 297

|
Цитата(kovigor @ Oct 18 2012, 17:41)  Все зависит от скорости. У обычного 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
|
|
|
|
|
Oct 18 2012, 18:10
|
Гуру
     
Группа: Свой
Сообщений: 2 563
Регистрация: 8-04-05
Из: Nsk
Пользователь №: 3 954

|
Цитата(Andrey Pesoshin @ Oct 18 2012, 23:41)  спасибо за ответ! Видимо, действительно, штатной возможности у ПК нет такая штатная возможность есть у последовательных портов. или переходников 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 скорости-то какие нужны?
|
|
|
|
|
Oct 19 2012, 08:58
|
Участник

Группа: Участник
Сообщений: 51
Регистрация: 5-07-10
Пользователь №: 58 297

|
Цитата(_pv @ Oct 18 2012, 22:10)  такая штатная возможность есть у последовательных портов. или переходников 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?
|
|
|
|
|
Oct 19 2012, 09:59
|
Гуру
     
Группа: Свой
Сообщений: 2 563
Регистрация: 8-04-05
Из: Nsk
Пользователь №: 3 954

|
Цитата(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); }
|
|
|
|
Сообщений в этой теме
Andrey Pesoshin ПК и GPIO-интерфейс Oct 18 2012, 13:16   kovigor Цитата(_pv @ Oct 18 2012, 21:10) такая шт... Oct 18 2012, 20:51    _pv Цитата(kovigor @ Oct 19 2012, 03:51) C US... Oct 18 2012, 22:06     kovigor Цитата(_pv @ Oct 19 2012, 01:06) но если ... Oct 19 2012, 07:34    kovigor Цитата(Andrey Pesoshin @ Oct 19 2012, 11... Oct 19 2012, 10:34 iosifk Цитата(Andrey Pesoshin @ Oct 18 2012, 17... Oct 19 2012, 11:18 Andrey Pesoshin _pv
спасибо за действительно интересный подход
ko... Oct 19 2012, 13:11 kovigor Цитата(Andrey Pesoshin @ Oct 19 2012, 16... Oct 19 2012, 13:15
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|