1

タイトルの通り、シリアル ポートから 300 ~ 400 ミリ秒のパルスを送信する必要があります。私のセンサーは、目を覚ますためにそのようなパルスを必要とします。私のセンサーのプロデューサーが提供するプログラムは、Windows でこれを行うことができます。ただし、私のプロジェクトはubuntuを使用しているため、ubuntuで同様のプログラムを開発する必要があります。指摘も大歓迎です。

よろしく、

4

1 に答える 1

2

まず第一に、そのパルスを与えたいピンを決定したいと思うでしょう。RS232 に関するウィキペディアのページを見て、どの信号が存在するかを確認してください。Tx (Transmit Data) でパルスを送信することは可能ですが、これはかなり珍しいことですが、RTS または DTR を介してパルスを送信する必要があると思います。

これを行うには、ioctlが必要です。これは、DTR をパルスしたい場合の方法です。

int pulseDTR(int fd)
{
    int status;

    // get the current modem control lines status
    if (ioctl(fd, TIOCMGET, &status) == -1) {
        // handle the error
    }

    // Now set DTR high
    status |= TIOCM_DTR;
    // and apply  
    if (ioctl(fd, TIOCMSET, &status) == -1) {
        // handle the error
    }
    // wait a bit
    usleep (400*1000);
    // Now set DTR low
    status &= ~TIOCM_DTR;
    // and apply  
    if (ioctl(fd, TIOCMSET, &status) == -1) {
        // handle the error
    }

    return 0;
}

RTS をパルスする必要がある場合は、 に置き換えTIOCM_DTRTIOCM_RTSください。

シリアル ポートのプログラミングの詳細については、Serial Programming Guide for POSIX Operating SystemsおよびLinux serial Howtoをお勧めします。

編集:OPのコメントに基づいて、ブレークを送信することが実際に必要です。ブレークを送信するということは、Tx ラインが一定時間 (制御信号ではなく) 論理 0 になることを意味します。これは、Linux シリアル プログラミングのハウツーで説明されており、次のように行われます。

ioctl の使用:

   int ioctl( fd, TCSBRK, int arg );

tc* 呼び出しの使用

   int tcsendbreak( fd, int arg );

Linux シリアル プログラミング ハウツーのコメントに注意してください。

ブレークを送る: ここで、従来の
ioctl() 呼び出しと POSIX 呼び出しで動作が異なります。従来の呼び出しでは、引数「0」は UART のブレーク制御ラインを 0.25 秒に設定します。POSIX コマンドの場合、区切り行は arg に 0.1 秒を掛けた値に設定されます。

EDIT2: オープン ソースの素晴らしい点は、ソースが利用できることです:-) これは minicom ソースからの逐語的なものであり、ブレークを送信する 3 つの方法を示しているため、非常に優れています。

/*
 * Send a break
 */
void m_break(int fd)
{
#ifdef USE_SOCKET
  if (portfd_is_socket)
    return;
#endif
#ifdef POSIX_TERMIOS
  tcsendbreak(fd, 0);
#else
#  ifdef _V7
#    ifndef TIOCSBRK
  {
    struct sgttyb sg, ng;

    ioctl(fd, TIOCGETP, &sg);
    ioctl(fd, TIOCGETP, &ng);
    ng.sg_ispeed = ng.sg_ospeed = B110;
    ng.sg_flags = BITS8 | RAW;
    ioctl(fd, TIOCSETP, &ng);
    write(fd, "\0\0\0\0\0\0\0\0\0\0", 10);
    ioctl(fd, TIOCSETP, &sg);
  }
#    else
  ioctl(fd, TIOCSBRK, 0);
  sleep(1);
  ioctl(fd, TIOCCBRK, 0);
#    endif
#  endif
#endif
} 
  1. Linuxは最初のオプションを使用していると思いますが、tcsendbreak(fd, 0);
  2. 3 番目のオプションも非常に興味深いものです。パフォーマンスioctl(fd, TIOCSBRK, 0);に続いてスリープ コールが続き、その後にioctl(fd, TIOCCBRK, 0);微調整された長さのブレーク信号を送信できるはずです。
  3. 2 番目のオプションは、ポート設定をいじってゼロの文字列を送信することでブレークをエミュレートする方法を示しているため、実際にはかなり気の利いたものです。break を実装していないシステムでは常に便利です。

で、結論?最初に を試すtcsendbreak(fd, 0);のが最も簡単で、それでうまくいかない場合は を試してくださいioctl(fd, TIOCSBRK, 0); some sort of sleep ; ioctl(fd, TIOCCBRK, 0);。正常なシステムでは、「エミュレートされたブレーク」は必要ありません。

于 2013-03-31T10:58:42.287 に答える