2

シリアルポートを介してLPC1786マイクロコントローラーにいくつかのコマンドを送信します。このタスクを実行するために、このコードを使用してシリアルポートを開きます。

struct termios tio;
int tty_fd;

memset(&tio,0,sizeof(tio));
tio.c_iflag = 0;
tio.c_oflag = 0;
tio.c_cflag = CS8|CREAD|CLOCAL;           // 8n1, see termios.h for more information
tio.c_lflag = 0;
tio.c_cc[VMIN] = 1;
tio.c_cc[VTIME] = 5;

tty_fd = open(device, O_RDWR | O_NONBLOCK);
cfsetospeed(&tio, B9600);            // 115200 baud
cfsetispeed(&tio, B9600);            // 115200 baud
tcflush(tty_fd, TCIFLUSH);

これは、(iMX53)を使用する組み込みLinuxシステム用です。PCでコードをコンパイルして実行するとき。私はこれを手に入れます:

sent:    ?
recieve: Sinchronized<CR><LF>
sent:    Sinchronized<CR><LF>
recieve: Synchronized<CR>OK<CR><LF>
sent:    16000<CR><LF>
recieve: 16000<CR>OK<CR><LF>

魔女は元気です。クロスコンパイルしてシステムにアップロードすると、これが表示されます。

Sent:  ?
HEX:   0x53 0x79 0x6E 0x63 0x68 0x72 0x6F 0x6E 0x69 0x7A 0x65 0x64 0xA 0xA 0x53 0x79 0x6E 0x63 0x68 0x72 0x6F 0x6E 0x69 0x7A 0x65 0xA
ASCII: SynchronizedSynchronizedOKOKnchronized1K024K024chronized1

Sent:  ?
HEX:   0xA 0xA 0xA 0xA 0xA 0xA 0xA 0x30 0xA 0xA 0x31 0xA 0xA 0xA 0xA 0xA 0xA 0x34 0xA 0xA 0x31 0xA 0xA 0xA 0xA 0xA 0xA 0xA 0xA 0xA 0A
ASCII: 014141hronized1111111ronized1

魔女は私の一日を台無しにします。書き込みと読み取りには、書き込みと読み取りの関数を使用しています。これは私がシリアルポートを開いている方法と関係があるに違いありません。しかし、何が悪いのか。さまざまな設定を試しましたが、ほとんど成功しませんでした。最良の場合、応答として「?????1???」が表示されます。そして、ほとんどの場合、読むべきものは何もありません。

4

4 に答える 4

3

基本的な問題は、コードがttyポートを(適切に)初期化していないことを示していることです。tcsetattr()基本的に、初期化は、指定しようとした更新された構成をインストールするために呼び出されません。

ttyポートを初期化する適切な方法は、ポートを開き、現在の属性を取得し、プログラム終了時に復元するために現在の属性を保存し、属性を変更して、属性をインストールすることです。また、システムコールからのリターンコードを常にテストします。

    tty_fd = open(device, O_RDWR | O_NONBLOCK);
    if (tty_fd< 0) {
        syslog(LOG_DEBUG, "failed to open: %d, %s", tty_fd, strerror(errno));
        exit (-1);
    }
    rc = tcgetattr(tty_fd, &tio);
    if (rc < 0) {
        syslog(LOG_DEBUG, "failed to get attr: %d, %s", rc, strerror(errno));
        exit (-2);
    }
    savetio = tio;    /* preserve original settings for restoration */

    spd = B9600;
    cfsetospeed(&tio, (speed_t)spd);
    cfsetispeed(&tio, (speed_t)spd);

    cfmakeraw(&tio);

    tio.c_cc[VMIN] = 1;
    tio.c_cc[VTIME] = 5;

    tio.c_cflag &= ~CSTOPB;
    tio.c_cflag &= ~CRTSCTS;    /* no HW flow control? */
    tio.c_cflag |= CLOCAL | CREAD;
    rc = tcsetattr(tty_fd, TCSANOW, &tio);
    if (rc < 0) {
        syslog(LOG_DEBUG, "failed to set attr: %d, %s", rc, strerror(errno));
        exit (-3);
    }

もちろん、ケーブルやハードウェアの問題もまだ解決されていない可能性がありますが、ttyポートが希望または必要な動作状態に初期化されていないため、期待どおりに機能しない可能性があります。

シリアルポートをプログラミングするためのガイドは次のとおりです。

于 2013-03-21T19:06:12.987 に答える
1

この質問には多くの良いデバッグコメントがありますが、シリアルリンクをチェックするための項目の要約リストがあります:(私自身のいくつかを追加し、開発システムの立ち上げに傾いています)

これら2つは、一種の初期設計レベルのチェックです。時々あなたはそれらを再訪することになります:

  • データシートを確認してください:電圧レベルは一致していますか?例:「真の」RS232対TTL、12v対5v対3v
  • ケーブルまたは回路接続をバズアウトします:接地、差動がTX + / TX-などの一致を行う場合、rxはtxに移行しますか?(特にカスタムケーブルまたは手作りケーブルの場合)

これらはより一般的です:

  • ボーレートが一致することを確認します
  • データ、ストップビット、フロー制御設定が両端で一致していることを確認してください
  • より低いボーレートは機能しますか?
  • おそらく代替ケーブルを試してみませんか?
  • おそらく別のPCを試してみてください(ラップトップのAC電源で奇妙なグランドループが発生し、一度問題が発生しました)
  • 可能であれば、一方の端を「正常な」量にします。

これらはまれなチェックです:

  • シリアルペリフェラルのボーレートを供給する入力クロック設定を確認します。
  • スコープを分割して、信号が破損していないかどうかを確認します(レベルの変化は「正方形」であり、ハードウェアの電圧レベルと一致していますか)
于 2013-03-21T17:04:28.540 に答える
1

他の回答で言及されている問題に加えて、考えられる原因の1つは、MCUUARTに供給されるプリスケーラクロックの不良です。UARTには±3%のクロック精度が必要です。プリスケーラがそれほど正確でない場合は質問で説明されている種類の問題が発生します。ほとんどの場合、データは正常に表示され、突然ゴミが発生します。

これをトラブルシューティングするときは、レシーバー側でオーバーラン、フレーミングエラーなどをチェックする必要があります。信号を確認し、オシロスコープでボーレートを測定します。オシロスコープなしで組み込みアプリケーションを開発することはできません。それはデバッガと同じくらい不可欠なツールです。

于 2013-03-22T07:21:54.533 に答える
1

私は本質的にハードウェアの人なので、このようなことが起こったとき、私は下から始める傾向があります。

  • スコープまたはロジックアナライザーを取り出して、送信されたビットを確認します。ボーレートを確認してください。文字を確認してください。あなたのためにビットを解釈するスコープはここで大きな助けになります:)

  • 問題がない場合は、バイトが組み込みプロセッサに問題なく入っていることを確認します。割り込みサービスルーチンを確認してください。エントリにビットを設定し、終了する前にクリアします。入ってくる文字がISRをオーバーランしていないことを確認してください。

そこから作業を進めます-ISRからデータを取得する低レベルのドライバーはありますか?

于 2013-03-22T12:11:51.930 に答える