c - C - 循环,输入未正确读取,仅打印出“不匹配”
问题描述
我目前正在编写一个读取 GPS 输入并将输入写入数组的程序。inChar2 是 UART2 的 getchar。它循环遍历字符串,直到找到字符 $GPPGA 行,然后将经度和纬度写入它们各自的数组。然后我想比较 longitude & check_longitude 和 latitude & check_latitude ,如果匹配则打印出一件事,如果不匹配则打印出另一件事。但是,我的代码没有比较字符串,只打印出“不匹配”。我哪里错了?我还编写了一个名为 accum 的函数,它接收所有 GPS 输入并将其存储在一个巨大的字符串中。我认为它没有正确编写,并且我没有在 ISR 功能中使用它。这个程序是在 MPLAB X IDE 中编写的。
//accumulate variables
void accum(char c)
{
static char array[1000];
static char *end = array;
*end++ = c;
if (c == "\n")
{
*end++ = 0;
end = array;
}
}
void _ISR _U2RXInterrupt()
{
//setting up the variables used
unsigned char incomer_data = 0;
unsigned char longitude[13] = {};
unsigned char latitude[13] = {};
unsigned char array_count = 0;
unsigned char temp;
int is_in = 0;
//$GPGGA,224355.00,3326.51776,N,08849.74254,W,2,09,1.02,104.9,M,-29.5,M,,0000*64
unsigned char check_long[13] =
{ //"3327.12050,N", //sidewalk
"3326.51776",
};
unsigned char check_lat[13] =
{
//"08847.25265W",
"08849.74254",
};
accum(temp);
// printf("%c", temp);
//char c = inChar2();
//outChar(c);
while (1)
{
incomer_data = inChar2(); //get character, checking string $GPGGA
//outChar(incomer_data);
//step by step find the GPGGA line
if (incomer_data == '$')
{
//first statement of GPS data starts with $
incomer_data = inChar2(); //if the first IF becomes true then next phase
// outChar(incomer_data);
if (incomer_data == 'G')
{
incomer_data = inChar2();
//outChar(incomer_data);
if (incomer_data == 'P')
{
incomer_data = inChar2();
//outChar(incomer_data);
if (incomer_data == 'G')
{
incomer_data = inChar2();
//outChar(incomer_data);
if (incomer_data == 'G')
{
incomer_data = inChar2();
//outChar(incomer_data);
if (incomer_data == 'A')
{
incomer_data = inChar2();
//outChar(incomer_data);
if (incomer_data == ',')
{
// first ',' received
incomer_data = inChar2(); //at this stage Final check in done. GPGGA is found
//outChar(incomer_data);
while (incomer_data != ',')
{ //skipping GMT time
incomer_data = inChar2();
//outChar(incomer_data);
}
incomer_data = inChar2();
latitude[0] = incomer_data;
//outChar(incomer_data);
// printf("working\n");
while (incomer_data != ',')
{
//printf("hi\n");
for(array_count = 1; incomer_data != 'N'; array_count++)
{
incomer_data = inChar2();
latitude[array_count] = incomer_data; //Store Latitude data
outChar(incomer_data);
//printf("latitude data");
}
//printf("hi");
incomer_data = inChar2();
if (incomer_data == ',')
{
for(array_count = 0; (incomer_data != 'E'); array_count++)
{
incomer_data = inChar2();
longitude[array_count] = incomer_data; //store Longitude data
outChar(incomer_data);
//printf("longitude data");
}
}
int i = 0;
for (i = 0; i < 13; ++i)
{
if ((strcmp(check_long, longitude) == 0) & (strcmp(check_lat, latitude) == 0)) {
printf("hot, sidewalk, bright, sunny, weird\n");
is_in = 1;
}
}
if (is_in == 0)
{
printf("no match");
}
array_count = 0;
while (array_count < 12) { //array of latitude data is 11 digit
//print data
array_count++;
}
array_count = 0;
while (array_count < 13) { //array of longitude data is 12 digit
//print data
array_count++;
}
outChar(incomer_data); //prints out E
}
}
}
}
}
}
}
for(array_count = 0; array_count <= 13; array_count++)
{
incomer_data = 0;
latitude[array_count] = 0;
longitude[array_count] = 0;
}
array_count = 0;
}
}
//DELAY_MS(3000);
}
解决方案
以下是查看您发布的代码后的一些注意事项:
添加您要比较的字符串到您的“不匹配” printf,以防您得到一些不是完全匹配的合理内容(即“3326.51758”!=“3326.51756”,尽管由于抖动它仍然看起来很合理)。
您的 unsigned char temp 未经初始化就被传递给 accum,因此它的堆栈垃圾和 accum 函数可能无法按预期工作。
您的 is_in 标志可以设为 unsigned char 以节省 1-3 个字节,这没什么大不了的,但是每个字节都很重要。
check_long/check_lat 应该是 const 全局变量,这样你就不会在每次调用时在 ISR 堆栈上重新分配它们,更重要的是因为它们是“只读的”,即 const。
如果您确定“$”符号表示新 GPS 输入的开始,您可以/应该使用“$”进入读取 GPPDA 标签其余部分的状态机,类似于嵌套的 ifs,但可能会切换失败更具可读性(如果您讨厌失败,即使它们被评论,也可以循环切换)
我假设 inChar2 只是从寄存器中读取,因为这看起来像是一个 PIC,它可能类似于 U2RXREG。我会避免添加这么多 inChar2 调用,而直接从寄存器中读取。
您不需要在底部进行 for 循环将所有这些变量设置为 0,它们应该只是从堆栈中弹出并在下次通过此 ISR 获得串行/UART 流量时重新初始化为零。
归根结底,您真的不想将双精度值存储为字符串(您希望它们作为双精度值!)如果您想测试您的输入,将经纬度值存储为双精度值,然后对您的测试值进行 inside_epsilon 比较和输入。这可能对你有帮助,GL Converting char* to float or double
推荐阅读
- java - 尽管在 gradle 文件中实现了 CardView 类,但“找不到”
- postgresql - 无法通过 Flask SQLAlchemy 插入新记录
- go - 限制持续时间粒度
- ruby-on-rails - 如何在 RSpec 请求规范中模拟 ActiveStorage 上传
- python - 如何让 pyopengl 在我的 IDE 中工作?
- python - 如何直接从 XBee iolines 获取数据
- javascript - 石头剪刀布游戏 - userChoice 未定义,但它已定义...我想?
- c# - 如何修复健康栏
- opencv - 如何将opencv Mat矩阵保存到可以在Matlab中加载的文件中
- javascript - 仅使用 javascript 的 CORS