我从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 :(得分: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;
}
使用输入&#34; 7594819432 &#34;进行测试时的输出是:
newResBuffer地址: 0x10779f060
初始nRreset地址:0x10779f060
初始nR地址:0x10779f060rxRead:7保存到nR地址 0x10779f060
rxRead:5保存到nR地址0x10779f061
rxRead:9保存到nR地址0x10779f062
rxRead:4保存到nR地址0x10779f063
rxRead:8保存到nR地址0x10779f064
newRes: 75948
MAXCNT:151895
复位前的nR地址: 0x10779f065
复位后的nR地址: 0x10779f060rxRead:1保存到nR地址 0x10779f060
rxRead:9保存到nR地址0x10779f061
rxRead:4保存到nR地址0x10779f062
rxRead:3保存到nR地址0x10779f063
rxRead:2保存到nR地址0x10779f064
newRes: 19432
MAXCNT:38863
复位前的nR地址: 0x10779f065
复位后的nR地址: 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;
}