为什么 ,expected declaration" 错误出现在 #define 行中?使用 C

Why the ,,expected declaration" error appears in #define line? Useing C

我正在用 LoRa-02 为 stm32 编写 C 代码,我遇到了一个奇怪的错误。

错误:

预期的声明说明符或“...”在“(”标记之前

部分代码:

enter image description here

txt:

    #define PERIPH_BASE (0x40000000UL) /*!< Peripheral base address in the alias region */
    
    /*!< Peripheral memory map */
    
    #define APBPERIPH_BASE PERIPH_BASE
    
    #define AHBPERIPH_BASE (PERIPH_BASE + 0x00020000UL)
    
    #define IOPPERIPH_BASE (PERIPH_BASE + 0x10000000UL)

我正在为 SX1278 使用 stms 库。我不明白这个定义有什么问题。看起来声明顺序是正确完成的,也许是嵌套定义或一些狗屎,我不知道。另外,当我将这段代码复制粘贴到新项目中时,错误消失了。

对不起,我的伦敦不好,谢谢你的帮助:v

之前的代码:

编辑 1: 错误前的一段代码,只有其他定义:

typedef struct
{
  __IO uint16_t EP0R;            /*!< USB Endpoint 0 register,                Address offset: 0x00 */
  __IO uint16_t RESERVED0;       /*!< Reserved */
  __IO uint16_t EP1R;            /*!< USB Endpoint 1 register,                Address offset: 0x04 */
  __IO uint16_t RESERVED1;       /*!< Reserved */
  __IO uint16_t EP2R;            /*!< USB Endpoint 2 register,                Address offset: 0x08 */
  __IO uint16_t RESERVED2;       /*!< Reserved */
  __IO uint16_t EP3R;            /*!< USB Endpoint 3 register,                Address offset: 0x0C */
  __IO uint16_t RESERVED3;       /*!< Reserved */
  __IO uint16_t EP4R;            /*!< USB Endpoint 4 register,                Address offset: 0x10 */
  __IO uint16_t RESERVED4;       /*!< Reserved */
  __IO uint16_t EP5R;            /*!< USB Endpoint 5 register,                Address offset: 0x14 */
  __IO uint16_t RESERVED5;       /*!< Reserved */
  __IO uint16_t EP6R;            /*!< USB Endpoint 6 register,                Address offset: 0x18 */
  __IO uint16_t RESERVED6;       /*!< Reserved */
  __IO uint16_t EP7R;            /*!< USB Endpoint 7 register,                Address offset: 0x1C */
  __IO uint16_t RESERVED7[17];   /*!< Reserved */
  __IO uint16_t CNTR;            /*!< Control register,                       Address offset: 0x40 */
  __IO uint16_t RESERVED8;       /*!< Reserved */
  __IO uint16_t ISTR;            /*!< Interrupt status register,              Address offset: 0x44 */
  __IO uint16_t RESERVED9;       /*!< Reserved */
  __IO uint16_t FNR;             /*!< Frame number register,                  Address offset: 0x48 */
  __IO uint16_t RESERVEDA;       /*!< Reserved */
  __IO uint16_t DADDR;           /*!< Device address register,                Address offset: 0x4C */
  __IO uint16_t RESERVEDB;       /*!< Reserved */
  __IO uint16_t BTABLE;          /*!< Buffer Table address register,          Address offset: 0x50 */
  __IO uint16_t RESERVEDC;       /*!< Reserved */
  __IO uint16_t LPMCSR;          /*!< LPM Control and Status register,        Address offset: 0x54 */
  __IO uint16_t RESERVEDD;       /*!< Reserved */
  __IO uint16_t BCDR;            /*!< Battery Charging detector register,     Address offset: 0x58 */
  __IO uint16_t RESERVEDE;       /*!< Reserved */
} USB_TypeDef;

/**
  * @}
  */

/** @addtogroup Peripheral_memory_map
  * @{
  */
#define FLASH_BASE             (0x08000000UL) /*!< FLASH base address in the alias region */

#define DATA_EEPROM_BASE       (0x08080000UL) /*!< DATA_EEPROM base address in the alias region */
#define DATA_EEPROM_BANK2_BASE (0x08080C00UL) /*!< DATA EEPROM BANK2 base address in the alias region */
#define DATA_EEPROM_BANK1_END  (0x08080BFFUL) /*!< Program end DATA EEPROM BANK1 address */
#define DATA_EEPROM_BANK2_END  (0x080817FFUL) /*!< Program end DATA EEPROM BANK2 address */
#define SRAM_BASE              (0x20000000UL) /*!< SRAM base address in the alias region */
#define SRAM_SIZE_MAX          (0x00005000UL) /*!< maximum SRAM size (up to 20KBytes) */



#define PERIPH_BASE (0x40000000UL) /*!< Peripheral base address in the alias region */

编辑 2:

明确地说,我的代码 (main.c) 只是几个 #include 和一个无限循环。

部分代码,其中包含头文件:

#if defined(STM32L010xB)
  #include "stm32l010xb.h"
#elif defined(STM32L010x8)
  #include "stm32l010x8.h"
#elif defined(STM32L010x6)
  #include "stm32l010x6.h"
#elif defined(STM32L010x4)
  #include "stm32l010x4.h"
#elif defined(STM32L011xx)
  #include "stm32l011xx.h"
#elif defined(STM32L021xx)
  #include "stm32l021xx.h"
#elif defined(STM32L031xx)
  #include "stm32l031xx.h"
#elif defined(STM32L041xx)
  #include "stm32l041xx.h"
#elif defined(STM32L051xx)
  #include "stm32l051xx.h"
#elif defined(STM32L052xx)
  #include "stm32l052xx.h"
#elif defined(STM32L053xx)
  #include "stm32l053xx.h"
#elif defined(STM32L062xx)
  #include "stm32l062xx.h"
#elif defined(STM32L063xx)
  #include "stm32l063xx.h"
#elif defined(STM32L061xx)
  #include "stm32l061xx.h"
#elif defined(STM32L071xx)
  #include "stm32l071xx.h"
#elif defined(STM32L072xx)
 #include "stm32l072xx.h"  //here
#elif defined(STM32L073xx)
  #include "stm32l073xx.h"
#elif defined(STM32L082xx)
  #include "stm32l082xx.h"
#elif defined(STM32L083xx)
  #include "stm32l083xx.h"
#elif defined(STM32L081xx)
  #include "stm32l081xx.h"
#else
 #error "Please select first the target STM32L0xx device used in your application (in stm32l0xx.h file)"
#endif

和部分代码,其中使用了 PERIPH_BASE。这是一个 hal rcc 头文件:

/* Disable Backup domain write protection state change timeout */
#define RCC_DBP_TIMEOUT_VALUE      (100U)       /* 100 ms */
/* LSE state change timeout */
#define RCC_LSE_TIMEOUT_VALUE      LSE_STARTUP_TIMEOUT
#define CLOCKSWITCH_TIMEOUT_VALUE  (5000U)  /* 5 s    */
#define HSE_TIMEOUT_VALUE          HSE_STARTUP_TIMEOUT
#define MSI_TIMEOUT_VALUE          (2U)      /* 2 ms (minimum Tick + 1) */
#define HSI_TIMEOUT_VALUE          (2U)      /* 2 ms (minimum Tick + 1) */
#define LSI_TIMEOUT_VALUE          (2U)      /* 2 ms (minimum Tick + 1) */
#define PLL_TIMEOUT_VALUE          (2U)      /* 2 ms (minimum Tick + 1) */
#if defined(RCC_HSI48_SUPPORT)
#define HSI48_TIMEOUT_VALUE        (2U)      /* 2 ms (minimum Tick + 1) */
#endif /* RCC_HSI48_SUPPORT */
/**
  * @}
  */


/** @defgroup RCC_BitAddress_AliasRegion BitAddress AliasRegion
  * @brief RCC registers bit address in the alias region
  * @{
  */
#define RCC_OFFSET                (RCC_BASE - PERIPH_BASE)
/* --- CR Register ---*/
/* Alias word address of HSION bit */
#define RCC_CR_OFFSET             (RCC_OFFSET + 0x00U)
/* --- CFGR Register ---*/
/* Alias word address of I2SSRC bit */
#define RCC_CFGR_OFFSET           (RCC_OFFSET + 0x08U)
/* --- CSR Register ---*/
#define RCC_CSR_OFFSET            (RCC_OFFSET + 0x74U)

/* CR register byte 3 (Bits[23:16]) base address */
#define RCC_CR_BYTE2_ADDRESS      (0x40023802U)

/* CIER register byte 0 (Bits[0:8]) base address */
#define CIER_BYTE0_ADDRESS        ((uint32_t)(RCC_BASE + 0x10U + 0x00U))
/**

错误描述图片:

enter image description here

以及来自控制台的文本:

Building file: ../BSP/MLM32L07X01/mlm32l07x01.c
In file included from C:/Users/Wojtek/workspace/RA_B-L072Z-LRWAN1/CMSIS/device/stm32l0xx.h:153:0,
                 from C:/Users/Wojtek/workspace/RA_B-L072Z-LRWAN1/HAL_Driver/Inc/stm32l0xx_ll_rcc.h:29,
                 from ../HAL_Driver/Src/stm32l0xx_ll_utils.c:20:
C:/Users/Wojtek/workspace/RA_B-L072Z-LRWAN1/CMSIS/device/stm32l072xx.h:625:21: error: expected declaration specifiers or '...' before '(' token
 #define PERIPH_BASE (0x40000000UL) /*!< Peripheral base address in the alias region */
                     ^
C:/Users/Wojtek/workspace/RA_B-L072Z-LRWAN1/CMSIS/device/stm32l072xx.h:629:31: note: in expansion of macro 'PERIPH_BASE'
 #define APBPERIPH_BASE        PERIPH_BASE
                               ^~~~~~~~~~~
C:/Users/Wojtek/workspace/RA_B-L072Z-LRWAN1/CMSIS/device/stm32l072xx.h:641:32: note: in expansion of macro 'APBPERIPH_BASE'
 #define USART2_BASE           (APBPERIPH_BASE + 0x00004400UL)
                                ^~~~~~~~~~~~~~
C:/Users/Wojtek/workspace/RA_B-L072Z-LRWAN1/CMSIS/device/stm32l072xx.h:710:48: note: in expansion of macro 'USART2_BASE'
 #define USART2              ((USART_TypeDef *) USART2_BASE)
                                                ^~~~~~~~~~~
C:/Users/Wojtek/workspace/RA_B-L072Z-LRWAN1/inc/mlm32l0xx_hw_conf.h:120:42: note: in expansion of macro 'USART2'
 #define USARTx                           USART2
                                          ^~~~~~
C:/Users/Wojtek/workspace/RA_B-L072Z-LRWAN1/HAL_Driver/Inc/stm32l0xx_ll_rcc.h:1586:62: note: in expansion of macro 'USARTx'
 __STATIC_INLINE uint32_t LL_RCC_GetUSARTClockSource(uint32_t USARTx)
                                                              ^~~~~~
HAL_Driver/Src/subdir.mk:210: recipe for target 'HAL_Driver/Src/stm32l0xx_ll_utils.o' failed
make: *** [HAL_Driver/Src/stm32l0xx_ll_utils.o] Error 1
Invoking: MCU GCC Compiler
make: *** Waiting for unfinished jobs....
C:\Users\Wojtek\workspace\RA_B-L072Z-LRWAN1\Debug
arm-none-eabi-gcc -mcpu=cortex-m3 -mthumb -mfloat-abi=soft -DSTM32 -DSTM32L0 -DSTM32L072CZYx -DB_L072Z_LRWAN1 -DDEBUG -DSTM32L072xx -DUSE_HAL_DRIVER -DUSE_B_L072Z_LRWAN1 -I"C:/Users/Wojtek/workspace/RA_B-L072Z-LRWAN1/inc" -I"C:/Users/Wojtek/workspace/RA_B-L072Z-LRWAN1/CMSIS/core" -I"C:/Users/Wojtek/workspace/RA_B-L072Z-LRWAN1/CMSIS/device" -I"C:/Users/Wojtek/workspace/RA_B-L072Z-LRWAN1/HAL_Driver/Inc" -I"C:/Users/Wojtek/workspace/RA_B-L072Z-LRWAN1/HAL_Driver/Inc/Legacy" -I"C:/Users/Wojtek/workspace/RA_B-L072Z-LRWAN1/BSP/B-L072Z-LRWAN1" -I"C:/Users/Wojtek/workspace/RA_B-L072Z-LRWAN1/BSP/MLM32L07X01" -I"C:/Users/Wojtek/workspace/RA_B-L072Z-LRWAN1/BSP/MLM32L07X01/Phy" -I"C:/Users/Wojtek/workspace/RA_B-L072Z-LRWAN1/Lora/Phy" -I"C:/Users/Wojtek/workspace/RA_B-L072Z-LRWAN1/Lora/Utilities" -O0 -g3 -Wall -fmessage-length=0 -ffunction-sections -c -MMD -MP -MF"BSP/MLM32L07X01/mlm32l07x01.d" -MT"BSP/MLM32L07X01/mlm32l07x01.o" -o "BSP/MLM32L07X01/mlm32l07x01.o" "../BSP/MLM32L07X01/mlm32l07x01.c"
Finished building: ../HAL_Driver/Src/stm32l0xx_ll_usb.c
 
Finished building: ../BSP/MLM32L07X01/Phy/sx1276.c
 
Finished building: ../BSP/MLM32L07X01/mlm32l07x01.c
 

14:07:34 Build Finished (took 15s.652ms)

编辑 3:

可能导致问题的函数:

stm32l0xx_ll_rcc.c:

uint32_t LL_RCC_GetUSARTClockFreq(uint32_t USARTxSource)
{
  uint32_t usart_frequency = LL_RCC_PERIPH_FREQUENCY_NO;

  /* Check parameter */
  assert_param(IS_LL_RCC_USART_CLKSOURCE(USARTxSource));
#if defined(RCC_CCIPR_USART1SEL)
  if (USARTxSource == LL_RCC_USART1_CLKSOURCE)
  {
    /* USART1CLK clock frequency */
    switch (LL_RCC_GetUSARTClockSource(USARTxSource))
    {
      case LL_RCC_USART1_CLKSOURCE_SYSCLK: /* USART1 Clock is System Clock */
        usart_frequency = RCC_GetSystemClockFreq();
        break;

      case LL_RCC_USART1_CLKSOURCE_HSI:    /* USART1 Clock is HSI Osc. */
        if (LL_RCC_HSI_IsReady() != 0U)
        {
          if (LL_RCC_IsActiveFlag_HSIDIV() != 0U)
          {
            usart_frequency = (HSI_VALUE >> 2U);
          }
          else
          {
            usart_frequency = HSI_VALUE;
          }
        }
        break;

      case LL_RCC_USART1_CLKSOURCE_LSE:    /* USART1 Clock is LSE Osc. */
        if (LL_RCC_LSE_IsReady() != 0U)
        {
          usart_frequency = LSE_VALUE;
        }
        break;

      case LL_RCC_USART1_CLKSOURCE_PCLK2:  /* USART1 Clock is PCLK2 */
      default:
        usart_frequency = RCC_GetPCLK2ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq()));
        break;
    }
  }
