2016-04-25 21 views
3

私はRaspから5バイトのデータを送信しています。 UARTを使用してdsPIC30Fマイクロコントローラを介して受信します。データを正しく受信し、MAXCNTレジスタを希望の値に設定することができます。問題は、私が2番目の値を送信しようとしたときに発生します。 newResBuffer []の値は、最初に読み込まれたデータの後で変更されません。文字の配列へのポインタのリセット

私はポインタ/配列については初心者ですが、自分の問題が自分のポインタをリセットする方法にあると思われます。私はこれを成功させることなく、さまざまな方法で試しました。このステップを正しく実行していますか?

#include <string.h> 

char newResBuffer[10]; 
char *nR = newResBuffer; 
char *nRreset = NULL; 
char rxRead = 0; 
int newRes = 0; 
int newResFlag = 0; 
int j = 0; 

int main(void) 
{ 
    nRreset = nR; // set reset point at the beginning of newResBuffer[] 

    while(1) 
    { 
    if(U1STAbits.URXDA) // check if there is data available 
    { 
     rxRead = U1RXREG & 0xFF; //read data from UART receive register 
     *nR = rxRead; //store data to first byte of newResBuffer[] 
     nR++;   // increment pointer 
     j++; 

     if(j > 4) 
     { 
     *nR = '\0';  // null terminate the string 
     newResFlag = 1; // set the flag that new value is ready to be set 
     j = 0;    // reset count variable 

     }//if(j>4) 

    }//if(U1STAbits.URXDA) 

    if(newResFlag)   // has flag been set? 
    { 
     sscanf(newResBuffer, "%d", &newRes); // convert string received to an int 
     MAXCNT = (newRes * 2) - 1; // set MAXCNT register to new value 
     nR = nRreset;    // reset pointer to start of newResBuffer[] 
     newResFlag = 0;    // reset flag 

    }//if(newResFlag) 
    }//while(1) 

return 0; 
}//main() 

診断LEDでテストしましたが、newResBuffer []が最初に送信した値にリセットされているようです。私は新しいMAXCNT値を無駄に設定した後、すべての0にアレイを再初期化しようとしました。

+0

わからない 'のsscanf(newResBuffer、 "%dの"、およびnewresコマンド);:

は、ここで同じことを達成し、コードの簡単なバージョンです'あなたがしたいことをしていて、あなたは無限のwhileループを持っています – sjsam

+0

無限ループは私が撮影したものです。sscanf()については、文字列(newResBuffer = {'1'、 '2'、 '3'、 '4'、 '5'、 '\ 0'})を変換して変換したいそれをintに変換します(例:12345)。これは間違っているのでしょうか? – cjswish

+1

変数の宣言を表示します。現在、 'nR-4'の代わりに' newResBuffer'から 'sscanf'しています。 – gudok

答えて

1

ポインタをリセットする方法は正しいですが、それを達成するための簡単な方法があります。私はあなたのエラーが何らかの形でMAXCNTレジスタを設定するか、または受信レジスタから新しいデータを読み出すことに関係していると仮定します。お手伝いするラズベリーパイマイクロコントローラについては十分に分かりませんが、新しい値に更新する前にMAXCNTレジスタをフラッシュまたはリフレッシュする必要がありますか?

私はあなたのコードをテストしました。ラズベリーパイ固有レジスタの使用法をstdinから読み取ってstdoutに読むための標準的なC関数に置き換えました。テストするのは簡単ですし、個々のchar桁を受け取って文字列バッファに格納し、そのバッファをintに変換してバッファを再利用するというコードの部分がすべて正しいことを確認してください。ここに私のコードは、値が正しく読み込まれていることを示すとバッファアドレスがインクリメントされていることを確認し、正しくリセットするためにいくつかの追加情報を示しています:

#include <string.h> 
#include <stdlib.h> 
#include <stdio.h> 

char newResBuffer[10]; 
char *nR = newResBuffer; 
char *nRreset = NULL; 
char rxRead = 0; 
int newRes = 0; 
int newResFlag = 0; 
int j = 0; 

