0

私は PICKit3、PIC v6.0.0 用の MikroC PRO、PIC18F45 @ 8MHz、および RN-42 Bluetooth モジュールを使用しています。ラップトップと Android アプリの両方から RN-42 モジュールに接続し、パスワードを送信しています。奇妙なことに、PIC はパスワードが正しいと言うことがありますが、そうでないこともあります。同じ文字列を送信しています。テスト中、たまたま最初の 1 回だけパスを受け入れず、他のすべての試みは受け入れられました。UART ボーレートは、PIC と RN-42 の両方で 9600 に設定されています。RN-42 の RTS と CTS が接続されていません。

私も試しました:

char password[] = "abc";
char password[4] = "abc";
char password[5] = "abc\0";
char *password = "abc\0";

strcmp(input, "\0"); after the UART1_Read_Text(input, "|", MAX_UART_RX_CHARACTERS);

しかし、それは同じです...何が問題なのですか、それは私のコードにありますか、それともMikroC関数内で発行することは可能ですか?

void authenticate() {
     char input[MAX_UART_RX_CHARACTERS + 1] = "";
     char password[] = "abc\0";
     unsigned char ready = 0;

     Delay_ms(500);
     UART1_Write_Text("TRobot\n");

     while (connected && !ready) {
           if (UART1_Data_Ready()) {
              TMR0ON_bit = 0;
              time_out = 0;
              UART1_Read_Text(input, "|", MAX_UART_RX_CHARACTERS);

              if (strcmp(input, password) == 0) {
                 UART1_Write('y');
                 serve();
              } else {
                 UART1_Write('n');
                 disconnect();
              }

              ready = 1;
           }

           if (time_out) {
              disconnect();
           }
     }
}

UARTx_Read_Text() プロトタイプ:

void UARTx_Read_Text(char *Output, char *Delimiter, char Attempts);

UARTx_Read_Text() 説明:

デリミタ シーケンスが検出されるまで、UART 経由で受信した文字を読み取ります。読み取りシーケンスはパラメーター出力に格納されます。区切り文字シーケンスは、パラメーター区切り文字に格納されます。

これはブロッキング呼び出しです。デリミタ シーケンスが必要です。それ以外の場合、プロシージャは終了します (デリミタが見つからない場合)。

パラメーター :

出力: 受信したテキスト デリミタ: 受信した文字列の終わりを識別する文字のシーケンス 試行: デリミタ シーケンスが期待される受信文字数を定義します。Attempts が 255 に設定されている場合、このルーチンは連続して Delimiter シーケンスを検出しようとします。

例:

シーケンス「OK」が受信されるまでテキストを読み取り、受信したものを返信します。

UART1_Init(4800);                         // initialize UART1 module
Delay_ms(100);

while (1) {
  if (UART1_Data_Ready() == 1) {          // if data is received 
    UART1_Read_Text(output, "OK", 10);    // reads text until 'OK' is found
    UART1_Write_Text(output);             // sends back text 
 }
}
4

5 に答える 5

3

おそらくUART1_Read_Text()期待通りの動作をしません。その(非標準)関数のドキュメント/ソースを探しましたが、見つかりませんでした。

ユーザーが return キーを押したときに文字で適切に終了inputすることを確認してください。'\0'

于 2014-07-02T07:16:08.647 に答える
1

問題を解決しました。disconnect() を呼び出した後に問題が発生することがわかりました

通常、入力がパスワードと異なる場合、disconnect() が呼び出されます。新しい接続が確立され、正しいパスワード文字列が送信されると、毎回入力文字列の先頭に 2 バイトが追加されることに気付きました。UART1_Write_Text(input)を使って簡単なデバッグを行いました。

切断機能は、RN-42 モジュールをコマンド モードに設定し、接続を切断してコマンド モードを終了します。RN-42 の赤い LED が速く点滅し始め、その後ゆっくりと点滅します。これは、CMD モードではないことを意味します。切断機能を削除し、パスワードの試行間に 5000 ミリ秒のタイムアウトを設定しました。しかし、私はまだ何が問題を引き起こしているのか正確にはわかりません。

void disconnect() {
     UART1_Write('$');
     Delay_ms(100);
     UART1_Write('$');
     Delay_ms(100);
     UART1_Write('$');
     Delay_ms(100);
     UART1_Write('K');
     Delay_ms(100);
     UART1_Write(',');
     Delay_ms(100);
     UART1_Write('-');
     Delay_ms(100);
     UART1_Write('-');
     Delay_ms(100);
     UART1_Write('-');
     Delay_ms(100);
     UART1_Write('\n');
     Delay_ms(100);
}
于 2014-07-05T07:51:33.860 に答える
1

strlen(input)背後に目に見えないシンボルがあるかどうかを確認したり、配列の値を値ごとに比較して違いがどこにあるかを確認したりできます。

またstrncmp(input, password, strlen(password));、役立つかもしれません。passwordこれは、有効なパスワードを作成する長さの背後にあるすべての記号を無視するabcdため、これを恐れてください.

于 2014-07-02T07:42:24.103 に答える
1

strcmp() は、同じ入力に対して異なる値を返します

いいえ、違います。同一の入力が与えられると、strcmp()同一の出力が返されます。明らかに、同一の入力を異なる呼び出しに渡していませんstrcmp()。値を調べて、それらがどこで異なるかを見つけるために、いくつかのデバッグを行う必要があります。

于 2014-07-02T08:29:09.380 に答える
0

読み取り関数がデータを間違って取得しているようです。割り込みが無効になっているようです。IRQ を有効にして、割り込みでデータを受信することをお勧めします。そうしないと、データが失われます。

とにかく、1.デバイスが物理的に取得するものと2.読み取り機能が機能した後にメモリにドロップするものを比較すると役立ちます。

  1. オシロスコープで見る - それはバイトの短いシーケンスで、簡単に見ることができます。

  2. 別のインターフェイスがある場合はそれを介して出力するか、JTAG でデバッグできます。

誰もがより理解を深め、より良い答えを出せるように、結果と最新の質問を含めてください。

于 2014-07-02T09:55:57.880 に答える