我正在开发一个嵌入式项目,我的所有端口和引脚都是这样定义的:
#define SENSOR_1 gpioPortA,15
有没有办法只提取整数而不创建新的#define?
到目前为止,我使用了typedef并从#define分配了引脚值,如下所示:
typedef struct
{
GPIO_Port_TypeDef port;
uint8_t pin;
}sensor_t;
sensor_t sensor1 = {SENSOR_1};
/* Now sensor1.pin is the pin value */
但是我想将引脚传递给一个switch case,我只能使用常量值,而我宁愿避免使用if
语句。
有没有办法将引脚传递给没有新#define的开关盒?
答案 0 :(得分:4)
简短的回答是否定的。
但是,您可以在需要时使用sensor1.pin
,但不能在case
switch
语句中使用if-else
,因为switch不支持变量。在这种情况下,请使用#define SENSOR_1_PIN 10
#define SENSOR_1 my_port,SENSOR_1_PIN
语句。
或者这样做:
SENSOR_1_PIN
然后在切换中使用case
部分中的switch (condition) {
case SENSOR_1_PIN:
//Do stuff
break;
//....
}
。
#define SENSOR_1_PORT GPIOB
#define SENSOR_1_PIN 15
//If structure order changes here, you may lead to wrong data interpretation
sensor_t sensor1 = {SENSOR_1_PORT, SENSOR_1_PIN};
再次提醒,因为它是在您的问题的第一条评论中发布的。这样做非常危险。
最恰当的方法是这样做:
//If structure order changes here, your data are still properly assigned to fields
sensor_t sensor1 = {.port = SENSOR_1_PORT, .pin = SENSOR_1_PIN};
如果您符合C99标准,那么您可能会更加安全:
HttpClient
答案 1 :(得分:2)
您可以定义宏以从定义中提取值。
#define GET_SECOND(x, y) y
#define PIN_VALUE(x) GET_SECOND(x)
switch (pin) {
case PIN_VALUE(SENSOR_1):
/* ... */
break;
}
PIN_VALUE
必须允许通过帮助宏扩展SENSOR_1
,以便可以提取第二部分。
答案 2 :(得分:1)
此时正确的解决方案是将定义重新设计为更有意义的内容,或者创建新的常量。
作为最后的手段,如果你坚持使用这些宏,你可以通过以下方式解析它们:
#include <stdio.h>
#include <stdint.h>
typedef int GPIO_Port_TypeDef; // whatever type this happens to be
typedef struct
{
GPIO_Port_TypeDef port;
uint8_t pin;
}sensor_t;
#define GET_FIELD(field,...) (sensor_t){__VA_ARGS__}.field
#define SENSOR_1 gpioPortA,15
int main (void)
{
int gpioPortA = 1;
printf("%d %d", GET_FIELD(port, SENSOR_1), GET_FIELD(pin, SENSOR_1));
}
类型通用版本将是:
#define GET_FIELD(type, field, ...) (type){__VA_ARGS__}.field
...
printf("%d %d", GET_FIELD(sensor_t, port, SENSOR_1), GET_FIELD(sensor_t, pin, SENSOR_1));
无论有多少个字段,这都可以变化。但是,这不是推荐的做法。应该避免使用宏,特别是可变宏。
至于如何在case
中使用运行时变量 - 你不能。请改用if-else if
语句。
答案 3 :(得分:0)
如何在define中插入一个定义?不是直接添加15,而是可以定义保持15并将其插入其他位置。
E.g:
#define SENSORVAL 15
#define SENSOR_1 gpioPortA,SENSORVAL
typedef struct
{
GPIO_Port_TypeDef port;
uint8_t pin;
}sensor_t;
sensor_t sensor1 = {SENSOR_1};
/* Now sensor1.pin is the pin value */