#endif /* RCC_CCIPR_USART1SEL  */

#if defined(RCC_CCIPR_USART2SEL)
  if (USARTxSource == LL_RCC_USART2_CLKSOURCE)
  {
    /* USART2CLK clock frequency */
    switch (LL_RCC_GetUSARTClockSource(USARTxSource))
    {
      case LL_RCC_USART2_CLKSOURCE_SYSCLK: /* USART2 Clock is System Clock */
        usart_frequency = RCC_GetSystemClockFreq();
        break;

      case LL_RCC_USART2_CLKSOURCE_HSI:    /* USART2 Clock is HSI Osc. */
        if (LL_RCC_HSI_IsReady() != 0U)
        {
          if (LL_RCC_IsActiveFlag_HSIDIV() != 0U)
          {
            usart_frequency = (HSI_VALUE >> 2U);
          }
          else
          {
            usart_frequency = HSI_VALUE;
          }
        }
        break;

      case LL_RCC_USART2_CLKSOURCE_LSE:    /* USART2 Clock is LSE Osc. */
        if (LL_RCC_LSE_IsReady() != 0U)
        {
          usart_frequency = LSE_VALUE;
        }
        break;

      case LL_RCC_USART2_CLKSOURCE_PCLK1:  /* USART2 Clock is PCLK1 */
      default:
        usart_frequency = RCC_GetPCLK1ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq()));
        break;
    }
  }
