1

私のソースコードで非常に奇妙なことが起こります。次の関数はうまく機能し、パスワードが正しい場合は 'y' を出力し、正しくない場合は 'n' を出力します。しかし、いくつかの UART1_Write および Delay 関数を else ステートメントに追加すると、バグが出てきて、パスワードが "zxc" (正しい) であっても、常に else ステートメントに入ります。私は PIC v6.0.0 用に MikroC PRO を使用しています。ロボット システムは PIC18F452 とそれに接続された RN-42 Bluetooth モジュールで構成されています。BluetoothとTeraTermを備えたラップトップでテストしています。

詳細情報: http://instagram.com/p/pLnU9eDL8z/#

これはうまく機能するルーチンです。

void authenticate() {
     char *input = "";
     char *password = "zxc\0";
     unsigned char ready = 0;

     while (connected && !ready) {
           if (UART1_Data_Ready()) {
              UART1_Read_Text(input, "|", 17);
              strcat(input, "\0");

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

このバージョンのルーチンは、常に strcmp(input, password) == 0 の部分の ELSE ステートメントに入ります。

void authenticate() {
     char *input = "";
     char *password = "zxc\0";
     unsigned char ready = 0;

     while (connected && !ready) {
           if (UART1_Data_Ready()) {
              UART1_Read_Text(input, "|", 17);
              strcat(input, "\0");

              if (strcmp(input, password) == 0) {
                 UART1_Write('y');
                 ready = 1;
              } else {
                 UART1_Write('n');
                 Delay_ms(100);
                 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');
                 ready = 1;
              }
           }
     }
}

RN-42 をコマンド モードにして、パスワードが間違っている場合にユーザーを切断するには、これらすべての追加シンボルを送信することが重要です。問題を解決するのを手伝ってください。どんなアイデアでも大歓迎です!

4

1 に答える 1

3

コメント セクションで他の人が指摘しているように、コードの主な問題は、自分のものではないメモリに UART データを保存しようとしているということです。

を宣言するときchar *input = "";、「 」を格納する 1 バイトを除いて、実際にはスペースを割り当てていません\0。次に、 を使用するときにUART1_Read_Text()、区切り文字を見つける前に最大 17 文字を読み取ることができることをその関数に指示します。これらの文字はすべて、 が指す場所に格納する必要がありますinput

そのライブラリ関数の説明は、ここにあります。また、ライブラリの説明に基づいて、UART データにヌル終端が既に追加されているようです。 UART1_Read_Text()この仮定はUARTx_Write_Text、彼らの Web サイトで提供されている説明と例に基づいています。ただし、実際にそうであることを確認することをお勧めします。

また、 の初期化passwordは冗長であるため、char *password = "zxc\0"に変更する必要がありますchar *password = "zxc"。二重引用符を使用して文字列リテラルを宣言すると、自動的に null で終了します。この抜粋は、「C in a Nutshell」からのものです。

文字列リテラルは、二重引用符で囲まれた一連の文字 (および/またはエスケープ シーケンス) で構成されます... . 空の文字列 "" はメモリ内で正確に 1 バイトを占有し、終端の null 文字を保持します。

上記を踏まえて、もう少し詳しく説明すると、次のようになります。

#define MAX_NUM_UART_RX_CHARACTERS    17
void authenticate() 
{
    char input[MAX_NUM_UART_RX_CHARACTERS + 1];
    char *password = "zxc";
    unsigned char ready = 0;

    while (connected && !ready) 
    {
        if (UART1_Data_Ready()) 
        {
            UART1_Read_Text(input, "|", MAX_NUM_UART_RX_CHARACTERS);

            if (strcmp(input, password) == 0) 
            {
                UART1_Write('y');
                ready = 1;
            } 
            else 
            {
                UART1_Write('n');
                ready = 1;
            }
        }
    }
}
于 2014-06-17T00:04:09.397 に答える