2016-08-01 136 views
1

我正在开发一个项目,我需要使用'extern'在主函数中使用某个文件(比如说mylib.c)声明的一个变量。所有标题都包含在警戒词中以避免多重包含。 该变量是一个结构(在mylib.h中定义),其成员只是浮点数和整数。它在主函数的开始处被初始化。STM32上C语言的全局变量

进入main循环并做一些工作后,一些不关心的成员会得到随机值。

因此,我从main中的声明中移除了extern,而是将它放在mylib.c中的声明中。它的工作。

Sim808.h

#ifndef _SIM808_H 
#define _SIM808_H 
typedef struct{ 
uint8_t GPRS_Active; 

float gsm_latitude; 
float gsm_longitude; 
}SIM808; 
void sendCmd(const char cmd[]); 
void sim808_init(void); 
void parse_gsm_location(uint8_t* line); 
#endif 

Sim808.c

#include "sim808.h" 
SIM808 sim808; 
void parse_gsm_location(uint8_t* line) 
{ 
uint8_t commas=0,index=0; 
uint16_t err; 
if((err=atoi((const char*)line+12))!=0) 
{ 
    printf("No coordinates received\n"); 
    if(err==404 || err==601) 
     sim808.GPRS_Active=0; 

    return; 
} 
while (line[index]!= '\0' && index <50) 
    { 
    if(line[index]==',') 
    { 
     commas++; 
     switch (commas) 
     { 
      case 1: 
       sim808.gsm_longitude=atof((const char*)(line+index+1)); 
       printf("Long:%f\n",sim808.gsm_longitude); 
      break; 
      case 2: 
       sim808.gsm_latitude=atof((const char*)(line +index+1)); 
       printf("Longitude%f  Latitude%f\n",sim808.gsm_longitude,sim808.gsm_latitude); 
      break; 
      case 3: 
       sscanf((const char*)(line+index+1),"%4d/%2d/%2d", (int*)&sim808.gsmDate.year,(int*)&sim808.gsmDate.month, 
        (int*)&sim808.gsmDate.day); 
      break; 
      case 4: 
       sscanf((const char*)(line+index+1),"%2d/%2d/%2d", 
        (int*)&sim808.gsmTime.hours,(int*)&sim808.gsmTime.minutes,(int*)&sim808.gsmTime.seconds); 
      break; 
     } 
    } 
     index++; 
    } 
} 

的main.c

#include "sim808.h" 
extern SIM808 sim808; 

int main(void) 
{ 
    uint8_t response[150]; 
//init functions 
while(1) 
{ 
    if(sim808.GPRS_Active==1) 
    { 
     sendCmd("AT+CIPGSMLOC=1,1\r\n"); 
     HAL_UART_Receive(&huart4,response,2,60000);//max response time is 1 min 
     HAL_UART_Receive(&huart4,response,150,1000);//we dont need first 2 chars 
     parse_gsm_location(response); 
     memset((void*)response,0,150); 
    } 
    else 
     sim808_init(); 
    } 
} 

正如你所看到的,该成员GPRS_Active只能接受1或0我码。 使用printf,它在第一次迭代后变成了242。 有人可以解释吗?这可能是一个编译器错误? 谢谢。

+3

由于您提供的数据很少,我的水晶球猜测您在代码中存在问题,因为这是一个编译器错误的可能性非常小。要获得真实答案,请发布[MCVE](http://stackoverflow.com/help/mcve) –

+0

发布您的代码。 – rost0031

回答

2

它是一个编译器问题的可能性非常小。更可能的是你的变量被你的代码的一部分修改了。尽量避免使用全局变量,因为它们的范围最大。

你用同名的某个地方变量吗?
您是否检查过地图文件或在调试器中放置它的位置?

如果某些地址的数据发生变化,以帮助您跟踪此问题,则可以使用调试器功能datawatch。

+0

感谢您的回答。稍后我会添加一些代码,以便您可以看到发生了什么。但我加倍检查了一切。而变量名称是唯一的。 –

+0

@John Wick该变量应声明为“extern VarType varName;”在标题中。但从描述来看,您可能会遇到一些数组索引或指针问题。移动变量可能会将问题移动到一个你不想看的地方。这是一场灾难,或至少几个小时的挫折。 – Flip

0

当我使用全局变量时,我不会在.h文件中声明它们以避免多重包含的问题。你当然可以找到一些技巧来在.h中声明它们,但是我认为它使事情变得如此复杂。所以,试试这个:

在mylib.c:

int myGlobalVariable; 

main.c中

extern int myGlobalVariable; 

int main(void) 
{ 
    myGlobalVariable = 5; 
} 

如果您仍然有问题,尽量增加你的堆栈的大小。如果堆栈不够大,可能会被其他数据覆盖。

如果您在任何代码中使用memset或memcpy,请确保长度参数是正确的。 memset和memcpy是相当危险的,你可以很容易地写入你不想要的内存的某些部分。

+0

感谢您的输入。当我按照你指示的方式宣布变量时,问题就发生了。什么解决了(种类?),把“int myGlobalVariable;”在main.c和“extern int myGlobalVariable;”在mylib.c中 –