我还在学习在微处理器中使用C。一开始我使用了很多全局变量。现在我正在尽可能地避免它,但对我来说,并不总是清楚如何做到这一点。
例如电池监控器,在这种情况下,有4个功能需要读取或修改变量。我有这些功能都使用可变低电压。
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()需要写入LowVoltage
- MenuVoltage()需要读取和写入LowVoltage
在不使LowVoltage全球化的情况下,我如何才能做到这一点??我需要制作另一个函数来读取或写入LowVoltage吗?类似这样的东西:
unsigned int Low_Voltage(short Get, unsigned int Value){
static unsigned int LowVoltage;
if(Get) return LowVoltage;
else LowVoltage= Value;
}
或者有更好的方法吗?我想一定有:)我最近一直在读关于结构的书,但说实话,我还不完全理解它们,我甚至不确定在这种情况下它会对我有帮助吗?
在函数之间共享变量有几种选择:
- 在静态内存中分配变量-这几乎就是您的代码所做的。你有两种选择:函数静态、翻译单元静态和全局
- 将指向变量的指针作为函数参数-此选项需要以某种形式传递指针
- 使用具有智能初始化功能的线程本地存储-当您使用微控制器时,此选项通常不可用;为了完整起见,我在这里列出了它
在您的情况下,我认为使用翻译单位静态变量是合适的。将四个函数的实现放入一个C文件中,并在顶部声明LowVoltage
为静态变量:
static unsigned int LowVoltage;
这种简单但高效的封装机制为您提供了全局变量的所有好处,而没有全局变量的缺点:
- C模块中的所有函数都可以"看到"这个变量,并可以自由操作它
- C模块之外的任何其他函数都不能访问此变量。他们可以声明自己的
LowVoltage
变量,赋予它完全不同的含义
我能想到的两种解决方案
-
制作类似的函数签名
unsigned int Load_LowVoltage(unsigned int lowVoltage);
然后传递
LowVoltage
并为其分配返回值,就像这个一样LowVoltage = Load_LowVoltage(LowVoltage);
-
在函数中修改
LowVoltage
,并像一样将指针传递到原始LowVoltage
void LowVoltage(unsigned int *lowVoltage) { *lowVoltage = modifiedValue; }
那么你可以像这个一样使用它
Load_LowVoltage(&LowVoltage);
我认为第二种解决方案更清洁,因为你所处的环境资源有限,所以从这个意义上来说也更好。但它们都很容易实现,而且效果也很好。
您可以创建一个包含所有电池参数的结构,例如:
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);