C - 初始化 GPIO 时函数调用出现 STM32f4 错误

C - STM32f4 error on function call when initializing GPIO

我已经编写了一个程序来为 STM32F4 初始化 GPIO,但是在我尝试构建此代码后出于某种原因:

包括 ST header:

#include "stm32f4_discovery.h"

定义GPIO起始地址:

#define GPIOA ((struct GPIO *) 0x40020000)
#define GPIOB ((struct GPIO *) 0x40020400)
#define GPIOC ((struct GPIO *) 0x40020800)
#define GPIOD ((struct GPIO *) 0x40020C00)
#define GPIOE ((struct GPIO *) 0x40021000)
#define GPIOF ((struct GPIO *) 0x40021400)
#define GPIOG ((struct GPIO *) 0x40021800)
#define GPIOH ((struct GPIO *) 0x40021C00)
#define GPIOI ((struct GPIO *) 0x40022000)

重置和时钟控制:

#define RCC   ((uint32_t *) 0x40023830)

#define IN              uint8_t 0
#define OUT             uint8_t 1
#define NO_PULL         uint8_t 0
#define PULL_UP         uint8_t 1
#define PULL_DOWN       uint8_t 2
#define PUSH_PULL       uint8_t 0
#define OPEN_DRAIN      uint8_t 1
#define S2MHz           uint8_t 0
#define S25MHz          uint8_t 1
#define S50MHz          uint8_t 2
#define S100MHz         uint8_t 3

基本 GPIO 结构:

struct GPIO {
    uint32_t MODER;
    uint32_t TYPER;
    uint32_t OSPEEDR;
    uint32_t PUPDR;
    uint32_t IDR;
    uint32_t ODR;
    uint16_t BSSR_SET;
    uint16_t BSSR_RESET;
};

void Init_GPIO(struct GPIO *GPIO_Type, uint32_t GPIO_Mode, uint8_t in_out, uint8_t pull, uint8_t push_pull, uint8_t freq) {
    // Set MODER:

    if (in_out) {
        GPIO_Type->MODER |= (1 << GPIO_Mode);
        GPIO_Type->MODER &= ~(2 << GPIO_Mode);
    }
    else {
        GPIO_Type->MODER &= ~(3 << GPIO_Mode);
    }

    // Set PUPDR:

    if (!pull) {
        GPIO_Type->PUPDR &= ~(3 << GPIO_Mode);
    }
    else if (pull == 1) {
        GPIO_Type->PUPDR |= (1 << GPIO_Mode);
        GPIO_Type->PUPDR &= ~(2 << GPIO_Mode);
    }
    else if (pull == 2) {
        GPIO_Type->PUPDR |= (2 << GPIO_Mode);
        GPIO_Type->PUPDR &= ~(1 << GPIO_Mode);
    }

    // Set TYPER:

    if (push_pull) {
        GPIO_Type->TYPER &= ~(1 << GPIO_Mode);
    }
    else {
        GPIO_Type->TYPER |= (1 << GPIO_Mode);
    }

    // Set OSPEEDR:

    if (!freq) {
        GPIO_Type->OSPEEDR &= ~(3 << GPIO_Mode);
    }
    else if (freq == 1) {
        GPIO_Type->OSPEEDR |= (1 << GPIO_Mode);
        GPIO_Type->OSPEEDR &= (2 << GPIO_Mode);
    }
    else if (freq == 2) {
        GPIO_Type->OSPEEDR |= (2 << GPIO_Mode);
        GPIO_Type->OSPEEDR &= ~(1 << GPIO_Mode);
    }
    else {
        GPIO_Type->OSPEEDR &= (3 << GPIO_Mode);
    }
}

/**
  * @brief  Main program
  * @param  None
  * @retval None
  */
int main(void)
{
    Init_GPIO(GPIOD,  12, OUT, NO_PULL, PUSH_PULL, S2MHz);
    Init_GPIO(GPIOA, 0, IN, NO_PULL, PUSH_PULL, S2MHz);

    while (1) {

    }
}

我收到以下关于 Init_GPIO 函数调用的错误:

Error[Pe254]: type name is not allowed C:\Users\..\main.c 93 
Error[Pe165]: too few arguments in function call C:\Users\..\main.c 93
Error[Pe018]: expected a ")" C:\Users\..\main.c 93 
Error[Pe254]: type name is not allowed C:\Users\..\main.c 94
Error[Pe165]: too few arguments in function call C:\Users\..\main.c 94
Error[Pe018]: expected a ")" C:\Users\..\main.c 94
Error while running C/C++ Compiler 

您的宏 INOUT 等定义不正确,并且在对 Init_GPIO() 的调用中展开时没有语法意义。

变化:

#define IN              uint8_t 0

#define IN              ((uint8_t)0)

例如,类似地为其他类似地定义宏。

每当您在包含预处理器宏的行上遇到编译器错误时,您必须考虑该行在宏扩展后的样子,因为这就是编译器 "seeing".

或者,使用 ST 标准外设库,其中已经正确 定义了 GPIO 初始化和与您定义的相似的符号、类型和宏。可以找到使用标准外设库访问 GPIO 的示例 here. The author refers to it as the CMSIS Library, but strictly it is merely CMSIS compliant but STM32 specific. Other examples are included with the library itself. The library is likely included with you toolchain (which appears to be IAR), but can be downloaded from ST here - 您可能会忽略有关库被 STM32Cube 取代的内容,除非您想要那种手握代码膨胀并且永远不会喜欢的东西想要将您的代码移植到非 STM32 平台。