2016-04-25 71 views
3

我從Rasp發送5個字節的數據。 Pi並使用UART通過dsPIC30F微控制器接收它們。我可以正確接收數據並將MAXCNT寄存器設置爲所需的值。當我嘗試發送第二個值時出現問題。 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

無限while循環就是我正在拍攝的東西。至於sscanf(),我希望能夠得到字符串(例如newResBuffer = {'1','2','3','4','5','\ 0'})並轉換它變成一個int(例如12345)。這是做錯的方式嗎? – cjswish

+1

顯示變量的聲明。目前你從'newResBuffer'而不是'nR-4'運行'sscanf'。 – gudok

回答

1

重置指針的方法是正確的,雖然有一些更簡單的方法來實現它。我假設你的錯誤必須與設置MAXCNT寄存器或從接收寄存器讀取新數據有關。我不太瞭解Raspberry Pi微控制器在這方面的幫助,但可能需要刷新或刷新MAXCNT寄存器,然後將其更新爲新值?

我測試了您的代碼,將標準C函數替換爲Raspberry Pi特定寄存器用法,以便從標準輸入讀取並打印到stdout。很容易測試並看到涉及接收單個字符數字,將其存儲在字符串緩衝區,將該緩衝區轉換爲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:7保存到NR地址0x10779f060
rxRead:5保存到NR地址0x10779f061
rxRead:9保存到NR地址0x10779f062
rxRead:4保存到NR地址0x10779f063
rxRead:8保存到NR地址0x10779f064
newRes:
MAXCNT:151895
NR地址復位前:0x10779f065
NR地址復位後:0x10779f060

rxRead:1保存到NR地址0x10779f060
rxRead:9保存到NR地址0x10779f061
rxRead:4保存到NR地址0x10779f062
rxRead:3保存到NR地址0x10779f063
rxRead:2保存到NR地址0x10779f064
newRes:
MAXCNT:38863
個 NR地址復位前:復位後0x10779f065
NR地址:0x10779f060

我前面,有你重置指針一些更簡單的方法提及。你可以在不使用nRreset的情況下做到這一點;由於newResBuffer的基地址永不改變,因此您可以簡單地將其重置爲nR = newResBuffer

更簡單的方法就是不使用移動指針,只需使用代碼中已有的變量j來索引newResBuffer

您還可以使用的sscanf()atoi()strtol()而不是字符串緩衝區轉換爲int(或long)。

下面是其實現同樣的事情的代碼的簡化版本:

#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