带#ifdef的C宏
我想知道是否有更好的方法来实现此代码:带#ifdef的C宏,c,stm32,stm32f4,C,Stm32,Stm32f4,我想知道是否有更好的方法来实现此代码: if (strcmp(port_p, all_ports_a[inc++]) == 0) { #ifdef GPIOA HAL_GPIO_WritePin(GPIOA, all_pins_a[offset] , atoi(args[OFF_VALUE_WRITE])); SER_send("Value written\r", strlen("Value written\r"));
if (strcmp(port_p, all_ports_a[inc++]) == 0)
{
#ifdef GPIOA
HAL_GPIO_WritePin(GPIOA, all_pins_a[offset] , atoi(args[OFF_VALUE_WRITE]));
SER_send("Value written\r", strlen("Value written\r"));
return 1;
#endif
//b
}else if (strcmp(port_p, all_ports_a[inc++]) == 0){
#ifdef GPIOB
HAL_GPIO_WritePin(GPIOB, all_pins_a[offset] , atoi(args[OFF_VALUE_WRITE]));
SER_send("Value written\r", strlen("Value written\r"));
return 1;
#endif
//c
}else if (strcmp(port_p, all_ports_a[inc++]) == 0){
#ifdef GPIOC
HAL_GPIO_WritePin(GPIOC, all_pins_a[offset] , atoi(args[OFF_VALUE_WRITE]));
SER_send("Value written\r", strlen("Value written\r"));
return 1;
#endif
//etc.
特别是这一部分:
#ifdef GPIOA
HAL_GPIO_WritePin(GPIOA, all_pins_a[offset] , atoi(args[OFF_VALUE_WRITE]));
SER_send("Value written\r", strlen("Value written\r"));
return 1;
#endif
我想用一个宏来代替它,比如:
MY_宏(GPIOx,消息):
我知道我们不能在宏中添加#ifdef,但也许我遗漏了什么?一行而不是5行就太好了
谢谢
AJT这里有一个可能的解决方案,尽管它可能不是对原始代码的改进
#ifdef GPIOA
#define MY_MACRO_GPIOA(MESSAGE) MY_MACRO_(GPIOA, MESSAGE)
#else
#define MY_MACRO_GPIOA(MESSAGE) do; while (0)
#endif
#ifdef GPIOB
#define MY_MACRO_GPIOB(MESSAGE) MY_MACRO_(GPIOB, MESSAGE)
#else
#define MY_MACRO_GPIOB(MESSAGE) do; while (0)
#endif
#ifdef GPIOC
#define MY_MACRO_GPIOC(MESSAGE) MY_MACRO_(GPIOC, MESSAGE)
#else
#define MY_MACRO_GPIOC(MESSAGE) do; while (0)
#endif
#define MY_MACRO_(GPIOx, MESSAGE) \
do { \
HAL_GPIO_WritePin(GPIOx, all_pins_a[offset] , atoi(args[OFF_VALUE_WRITE])); \
SER_send(MESSAGE, strlen(MESSAGE)); \
return 1; \
} while (0)
#define MY_MACRO(GPIOx, MESSAGE) MY_MACRO_##GPIOx(MESSAGE)
这里有一个可能的解决方案,尽管它可能不是对原始代码的改进
#ifdef GPIOA
#define MY_MACRO_GPIOA(MESSAGE) MY_MACRO_(GPIOA, MESSAGE)
#else
#define MY_MACRO_GPIOA(MESSAGE) do; while (0)
#endif
#ifdef GPIOB
#define MY_MACRO_GPIOB(MESSAGE) MY_MACRO_(GPIOB, MESSAGE)
#else
#define MY_MACRO_GPIOB(MESSAGE) do; while (0)
#endif
#ifdef GPIOC
#define MY_MACRO_GPIOC(MESSAGE) MY_MACRO_(GPIOC, MESSAGE)
#else
#define MY_MACRO_GPIOC(MESSAGE) do; while (0)
#endif
#define MY_MACRO_(GPIOx, MESSAGE) \
do { \
HAL_GPIO_WritePin(GPIOx, all_pins_a[offset] , atoi(args[OFF_VALUE_WRITE])); \
SER_send(MESSAGE, strlen(MESSAGE)); \
return 1; \
} while (0)
#define MY_MACRO(GPIOx, MESSAGE) MY_MACRO_##GPIOx(MESSAGE)
你可以做一些完全不同的事情。在表中排列数据,然后查找具有匹配名称的行,并使用该行上的值 首先定义包含所有必要数据的表格:
// Definition of single row
typedef struct {
char name[NAME_MAX];
GPIO_T gpio;
char message[MESSAGE_MAX];
} Port_T;
// Table with all rows
Port_T const ports[] = {
#ifdef GPIOA
{ "GPIOA", GPIOA, "GPIOA message" },
#endif
#ifdef GPIOB
{ "GPIOB", GPIOB, "GPIOB message" },
#endif
...
};
// Number of rows on the table
size_t const portCount = sizeof ports / sizeof *ports;
然后将if/else
链替换为for
循环:
for(size_t i=0; i<portCount; ++i) {
Port_T const * port = &ports[i];
if(strcmp(port_p, port->name) == 0) {
HAL_GPIO_WritePin(port->gpio, all_pins_a[offset], atoi(args[OFF_VALUE_WRITE]));
SER_send(port->message, strlen(port->message));
return 1;
}
}
(大小i=0;iname)==0)的{
HAL_GPIO_WritePin(端口->GPIO,所有_管脚_a[offset],atoi(args[OFF_VALUE\u WRITE]);
SERU send(端口->消息,strlen(端口->消息));
返回1;
}
}
对于循环,您还可以使用比简单的
更高级的搜索例程,如二进制搜索。您可以做一些完全不同的事情。在表中排列数据,然后查找具有匹配名称的行,并使用该行上的值
首先定义包含所有必要数据的表格:
// Definition of single row
typedef struct {
char name[NAME_MAX];
GPIO_T gpio;
char message[MESSAGE_MAX];
} Port_T;
// Table with all rows
Port_T const ports[] = {
#ifdef GPIOA
{ "GPIOA", GPIOA, "GPIOA message" },
#endif
#ifdef GPIOB
{ "GPIOB", GPIOB, "GPIOB message" },
#endif
...
};
// Number of rows on the table
size_t const portCount = sizeof ports / sizeof *ports;
然后将if/else
链替换为for
循环:
for(size_t i=0; i<portCount; ++i) {
Port_T const * port = &ports[i];
if(strcmp(port_p, port->name) == 0) {
HAL_GPIO_WritePin(port->gpio, all_pins_a[offset], atoi(args[OFF_VALUE_WRITE]));
SER_send(port->message, strlen(port->message));
return 1;
}
}
(大小i=0;iname)==0)的{
HAL_GPIO_WritePin(端口->GPIO,所有_管脚_a[offset],atoi(args[OFF_VALUE\u WRITE]);
SERU send(端口->消息,strlen(端口->消息));
返回1;
}
}
您还可以使用比简单的更高级的搜索例程来执行循环,如二进制搜索。您不知道如何使用#define
定义宏吗?我会先询问基本程序设计。为什么要将字符串比较与GPIO混合使用?这是一个可疑的组合。。。这些字符串是通过UART终端还是其他方式输入的?如果是这样,您应该1)解析输入,2)找出它指定的端口3)将其转换为整数索引0到n 4)激活与该索引对应的端口。您应该发现自己拥有一个volatile uint32\u t*
数组,该数组要么指向GPIO端口,要么指向NULL,具体取决于端口是否存在。通过预处理器#idef
或类似程序生成该表。如果在未定义各种符号时,then子句将为空,您也可以省略strcmp
测试(有一些小改动,因此inc
得到正确管理)。@Lundin,是的,我通过串行链接发送命令(在我的例子中是UART)要配置端口、读取引脚等。配置命令示例:gpio_config a 5 opp nopull flow none\r write命令示例:gpio_write a 5 1\r解析命令是在程序的另一部分中完成的,我的应用程序是在MCU上实现的外壳(目前为STM32Fxx,因此我的代码应该在所有STM32Fxx上编译)你难道不知道如何用#define
定义宏吗?我首先要问的是基本的程序设计。为什么要将字符串比较与GPIO混合使用?这是一个可疑的组合。。。这些字符串是通过UART终端还是其他方式输入的?如果是这样,您应该1)解析输入,2)找出它指定的端口3)将其转换为整数索引0到n 4)激活与该索引对应的端口。您应该发现自己拥有一个volatile uint32\u t*
数组,该数组要么指向GPIO端口,要么指向NULL,具体取决于端口是否存在。通过预处理器#idef
或类似程序生成该表。如果在未定义各种符号时,then子句将为空,您也可以省略strcmp
测试(有一些小改动,因此inc
得到正确管理)。@Lundin,是的,我通过串行链接发送命令(在我的例子中是UART)要配置端口、读取引脚等。配置命令示例:gpio_config a 5 opp nopull flow none\r write命令示例:gpio_write a 5 1\r解析命令是在程序的另一部分中完成的,我的应用程序是在MCU上实现的外壳(目前为STM32Fxx,因此我的代码应该在所有STM32Fxx上编译)检索命令并处理它。好的,很好!我以后再试试!谢谢你的回答好的,太好了!我以后再试试!谢谢你的回答