I am sending 5 bytes of data from a Rasp. Pi and receiving them via a dsPIC30F microcontroller using UART. I can receive the data correctly and set the MAXCNT register to the value desired. The problem arises when I try to send a second value. The value in newResBuffer[] will not change after the first data read.
I am a beginner when it comes to pointers/arrays, but I suspect that my issue may lie with my method of resetting my pointer. I have tried many different ways of this with no success. Am I performing this step correctly?
#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()
I did some testing with diagnostic LEDs and it looks like newResBuffer[ ] keeps being reset to the first value I send it. I have even tried re-initializing the array to all 0's after setting the new MAXCNT value to no avail.
Your method of resetting the pointer is correct, although there are some easier ways to achieve it. I assume that your error must be somehow related setting the MAXCNT register or reading new data from the receive register. I don't know enough about the Raspberry Pi microcontroller to help you there, but perhaps you need to flush or refresh the MAXCNT register before updating it to a new value?
I tested your code by replacing the Raspberry Pi specific register usage with standard C functions for reading from stdin and printing to stdout. It's easy to test and see that the part of the code that involves receiving an individual char digit, storing it in a string buffer, converting that buffer to an int, and reusing the buffer, are all correct. Here's my code showing that the values are read in correctly and showing some additional information to confirm that the buffer address is incremented and reset correctly:
#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;
}
The output when tested with the input "7594819432" is:
newResBuffer address: 0x10779f060
Initial nRreset address: 0x10779f060
Initial nR address: 0x10779f060rxRead: 7 saved to nR address 0x10779f060
rxRead: 5 saved to nR address 0x10779f061
rxRead: 9 saved to nR address 0x10779f062
rxRead: 4 saved to nR address 0x10779f063
rxRead: 8 saved to nR address 0x10779f064
newRes: 75948
MAXCNT: 151895
nR address before reset: 0x10779f065
nR address after reset: 0x10779f060rxRead: 1 saved to nR address 0x10779f060
rxRead: 9 saved to nR address 0x10779f061
rxRead: 4 saved to nR address 0x10779f062
rxRead: 3 saved to nR address 0x10779f063
rxRead: 2 saved to nR address 0x10779f064
newRes: 19432
MAXCNT: 38863
nR address before reset: 0x10779f065
nR address after reset: 0x10779f060
I mentioned earlier that there are some easier ways for you to reset the pointer. You can actually do it without using nRreset; since the base address for newResBuffer never changes, you can simply reset it with nR = newResBuffer.
An even easier way to do it would be not to use a moving pointer at all and simply use the variable j you already have in your code to index newResBuffer.
You can also use atoi() or strtol() instead of sscanf() to convert the string buffer to an int (or long).
Here's a simpler version of the code which achieves the same thing:
#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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With