Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/hadoop/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
带#ifdef的C宏_C_Stm32_Stm32f4 - Fatal编程技术网

带#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上编译)检索命令并处理它。好的,很好!我以后再试试!谢谢你的回答好的,太好了!我以后再试试!谢谢你的回答