在这种情况下如何避免全局变量(嵌入式C)

时间:2015-03-30 14:19:43

标签: c global-variables mikroc

我还在学习用于微处理器的C语言。一开始我使用了很多全局变量。现在我试图尽可能地避免它,但对我来说,看到如何做到这一点并不总是很清楚。

例如电池监视器,在这种情况下,有4个函数需要读取或修改变量。 我有这些功能都使用变量LowVoltage。

void Check_Voltage(){
  checks current voltage against LowVoltage
}

void Menu_Voltage(){
  a menu on the LCD screen to set the value of LowVoltage
}

void Save_LowVoltage(){
 runs after the settings menu is finished to save LowVoltage to EEPROM
}

void Load_LowVoltage(){
 reads EEPROM and sets LowVoltage at startup 
}
  • Check_Voltage()和Save_LowVoltage()需要读取LowVoltage。
  • Load_LowVoltage()需要写低电压。
  • Menu_Voltage()需要读写LowVoltage。

如何在不降低电压全局的情况下完成这项工作? 我是否需要另外执行读写低电压的功能? 像这样:

unsigned int Low_Voltage(short Get, unsigned int Value){
  static unsigned int LowVoltage;

  if(Get) return LowVoltage;
  else LowVoltage= Value;
}

或者有更好的方法吗?我猜必须有:) 我最近一直在阅读有关结构的内容,但说实话,我并不完全了解它们,我甚至不确定它会在这样的情况下对我有所帮助吗?

3 个答案:

答案 0 :(得分:9)

在函数之间共享变量有几种选择:

  • 在静态内存中分配变量 - 这几乎就是您的代码所做的事情。你有两个选择:function-static,translation unit-static和global
  • 将指针传递给变量作为函数参数 - 此选项需要以某种形式传递指针
  • 通过巧妙的初始化使用线程本地存储 - 使用微控制器时,通常不会选择此选项。我在此列出完整性。

在您的情况下,我认为使用翻译单位 - 静态变量是合适的。将四个函数的实现放在一个C文件中,并在顶部将LowVoltage声明为静态变量:

static unsigned int LowVoltage;

这种简单但有效的封装机制为您提供了拥有全局变量的所有好处,而没有全局变量的缺点:

  • C模块内的所有功能"参见"这个变量,可以自由地操纵它
  • C模块外部没有其他功能可以访问此变量。他们可以声明自己的LowVoltage变量,赋予它完全不同的含义。

答案 1 :(得分:0)

我能想到的两个解决方案

  1. 制作像这样的功能签名

    unsigned int Load_LowVoltage(unsigned int lowVoltage);
    

    然后传递LowVoltage并为其指定返回值,如此

    LowVoltage = Load_LowVoltage(LowVoltage);
    
  2. 修改函数内的LowVoltage并将指针传递给原始的LowVoltage

    void LowVoltage(unsigned int *lowVoltage)
     {
        *lowVoltage = modifiedValue;
     }
    

    那么你可以像这样使用它

    Load_LowVoltage(&LowVoltage);
    
  3. 我认为第二种解决方案更清洁,因为您处于资源有限的环境中,在这种意义上它也更好。但它们都很容易实现并且工作得很好。

答案 2 :(得分:0)

您可以创建一个包含所有电池参数的结构,例如:

typedef struct {
  int low_voltage; 
  int voltage;
  int capacity;
  int temperature;
  ...
} BatteryData

在程序开始时,为它分配内存并将成员初始化为一些起始值:

BatteryData *battery = malloc(sizeof(BatteryData));
battery->low_voltage = 0;
...

然后将指向整个结构的指针传递给设置或读取单个值的函数,例如:

void Load_LowVoltage(BatteryData *battery){
 //reads EEPROM and sets LowVoltage at startup 
 int eeprom_val = get_low_voltage_from_eeprom();
 battery->low_voltage = eeprom_val;
}

不需要时释放结构:

free(battery);