Zamiast używać portu równoległego, czy za pomocą urządzenia seryjny? Ponieważ masz sygnał TTL, prawdopodobnie będziesz potrzebował konwertera poziomów do konwersji poziomów TTL na poziomy RS232 +/- 12V. Gdy używasz urządzenia szeregowego, możesz użyć standardowych wywołań szeregowych ioctl()
, aby wykryć zmianę statusu sygnału sterującego.
W szczególności można użyć ioctl TIOCMIWAIT
na podłączonym urządzeniu szeregowym, aby poczekać na zmianę, powiedzmy linię DCD, którą podłączysz do źródła zegara.
Twoja aplikacja przestrzeni użytkownika zostanie zablokowana podczas oczekiwania na wywołanie systemowe systemu ioctl TIOCMIWAIT
, dopóki nie nastąpi zmiana statusu na linii zegara, w którym to momencie aplikacja może zostać uruchomiona i powrócić z ioctl. Być może będziesz musiał się upewnić, że załatwisz przypadek, w którym zmienisz status przerwań zarówno na wznoszących się jak i opadających zboczach szeregowych sygnałów sterujących. Na niektórych urządzeniach UART (np. TL16C554A UART) możliwe jest, że otrzymasz tylko przerwanie na przejście sygnału w jednym kierunku. Na przykład dla TL16C554A, TIOCMIWAIT
będzie tylko spadać na zboczu narastającym dowolnej zmiany sygnału dzwonka.
Korzystanie z seryjnych ioctli w ten sposób ma także tę zaletę, że można użyć klucza USB-Serial, który obsługuje TIOCMIWAIT
w razie potrzeby (np. PL2303) i nadal zachowuje kompatybilność oprogramowania na poziomie użytkownika, aczkolwiek kosztem zwiększonego opóźnienia ze względu na na USB.
Jeśli potrzebujesz mniejszego opóźnienia, niż można uzyskać dzięki przestrzeni użytkownika, najlepiej napisać moduł sterownika jądra, który może obsłużyć czas i próbkowanie, ale nie sugerowałbym tej trasy, jeśli nie jest to absolutnie konieczne. Łatwiej jest opracować kod przestrzeni użytkownika.
Oto niektóre niekompletne fragmenty kodu C próbki do korzystania z Ioctl TIOCMIWAIT
.
int serial_fd = open(cmdline.device_name, O_RDWR | O_NONBLOCK | O_NOCTTY);
static const unsigned int ri_flag = TIOCM_RNG;
/* Set up serial port here using tcsetattr. Set CRTSCTS | CLOCAL to ensure status interrupts
* are generated.
*/
while (1) {
/* Wait for positive RI transition. TIOCMIWAIT takes a mask
* as argument, only returning when the appropriate signal has changed.
*/
if (ioctl(serial_fd, TIOCMIWAIT, ri_flag)) {
fprintf(stderr, "ioctl() failed waiting for RI edge [%s]\n", strerror(errno));
break;
}
/* Do sensor sampling here. You could use TIOCMGET to first verify that
* the clock line is in the expected state, eg high, before continuing.
*/
}
To jest dokładnie to, co chciałbym zrobić. Nie wiedziałem, że nadal mogę używać przerwań RS232 przez adapter USB. To na pewno upraszcza sprawy. Wygląda na to, że mogę to łatwo zaimplementować w Pythonie za pomocą pytania http://stackoverflow.com/questions/5904895/python-monitor-serial-port-rs-232-handshake-signals – Mike
Przykład iokt Pythona działał idealnie z prawdziwym seryjnym Port! ioctl zwrócił błąd "Argument" za każdym razem, gdy próbowałem tego z adapterem USB Keyspan, ale lepiej nie mieć opóźnienia i używać prawdziwego portu COM. Teraz wystarczy zbudować regulator TTL na poziomie +/- 12V. – Mike
@Mike Spojrzałem w źródle, sterownik keyspan nie obsługuje 'TIOCMIWEIT'. Tylko niektóre sterowniki USB-serial obsługują to, szukają '.tiocmiwait' w plikach sterowników w katalogu źródłowym' drivers/usb/serial'. PL2303 jest bardzo popularnym adapterem usb-serial. Możesz znaleźć jedną z nich i zhakować, aby ominąć przedni koniec +/- 12V w kluczu sprzętowym. Alternatywnie, Maxim tworzy serię układów konwerterów poziomów. –