如何在C ++宏中格式化“if”语句(以及如何使用Arduino的新EEPROM库获取& put函数)

时间:2016-01-02 20:18:19

标签: c++ if-statement arduino macros

更新:我现在也回答了我自己的问题。

我需要帮助格式化这个C ++宏中的“if”语句:

#define updateEEPROMVal(address,val)  if (EEPROM.get(address)!=val) \
                                        EEPROM.put(address,val)

我收到错误页面,所以我认为这是一个简单的格式化问题。

以下是完整的背景信息:

//----------------------------------------------------------------------------------------------------------------------------------
//storeXYValsIntoEEPROM
//-store the current global variable x and y low, center, and high values into EEPROM
//----------------------------------------------------------------------------------------------------------------------------------
#define updateEEPROMVal(address,val)  if (EEPROM.get(address)!=val) \
                                        EEPROM.put(address,val)
void storeXYValsIntoEEPROM()
{
  //update EEPROM values *only* if necessary, this way you minimize writes (and wear-and-tear) on the EEPROM, since it is limited to
  //100k writes per cell I believe (see datasheet)
  updateEEPROMVal(0,x_low);
  updateEEPROMVal(2,x_ctr);
  updateEEPROMVal(4,x_high);
  updateEEPROMVal(6,y_low);
  updateEEPROMVal(8,y_ctr);
  updateEEPROMVal(10,y_high);
}

更新:这是我的错误输出:

Arduino: 1.6.5 (Windows 8.1), Board: "Arduino Uno"  

Using library IRremote in folder: C:\Gabe\Gabe - RC-extra\Arduino\Sketches\libraries\IRremote (legacy)  

Using library eRCaGuy_ButtonReader in folder: C:\Gabe\Gabe - RC-extra\Arduino\Sketches\libraries\eRCaGuy_ButtonReader (legacy)  

Using library EEPROM in folder: C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\EEPROM   



C:\Program Files (x86)\Arduino\hardware\tools\avr/bin/avr-g++ -c -g -Os -Wall -Wextra -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -MMD -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10605 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR -IC:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino -IC:\Program Files (x86)\Arduino\hardware\arduino\avr\variants\standard -IC:\Gabe\Gabe - RC-extra\Arduino\Sketches\libraries\IRremote -IC:\Gabe\Gabe - RC-extra\Arduino\Sketches\libraries\eRCaGuy_ButtonReader -IC:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\EEPROM C:\Users\Gabriel\AppData\Local\Temp\build6111239347405487460.tmp\IR_Tx_code5_w_calibration_mode.cpp -o   C:\Users\Gabriel\AppData\Local\Temp\build6111239347405487460.tmp\IR_Tx_code5_w_calibration_mode.cpp.o   

In file included from IR_Tx_code5_w_calibration_mode.ino:27:0:
C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\EEPROM/EEPROM.h:43:30: warning: type qualifiers ignored on function return type [-Wignored-qualifiers]
     operator const uint8_t() const       { return **this; }  
                              ^
C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\EEPROM/EEPROM.h:92:26: warning: type qualifiers ignored on function return type [-Wignored-qualifiers]
     operator const int() const          { return index; }  
                          ^