#endif /* RCC_CCIPR_USART2SEL */

  return usart_frequency;
}

stm32l0xx_ll_rcc.h:

/**
  * @brief  Get USARTx clock source
  * @rmtoll CCIPR        USARTxSEL     LL_RCC_GetUSARTClockSource
  * @param  USARTx This parameter can be one of the following values:
  *         @arg @ref LL_RCC_USART1_CLKSOURCE (*)
  *         @arg @ref LL_RCC_USART2_CLKSOURCE
  * @retval Returned value can be one of the following values:
  *         @arg @ref LL_RCC_USART1_CLKSOURCE_PCLK2 (*)
  *         @arg @ref LL_RCC_USART1_CLKSOURCE_SYSCLK (*)
  *         @arg @ref LL_RCC_USART1_CLKSOURCE_HSI (*)
  *         @arg @ref LL_RCC_USART1_CLKSOURCE_LSE (*)
  *         @arg @ref LL_RCC_USART2_CLKSOURCE_PCLK1
  *         @arg @ref LL_RCC_USART2_CLKSOURCE_SYSCLK
  *         @arg @ref LL_RCC_USART2_CLKSOURCE_HSI
  *         @arg @ref LL_RCC_USART2_CLKSOURCE_LSE
  *
  *         (*) value not defined in all devices.
  */
__STATIC_INLINE uint32_t LL_RCC_GetUSARTClockSource(uint32_t USARTx)
{
  return (uint32_t)(READ_BIT(RCC->CCIPR, USARTx) | (USARTx << 16U));
}

编译器输出的这一片段揭示了问题的性质(或至少一个问题):

C:/Users/Wojtek/workspace/RA_B-L072Z-LRWAN1/inc/mlm32l0xx_hw_conf.h:120:42: note: in expansion of macro 'USART2'
 #define USARTx                           USART2
                                          ^~~~~~
C:/Users/Wojtek/workspace/RA_B-L072Z-LRWAN1/HAL_Driver/Inc/stm32l0xx_ll_rcc.h:1586:62: note: in expansion of macro 'USARTx'
 __STATIC_INLINE uint32_t LL_RCC_GetUSARTClockSource(uint32_t USARTx)

在函数 LL_RCC_GetUSARTClockSource 的声明中,您试图为参数指定一个已定义为宏标识符的名称 (USARTx)。结果是参数/宏名称被替换为宏的扩展文本,最终借鉴了您的 PERIPH_BASE 宏。这在当时是无效的。