int main(void) 
{ 
    nRreset = nR; 

    /* Printing out initial memory addresses */ 
    printf("newResBuffer address: %p\n", (void *) newResBuffer); 
    printf("Initial nRreset address: %p\n", (void *) nRreset); 
    printf("Initial nR address: %p\n\n", (void *) nR); 

    while(1) 
    { 
     /* Using rand() % 2 to simulate data availability */ 
     if(rand() % 2) 
     { 
      /* Using getc() instead of the register to read individual digits */ 
      rxRead = getc(stdin); 
      printf("rxRead: %c saved to nR address %p\n", rxRead, (void *) nR); 
      *nR = rxRead; 
      nR++; 
      j++; 

      if(j > 4) 
      { 
       *nR = '\0'; 
       newResFlag = 1; 
       j = 0; 
      } 
     } 

     if(newResFlag) 
     { 
      sscanf(newResBuffer, "%d", &newRes); 
      /* Printing newRes and MAXCNT instead of setting the register */ 
      printf("newRes: %d\n", newRes); 
      printf("MAXCNT: %d\n", (newRes * 2) - 1); 
      printf("nR address before reset: %p\n", (void *) nR); 
      nR = nRreset; 
      printf("nR address after reset: %p\n\n", (void *) nR); 
      newResFlag = 0; 
     } 
    } 

    return 0; 
} 

出力を入力して試験したとき、「」です。

newResBufferアドレス:0x10779f060
初期nRresetアドレス:0x10779f060
初期のNRアドレス:0x10779f060

rxRead:Nr個のアドレスに保存された7 0x10779f060
rxRead:Nr個のアドレスに保存された5 0x10779f061
rxRead:4のNRアドレスに保存0x10779f063
rxRead:8に保存9のNRアドレス0x10779f062
rxReadに保存nRのアドレス0x10779f064
newresコマンド:
MAXCNT:151895
nRのアドレスリセット前:0x10779f065
リセット後 のNRアドレス:0x10779f060

rxRead:1 0x10779f060
rxRead Nr個のアドレスに保存:9のNRアドレスに保存0x10779f061
rxRead:4のNRアドレスに保存0x10779f062
rxRead:3に保存nRのアドレス0x10779f063
rxRead:2 NRアドレスに保存されて0x10779f064
newresコマンド:
MAXCNT:38863リセット前の10 のNRアドレス:リセット後0x10779f065
nRのアドレス:0x10779f060

私はあなたがポインタをリセットするためのいくつかの簡単な方法があることを先に述べました。 nRresetを使わずに実際に行うことができます。 newResBufferのベースアドレスは決して変更されないので、単にnR = newResBufferでリセットすることができます。

さらに簡単に行うには、移動するポインタをまったく使用しないでください。コードnewResBufferに既に登録されている変数jを使用します。

またint(またはlong)に文字列バッファを変換する代わりにsscanf()atoi()またはstrtol()を使用することができます。

#include <string.h> 
#include <stdlib.h> 
#include <stdio.h> 

int main(void) { 
    char newResBuffer[10]; 
    char rxRead = 0; 
    int newRes = 0; 
    int newResFlag = 0; 
    int j = 0; 

    while (1) { 
     /* if (U1STAbits.URXDA) { */ 
     if (rand() % 2) { 
      /* rxRead = U1RXREG & 0xFF; */ 
      rxRead = getc(stdin); 
      newResBuffer[j++] = rxRead; 

      if (j > 4) { 
       newResBuffer[j] = '\0'; 
       newResFlag = 1; 
       j = 0; 
      } 
     } 

     if (newResFlag) { 
      newRes = atoi(newResBuffer); 
      /* MAXCNT = (newRes * 2) - 1; */ 
      printf("newRes: %d\n", newRes); 
      printf("MAXCNT: %d\n", (newRes * 2) - 1); 
      newResFlag = 0; 
     } 
    } 

    return 0; 
} 
+0

お返事ありがとうございました。私はポインターを全く使わずに、ちょうどカウンター変数jで配列の場所を参照しました。私の元のコードが正常に動作したように見える(マイクロコントローラのコード内に別のエラーが見つかった、受信バッファが1byteのデータを取得していて、オーバーフローエラーフラグをクリアしていない)が、今更新されたコードがはるかにスムーズだと感じる。ありがとう!! – cjswish