2016-08-01 140 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中 –