2023-05-03 06:34 PM
I am developing my own driver for a STM32 MCU, however I always get the same error when I try to compile the code. Here is the entire code from all the files I developed.
There are always 8 errors, saying that pGPIOA, pGPIOB, pGPIOC, pGPIOD, pGPIOE , pGPIOF and pGPIOG have multiple definitions.
main.c
#include "stm32f103xx.h"
void delay(void);
int main(void){
GPIO_Handle_t GPIOLed;
GPIOLed.pGPIOx = GPIOA;
GPIOLed.GPIO_PinConfig.GPIO_PinNumber = GPIO_PIN_5;
GPIOLed.GPIO_PinConfig.GPIO_PinMode = GPIO_MODE_OUTPUT_10MHZ;
GPIO_PeriClockControl(GPIOA, ENABLE);
GPIO_Init(&GPIOLed);
while(1){
GPIO_ToggleOutputPin(GPIOA, GPIO_PIN_5);
delay();
}
return 0;
}
void delay(void){
for(uint32_t i=0;i<500000;i++){
;
}
}
stm32f103xx.h
#ifndef INC_STM32F103XX_H_
#define INC_STM32F103XX_H_
#include <stdint.h> /* Native library to use unsigned integers of 8, 16 and 32 bits */
#define FLASH_BASEADDR 0x08000000U /* Start address of the embedded Flash memory */
#define SRAM1_BASEADDR 0x20000000U /* Start address of the embedded SRAM memory */
#define PERIPH_BASE 0x40000000U /* Start address of the peripheral bus */
#define APB1PERIPH_BASE PERIPH_BASE /* Start address of the APB1 bus */
#define APB2PERIPH_BASE 0x40010000U /* Start address of the APB2 bus */
#define APHPERIPH_BASE 0x40018000U /* Start address of the AHB bus */
#define RCC_BASEADDR (APHPERIPH_BASE + 0x9000)
/* Address from APB2 Peripherals APB2 */
#define GPIOA_BASEADDR (APB2PERIPH_BASE + 0x0800)
#define GPIOB_BASEADDR (APB2PERIPH_BASE + 0x0C00)
#define GPIOC_BASEADDR (APB2PERIPH_BASE + 0x1000)
#define GPIOD_BASEADDR (APB2PERIPH_BASE + 0x1400)
#define GPIOE_BASEADDR (APB2PERIPH_BASE + 0x1800)
#define GPIOF_BASEADDR (APB2PERIPH_BASE + 0x1C00)
#define GPIOG_BASEADDR (APB2PERIPH_BASE + 0x2000)
#define EXTI_BASEADDR 0x40010400 /* Start address of the EXTI bus */
/* Address from APB1 Peripherals APB1 */
#define SPI2_BASEADDR (APB1PERIPH_BASE + 0x3800)
#define SPI3_BASEADDR (APB1PERIPH_BASE + 0x3C00)
#define USART2_BASEADDR (APB1PERIPH_BASE + 0x4400)
#define USART3_BASEADDR (APB1PERIPH_BASE + 0x4800)
#define UART4_BASEADDR (APB1PERIPH_BASE + 0x4C00)
#define UART5_BASEADDR (APB1PERIPH_BASE + 0x5000)
#define I2C1_BASEADDR (APB1PERIPH_BASE + 0x5400)
#define I2C2_BASEADDR (APB1PERIPH_BASE + 0x5800)
/* Structure to hold the registers from GPIOs on STM32F103xx */
typedef struct{
volatile uint32_t CRL;
volatile uint32_t CRH;
volatile uint32_t IDR;
volatile uint32_t ODR;
volatile uint32_t BSRR;
volatile uint32_t BRR;
volatile uint32_t LCKR;
}GPIO_RegDef_t;
/* Structure to hold the registers from RCC on STM32F103xx*/
typedef struct{
volatile uint32_t CR;
volatile uint32_t CFGR;
volatile uint32_t CIR;
volatile uint32_t APB2RSTR;
volatile uint32_t APB1RSTR;
volatile uint32_t AHBENR;
volatile uint32_t APB2ENR;
volatile uint32_t APB1ENR;
volatile uint32_t BDCR;
volatile uint32_t CSR;
volatile uint32_t AHBSTR;
volatile uint32_t CFGR2;
}RCC_RegDef_t;
/* Macro for GPIOs memory positions */
# define GPIOA ((GPIO_RegDef_t*) GPIOA_BASEADDR)
# define GPIOB ((GPIO_RegDef_t*) GPIOB_BASEADDR)
# define GPIOC ((GPIO_RegDef_t*) GPIOC_BASEADDR)
# define GPIOD ((GPIO_RegDef_t*) GPIOD_BASEADDR)
# define GPIOE ((GPIO_RegDef_t*) GPIOE_BASEADDR)
# define GPIOF ((GPIO_RegDef_t*) GPIOF_BASEADDR)
# define GPIOG ((GPIO_RegDef_t*) GPIOG_BASEADDR)
GPIO_RegDef_t *pGPIOA = GPIOA;
GPIO_RegDef_t *pGPIOB = GPIOB;
GPIO_RegDef_t *pGPIOC = GPIOC;
GPIO_RegDef_t *pGPIOD = GPIOD;
GPIO_RegDef_t *pGPIOE = GPIOE;
GPIO_RegDef_t *pGPIOF = GPIOF;
GPIO_RegDef_t *pGPIOG = GPIOG;
/* Macro for RCC memory position */
#define RCC ((RCC_RegDef_t*) RCC_BASEADDR)
/* Macro for clock enable on APB2 bus peripherals */
#define GPIOA_PCLK_EN (RCC->APB2ENR |= (1 << 2))
#define GPIOB_PCLK_EN (RCC->APB2ENR |= (1 << 3))
#define GPIOC_PCLK_EN (RCC->APB2ENR |= (1 << 4))
#define GPIOD_PCLK_EN (RCC->APB2ENR |= (1 << 5))
#define GPIOE_PCLK_EN (RCC->APB2ENR |= (1 << 6))
/* Macro for clock enable on APB1 bus peripherals */
#define SPI2_PCLK_EN (RCC->APB1ENR |= (1 << 14))
#define SPI3_PCLK_EN (RCC->APB1ENR |= (1 << 15))
#define USART2_PCLK_EN (RCC->APB1ENR |= (1 << 17))
#define USART3_PCLK_EN (RCC->APB1ENR |= (1 << 18))
#define UART4_PCLK_EN (RCC->APB1ENR |= (1 << 19))
#define UART5_PCLK_EN (RCC->APB1ENR |= (1 << 20))
#define I2C1_PCLK_EN (RCC->APB1ENR |= (1 << 21))
#define I2C2_PCLK_EN (RCC->APB1ENR |= (1 << 22))
/* Macro for clock disable on APB2 bus peripherals */
#define GPIOA_PCLK_DI (RCC->APB2ENR &= ~(1 << 2))
#define GPIOB_PCLK_DI (RCC->APB2ENR &= ~(1 << 3))
#define GPIOC_PCLK_DI (RCC->APB2ENR &= ~(1 << 4))
#define GPIOD_PCLK_DI (RCC->APB2ENR &= ~(1 << 5))
#define GPIOE_PCLK_DI (RCC->APB2ENR &= ~(1 << 6))
/* Macro for clock disable on APB1 bus peripherals */
#define SPI2_PCLK_DI RCC->APB1ENR &= ~(1 << 14)
#define SPI3_PCLK_DI RCC->APB1ENR &= ~(1 << 15)
#define USART2_PCLK_DI RCC->APB1ENR &= ~(1 << 17)
#define USART3_PCLK_DI RCC->APB1ENR &= ~(1 << 18)
#define UART4_PCLK_DI RCC->APB1ENR &= ~(1 << 19)
#define UART5_PCLK_DI RCC->APB1ENR &= ~(1 << 20)
#define I2C1_PCLK_DI RCC->APB1ENR &= ~(1 << 21)
#define I2C2_PCLK_DI RCC->APB1ENR &= ~(1 << 22)
/* Macro to reset the GPIOx registers */
#define GPIOA_REG_RESET() do {(RCC->APB2RSTR |= (1 << 2)); (RCC->APB2RSTR &= (1 << 2));} while(0)
#define GPIOB_REG_RESET() do {(RCC->APB2RSTR |= (1 << 3)); (RCC->APB2RSTR &= (1 << 3));} while(0)
#define GPIOC_REG_RESET() do {(RCC->APB2RSTR |= (1 << 4)); (RCC->APB2RSTR &= (1 << 4));} while(0)
#define GPIOD_REG_RESET() do {(RCC->APB2RSTR |= (1 << 5)); (RCC->APB2RSTR &= (1 << 5));} while(0)
#define GPIOE_REG_RESET() do {(RCC->APB2RSTR |= (1 << 6)); (RCC->APB2RSTR &= (1 << 6));} while(0)
#define ENABLE 1
#define DISABLE 0
#define SET ENABLE
#define RESET DISABLE
#define GPIO_PIN_SET SET
#define GPIO_PIN_RESET RESET
#include "stm32f103xx_gpio_driver.h"
#endif
stm32f103xx_gpio_driver.h
#ifndef INC_STM32F103XX_GPIO_DRIVER_H_
#define INC_STM32F103XX_GPIO_DRIVER_H_
#include "stm32f103xx.h"
typedef struct{
uint8_t GPIO_PinNumber;
uint8_t GPIO_PinMode;
uint8_t GPIO_PinSpeed;
uint8_t GPIO_PinPuPdControl;
uint8_t GPIO_PinOPType;
uint8_t GPIO_PinAltFunMode;
}GPIO_PinConfig_t;
typedef struct{
GPIO_RegDef_t *pGPIOx; /* Holds the base address of the GPIO port to which the pin belongs */
GPIO_PinConfig_t GPIO_PinConfig; /* Holds the GPIO pin configuration settings */
}GPIO_Handle_t;
/* GPIO possible modes */
#define GPIO_MODE_INPUT 0
#define GPIO_MODE_OUTPUT_10MHZ 1
#define GPIO_MODE_OUTPUT_2MHZ 2
#define GPIO_MODE_OUTPUT_50MHZ 3
/* GPIO output mode */
#define GPIO_OUT_PP 0
#define GPIO_OUT_OD 1
#define GPIO_ALT_PP 2
#define GPIO_ALT_OD 3
/* GPIO input mode */
#define GPIO_IN_ANL 0
#define GPIO_IN_FI 1
#define GPIO_IN_PUPD 2
/* GPIO pin number */
#define GPIO_PIN_0 0
#define GPIO_PIN_1 1
#define GPIO_PIN_2 2
#define GPIO_PIN_3 3
#define GPIO_PIN_4 4
#define GPIO_PIN_5 5
#define GPIO_PIN_6 6
#define GPIO_PIN_7 7
#define GPIO_PIN_8 8
#define GPIO_PIN_9 9
#define GPIO_PIN_10 10
#define GPIO_PIN_11 11
#define GPIO_PIN_12 12
#define GPIO_PIN_13 13
#define GPIO_PIN_14 14
#define GPIO_PIN_15 15
/***************************************************************************************************
* APIs supported by this driver
* For more informations about the APIs check the function definitions
************************************************************************************************** */
/*
* Peripheral clock setup
*/
void GPIO_PeriClockControl(GPIO_RegDef_t *pGPIOx, uint8_t EnorDi);
/*
* Initialize and Disable Initialization
*/
void GPIO_Init(GPIO_Handle_t *pGPIOHandle);
void GPIO_Deinit(GPIO_RegDef_t *pGPIOx);
/*
* Data read and write
*/
uint8_t GPIO_ReadFromInputPin(GPIO_RegDef_t *pGPIOx, uint8_t PinNumber);
uint16_t GPIO_ReadFromInputPort(GPIO_RegDef_t *pGPIOx);
void GPIO_WriteToOutputPin(GPIO_RegDef_t *pGPIOx, uint8_t PinNumber, uint8_t Value);
void GPIO_WriteToOutputPort(GPIO_RegDef_t *pGPIOx, uint8_t Value);
void GPIO_ToggleOutputPin(GPIO_RegDef_t *pGPIOx, uint8_t PinNumber);
/*
* IRQ Configuration and ISR Handling
*/
void GPIO_IRQConfig(uint8_t IRQNumber, uint8_t IRQPriority, uint8_t EnorDi);
void GPIO_IRQHandling(uint8_t PinNumber);
#endif
On stm32f103xx_gpio_driver.c there are only the functions instructions defined in stm32f103xx_gpio_driver.h. At the beginning of the file, I include the stm32f103xx_gpio_driver.h
2023-05-03 07:12 PM
Problem here is that you define things in both main.c and stm32f103xx_gpio_driver.c
You need these in ONE .C file (definition / assignment)
And these is the stm32f103xx.h