2016-04-25 3 views
3

Я отправляю 5 байтов данных из Rasp. Pi и получать их через микроконтроллер dsPIC30F с использованием UART. Я могу получить данные правильно и установить регистр 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() 

Я сделал некоторые испытания с диагностическими светодиодами, и это выглядит как newResBuffer [] продолжает быть сброшен на первое значение я отправить его. Я даже попытался повторно инициализировать массив для всех 0 после установки нового значения MAXCNT безрезультатно.

+0

Не уверен, что 'sscanf (newResBuffer, "% d", & newRes); 'делает то, что вы хотите, чтобы он делал, и у вас есть бесконечный цикл while. – sjsam

+0

Бесконечный цикл while - это то, что я снимал.Что касается sscanf(), я надеялся взять строку символов (например, newResBuffer = {'1', '2', '3', '4', '5', '\ 0'}) и конвертировать это в int (например, 12345). Это неправильный способ сделать это? – cjswish

+1

Показать объявления переменных. В настоящее время вы 'sscanf'ing от' newResBuffer' вместо 'nR-4'. – gudok

ответ

1

Ваш метод сброса указателя правильный, хотя есть несколько более простых способов его достижения. Я предполагаю, что ваша ошибка должна быть каким-то образом связана с установкой регистра MAXCNT или чтением новых данных из регистра приема. Я не знаю достаточно о микроконтроллере Raspberry Pi, чтобы помочь вам там, но, возможно, вам нужно сбросить или обновить регистр MAXCNT, прежде чем обновлять его до нового значения?

Я проверил ваш код, заменив использование конкретного реестра Raspberry Pi стандартными функциями C для чтения с stdin и печати до 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
Initial nRreset адрес: 0x10779f060
Начальный адрес пк: 0x10779f060

rxRead: 7 сохраняется на Н.Р. адрес 0x10779f060
rxRead: 5 сохранены в Н.Р. адрес 0x10779f061
rxRead: 9 сохранены в Н.Р. адресу 0x10779f062
rxRead: 4 сохранено в Н.Р. адресу 0x10779f063
rxRead: 8 сохраняется в Н.Р. адрес 0x10779f064
newRes:
MAXCNT: 151 895
адрес до пк сброса: 0x10779f065
пк адрес после сброса: 0x10779f060

rxRead: 1 сохраняется в Н.Р. адрес 0x10779f060
rxRead: 9 сохранено в Н.Р. адрес 0x10779f061
rxRead: 4 сохранено в Н.Р. адрес 0x10779f062
rxRead: 3 сохраняются в адрес 0x10779f063 пк
rxRead: 2 сохраняется в Н.Р. адрес 0x10779f064
newRes:
MAXCNT: 38863
пк адреса перед сбросом: 0x10779f065
адрес пк после сброса: 0x10779f060

Я уже упоминал, что есть несколько простых способов для вас, чтобы сбросить указатель. Вы можете сделать это, не используя nRreset; поскольку базовый адрес для newResBuffer никогда не изменяется, вы можете просто сбросить его с помощью nR = newResBuffer.

Еще более простой способ сделать это - это не использовать движущийся указатель и просто использовать переменную j, которую вы уже имеете в своем коде для индекса newResBuffer.

Вы также можете использовать atoi() или strtol() вместо sscanf(), чтобы преобразовать строку буфера к 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. Похоже, что мой исходный код работал так, как должен (обнаружил еще одну ошибку в моем коде микроконтроллера, буфер приема получал слишком много данных на 1 байт, и я никогда не очищал флаг ошибки переполнения), но я чувствую, что мой обновленный код намного более плавный. Благодаря!! – cjswish

Смежные вопросы