IR_Tx_code5_w_calibration_mode.ino: In function 'void storeXYValsIntoEEPROM()':
IR_Tx_code5_w_calibration_mode.ino:430:61: error: no matching function for call to 'EEPROMClass::get(int)'
IR_Tx_code5_w_calibration_mode.ino:436:3: note: in expansion of macro 'updateEEPROMVal'
IR_Tx_code5_w_calibration_mode.ino:430:61: note: candidate is:
IR_Tx_code5_w_calibration_mode.ino:436:3: note: in expansion of macro 'updateEEPROMVal'
In file included from IR_Tx_code5_w_calibration_mode.ino:27:0:
C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\EEPROM/EEPROM.h:130:31: note: template<class T> T& EEPROMClass::get(int, T&)
     template< typename T > T &get( int idx, T &t ){  
                               ^
C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\EEPROM/EEPROM.h:130:31: note:   template argument deduction/substitution failed:
IR_Tx_code5_w_calibration_mode.ino:430:61: note:   candidate expects 2 arguments, 1 provided
IR_Tx_code5_w_calibration_mode.ino:436:3: note: in expansion of macro 'updateEEPROMVal'
IR_Tx_code5_w_calibration_mode.ino:430:61: error: no matching function for call to 'EEPROMClass::get(int)'
IR_Tx_code5_w_calibration_mode.ino:437:3: note: in expansion of macro 'updateEEPROMVal'
IR_Tx_code5_w_calibration_mode.ino:430:61: note: candidate is:
IR_Tx_code5_w_calibration_mode.ino:437:3: note: in expansion of macro 'updateEEPROMVal'
In file included from IR_Tx_code5_w_calibration_mode.ino:27:0:
C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\EEPROM/EEPROM.h:130:31: note: template<class T> T& EEPROMClass::get(int, T&)
     template< typename T > T &get( int idx, T &t ){  
                               ^
C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\EEPROM/EEPROM.h:130:31: note:   template argument deduction/substitution failed:
IR_Tx_code5_w_calibration_mode.ino:430:61: note:   candidate expects 2 arguments, 1 provided
IR_Tx_code5_w_calibration_mode.ino:437:3: note: in expansion of macro 'updateEEPROMVal'
IR_Tx_code5_w_calibration_mode.ino:430:61: error: no matching function for call to 'EEPROMClass::get(int)'
IR_Tx_code5_w_calibration_mode.ino:438:3: note: in expansion of macro 'updateEEPROMVal'
IR_Tx_code5_w_calibration_mode.ino:430:61: note: candidate is:
IR_Tx_code5_w_calibration_mode.ino:438:3: note: in expansion of macro 'updateEEPROMVal'
In file included from IR_Tx_code5_w_calibration_mode.ino:27:0:
C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\EEPROM/EEPROM.h:130:31: note: template<class T> T& EEPROMClass::get(int, T&)
     template< typename T > T &get( int idx, T &t ){  
                               ^
C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\EEPROM/EEPROM.h:130:31: note:   template argument deduction/substitution failed:
IR_Tx_code5_w_calibration_mode.ino:430:61: note:   candidate expects 2 arguments, 1 provided
IR_Tx_code5_w_calibration_mode.ino:438:3: note: in expansion of macro 'updateEEPROMVal'
IR_Tx_code5_w_calibration_mode.ino:430:61: error: no matching function for call to 'EEPROMClass::get(int)'
IR_Tx_code5_w_calibration_mode.ino:439:3: note: in expansion of macro 'updateEEPROMVal'
IR_Tx_code5_w_calibration_mode.ino:430:61: note: candidate is:
IR_Tx_code5_w_calibration_mode.ino:439:3: note: in expansion of macro 'updateEEPROMVal'
In file included from IR_Tx_code5_w_calibration_mode.ino:27:0:
C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\EEPROM/EEPROM.h:130:31: note: template<class T> T& EEPROMClass::get(int, T&)
     template< typename T > T &get( int idx, T &t ){  
                               ^
C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\EEPROM/EEPROM.h:130:31: note:   template argument deduction/substitution failed:
IR_Tx_code5_w_calibration_mode.ino:430:61: note:   candidate expects 2 arguments, 1 provided
IR_Tx_code5_w_calibration_mode.ino:439:3: note: in expansion of macro 'updateEEPROMVal'
IR_Tx_code5_w_calibration_mode.ino:430:61: error: no matching function for call to 'EEPROMClass::get(int)'
IR_Tx_code5_w_calibration_mode.ino:440:3: note: in expansion of macro 'updateEEPROMVal'
IR_Tx_code5_w_calibration_mode.ino:430:61: note: candidate is:
IR_Tx_code5_w_calibration_mode.ino:440:3: note: in expansion of macro 'updateEEPROMVal'
In file included from IR_Tx_code5_w_calibration_mode.ino:27:0:
C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\EEPROM/EEPROM.h:130:31: note: template<class T> T& EEPROMClass::get(int, T&)
     template< typename T > T &get( int idx, T &t ){  
                               ^
C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\EEPROM/EEPROM.h:130:31: note:   template argument deduction/substitution failed:
IR_Tx_code5_w_calibration_mode.ino:430:61: note:   candidate expects 2 arguments, 1 provided
IR_Tx_code5_w_calibration_mode.ino:440:3: note: in expansion of macro 'updateEEPROMVal'
IR_Tx_code5_w_calibration_mode.ino:430:61: error: no matching function for call to 'EEPROMClass::get(int)'
IR_Tx_code5_w_calibration_mode.ino:441:3: note: in expansion of macro 'updateEEPROMVal'
IR_Tx_code5_w_calibration_mode.ino:430:61: note: candidate is:
IR_Tx_code5_w_calibration_mode.ino:441:3: note: in expansion of macro 'updateEEPROMVal'
In file included from IR_Tx_code5_w_calibration_mode.ino:27:0:
C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\EEPROM/EEPROM.h:130:31: note: template<class T> T& EEPROMClass::get(int, T&)
     template< typename T > T &get( int idx, T &t ){  
                               ^
C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\EEPROM/EEPROM.h:130:31: note:   template argument deduction/substitution failed:
IR_Tx_code5_w_calibration_mode.ino:430:61: note:   candidate expects 2 arguments, 1 provided
IR_Tx_code5_w_calibration_mode.ino:441:3: note: in expansion of macro 'updateEEPROMVal'  
Multiple libraries were found for "IRremote.h"  

 Used: C:\Gabe\Gabe - RC-extra\Arduino\Sketches\libraries\IRremote  

 Not used: C:\Program Files (x86)\Arduino\libraries\RobotIRremote  

no matching function for call to 'EEPROMClass::get(int)'  

3 个答案:

答案 0 :(得分:2)

代码do{ ... }while(0)您的宏(并且不要忘记分号):

 #define updateEEPROMVal(address,val)  do{if (EEPROM.get(address)!=val) \
                                    EEPROM.put(address,val);}while(0)

另见this

更好的是,将其设为static inline函数(放入某个头文件中)。

另外,使用g++ -C -E source.cc > source.ii获取预处理表单,您可以查看其中。

答案 1 :(得分:2)

没有必要这样做。当我写这个库时,我确保它最大限度地减少了磨损和磨损。撕裂。

EEPROM函数put()在字节级使用更新方法。 你只是复制功能。

如果您对EEPROM库有更多疑问,请在论坛上提问。

我为我的图书馆创建了一个帖子:https://forum.arduino.cc/index.php?topic=312645

答案 2 :(得分:0)

我的回答:

对不起,很抱歉,我发现我误用了EEPROM.get函数,问题根本就在于我的宏。 EEPROM库文档位于:https://github.com/arduino/Arduino/tree/master/hardware/arduino/avr/libraries/EEPROM

我错过了第二个论点。

以下是我提出的两项解决方案。

1)使用单独的功能:

- 我更喜欢这种方法。结果是&#34;内联&#34;在这种情况下是可选的,没有区别 - 这个方法使我的程序7610字节,472字节用于全局变量。它比下面的选项2少了162个字节。

void storeGlobalXYValsIntoEEPROM()
{
  updateEEPROMVal(0,x_low);
  updateEEPROMVal(2,x_ctr);
  updateEEPROMVal(4,x_high);
  updateEEPROMVal(6,y_low);
  updateEEPROMVal(8,y_ctr);
  updateEEPROMVal(10,y_high);
}

inline void updateEEPROMVal(uint16_t address, uint16_t val)
{
  uint16_t val_in_EEPROM;
  EEPROM.get(address,val_in_EEPROM);
  if (val_in_EEPROM!=val)
    EEPROM.put(address,val);
}

2)使用宏,如下:

- 我更喜欢上述方法 - 该方法占用程序空间7772个字节,全局变量占472个字节。它比上述方法多162个字节。

#define updateEEPROMVal(address,val)  EEPROM.get(address,val_in_EEPROM); \
                                      if (val_in_EEPROM!=val)            \
                                        EEPROM.put(address,val)
void storeGlobalXYValsIntoEEPROM()
{
  uint16_t val_in_EEPROM;

  updateEEPROMVal(0,x_low);
  updateEEPROMVal(2,x_ctr);
  updateEEPROMVal(4,x_high);
  updateEEPROMVal(6,y_low);
  updateEEPROMVal(8,y_ctr);
  updateEEPROMVal(10,y_high);
}

感谢大家的帮助!

更新回答:

然而,我还没有完全阅读文档。 EEPROM库放置函数文档(https://github.com/arduino/Arduino/tree/master/hardware/arduino/avr/libraries/EEPROM)表示,&#34;此函数使用update方法写入其数据,因此只重写已更改的单元格。&#34;因此,我的更新代码是多余的。我只需要使用&#34; put&#34;功能原样。此处也请参考EEPROM库的作者(Chris A)的答案。

所以,我已经学到了很多,这是我的最终答案:

摆脱我的支持函数宏,并按原样使用put函数。它已经最小化了EEPROM磨损,只有在内容不同时才会写入。不过,为了完整性,我会留下我的上述答案&#39;那些正在寻找宏观或功能解决方案的人的缘故。