【问题标题】:Global variables in C on STM32STM32上C语言中的全局变量
【发布时间】:2016-08-01 11:27:58
【问题描述】:

我正在做一个项目,我需要在使用“extern”的主函数中使用在某个文件(比如 mylib.c)中声明的一个变量。所有标题都包含在警戒词中,以避免多次包含。 该变量是一个结构(在 mylib.h 中定义),其成员只有浮点数和整数。它在 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。 有人可以解释吗?这可能是编译器错误吗? 谢谢。

【问题讨论】:

  • 根据您提供的数据的匮乏,我的水晶球猜测您的代码存在问题,因为这是编译器错误的可能性非常小。要获得真正的答案,请发布MCVE

标签: c compiler-errors global-variables extern stm32


【解决方案1】:

这是编译器问题的可能性非常小。更有可能是您的变量被代码的某些部分修改。尽量避免使用全局变量,因为它们的作用域最大。

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

您可以使用调试器功能 datawatch 在某些地址的数据发生更改时中断,以帮助您跟踪此问题。

【讨论】:

  • 感谢您的回答。稍后我将添加一些代码,以便您查看发生了什么。但我仔细检查了一切。而且变量名是唯一的。
  • @John Wick 该变量应声明为“extern VarType varName;”在标题中。但从描述中,您可能遇到了一些数组索引或指针问题。移动变量可能会通过将其移动到您不看的地方来掩盖问题。这是灾难的根源,或者至少是几个小时的挫折。
【解决方案2】:

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

在 mylib.c 中:

int myGlobalVariable;

在 main.c 中

extern int myGlobalVariable;

int main(void)
{
    myGlobalVariable = 5;
}

如果仍有问题,请尝试增加堆栈大小。如果堆栈不够大,可能会被其他数据覆盖。

如果您在任何代码中使用 memset 或 memcpy,请确保长度参数正确。 memset 和 memcpy 非常危险,您可以轻松地在内存的某些部分写入您并不真正想要的内容。

【讨论】:

  • 感谢您的意见。当我按照您指示的方式声明变量时,问题就发生了。什么解决了(有点?)它是,把“int myGlobalVariable;”在 main.c 和“extern int myGlobalVariable;”中在 mylib.c 中
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多