Associate
January 24, 2023
Question
Why toggling LED4 USER doesn't work with this code ( Board nucleo G071RB) ? I know that problem is in my init function. But I don't know how to correct it because GPIOA base adress (which is also MODER register address) is right
- January 24, 2023
- 6 replies
- 2315 views
,void GPIO_Init(GPIO_Handle_t *pGPIOHandle)
{
uint32_t temp = 0;
//1.configure mode of gpio pin
if(pGPIOHandle->GPIO_PinConfig.GPIO_PinMode<=GPIO_MODE_ANALOG)
{
temp = (pGPIOHandle->GPIO_PinConfig.GPIO_PinMode<<(2 *pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber));
pGPIOHandle->pGPIOx->MODER &= ~(0x3<<pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber);//clear bit position before modification
pGPIOHandle->pGPIOx->MODER |= temp;
}
else
{
//later (interrruption)
}
temp = 0;
temp =( pGPIOHandle->GPIO_PinConfig.GPIO_PinSpeed<<(2*pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber));
pGPIOHandle->pGPIOx->OSPEEDR &= ~(0x3<<pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber);//clear bit position before modification
pGPIOHandle->pGPIOx->OSPEEDR |= temp;
temp = 0;
//3.configure pupd settings
temp =( pGPIOHandle->GPIO_PinConfig.GPIO_PinPuPdControl<<(2*pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber));
pGPIOHandle->pGPIOx->PUPDR &= ~(0x3<<pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber);//clear bit position before modification
pGPIOHandle->pGPIOx->PUPDR |= temp;
temp = 0;
//4.configure output type
temp =( pGPIOHandle->GPIO_PinConfig.GPIO_PinOPType<<(1*pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber));
pGPIOHandle->pGPIOx->OTYPER |= temp;
temp = 0;
//5.configure the alt functionality
if(pGPIOHandle->GPIO_PinConfig.GPIO_PinMode == GPIO_MODE_ALTFN)
{
uint32_t temp1, temp2;
temp1= pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber/8;
temp2= pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber%8;
pGPIOHandle->pGPIOx->AFR[temp1] &= ~(0xF<<(4*temp2));//clearing
pGPIOHandle->pGPIOx->AFR[temp1] |= (pGPIOHandle->GPIO_PinConfig.GPIO_PinAltFunMode<<(4*temp2));
}
}/*
* stm32g0xx.h
*
*
* Author: admin
*/
#ifndef INC_STM32G0XX_H_
#define INC_STM32G0XX_H_
#include <stdint.h>
#if !defined(__SOFT_FP__) && defined(__ARM_FP)
#warning "FPU is not initialized, but the project is compiling for an FPU. Please initialize the FPU before use."
#endif
#define FLASH_BASEADDR 0x08000000U
#define SRAM1_BASEADDR 0x20000000U
#define SRAM SRAM1_BASEADDR
#define ROM_BASEADDR 0x1FFF0000U
#define PERIPH_BASE 0x40000000U
#define APBPERIPHBASE PERIPH_BASE
#define AHBPERIPHBASE 0x40020000U
#define IOPERIPHBASE 0x50000000U
#define GPIOA_BASEADDR 0x50000000U
#define GPIOB_BASEADDR 0x50000400U
#define GPIOC_BASEADDR 0x50000800U
#define GPIOD_BASEADDR 0x50000C00U
#define GPIOE_BASEADDR 0x50001000U
#define GPIOF_BASEADDR 0x50001400U
#define SYSCFG_BASEADDR 0x40010000U
#define RCC_BASEADDR 0x40021000U
typedef struct //registre gPIO, accessible grace à un pointeur par la suite
{
volatile uint32_t MODER; //Adress offset: 0x00
volatile uint32_t OTYPER;//Adress offset: 0x04
volatile uint32_t OSPEEDR;
volatile uint32_t PUPDR;
volatile uint32_t IDR;
volatile uint32_t ODR;
volatile uint32_t BSRR;
volatile uint32_t LCKR;
volatile uint32_t AFR[2];//High et Low registers
volatile uint32_t BRR;
}GPIO_RegDef_t;
typedef struct
{
volatile uint32_t RCC_CR;
volatile uint32_t RCC_ICSCR;
volatile uint32_t RCC_CFGR;
volatile uint32_t RCC_PLL_CFGR;
volatile uint32_t Reserved0;//0x10
volatile uint32_t RCC_CRRCR;
volatile uint32_t RCC_CIER;
volatile uint32_t RCC_CIFR;
volatile uint32_t RCC_CICR;
volatile uint32_t RCC_IOPRSTR;
volatile uint32_t AHBRSTR;
volatile uint32_t RCC_APBRSTR1;
volatile uint32_t RCC_APBRSTR2;
volatile uint32_t RCC_IOPENR;
volatile uint32_t RCC_AHBENR;
volatile uint32_t RCC_APBENR1;
volatile uint32_t RCC_APBENR2;
volatile uint32_t RCC_IOPSMENR;
volatile uint32_t RCC_AHBSMENR;
volatile uint32_t RCC_APBSMENR1;
volatile uint32_t RCC_APBSMENR2;
volatile uint32_t RCC_CCIPR;
volatile uint32_t RCC_CCIPR2;
volatile uint32_t RCC_BDCR;
volatile uint32_t RCC_CSR;
}RCC_RegDef_t;
#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 RCC ((RCC_RegDef_t*)RCC_BASEADDR)
/*Clock enable Macros for Gpiox peripherals*/
#define GPIOA_PERI_CLOCK_EN() RCC->RCC_IOPENR |=(1<<0);
#define GPIOB_PERI_CLOCK_EN() RCC->RCC_IOPENR |=(1<<1);
#define GPIOC_PERI_CLOCK_EN() RCC->RCC_IOPENR |=(1<<2);
#define GPIOD_PERI_CLOCK_EN() RCC->RCC_IOPENR |=(1<<3);
#define GPIOE_PERI_CLOCK_EN() RCC->RCC_IOPENR |=(1<<4);
#define GPIOF_PERI_CLOCK_EN() RCC->RCC_IOPENR |=(1<<5);
//disable Macros for peripherals
#define GPIOA_PERI_CLOCK_DI()RCC->RCC_IOPENR &= ~(1<<0);
#define GPIOB_PERI_CLOCK_DI() RCC->RCC_IOPENR &= ~(1<<1);
#define GPIOC_PERI_CLOCK_DI() RCC->RCC_IOPENR &= ~(1<<2);
#define GPIOD_PERI_CLOCK_DI() RCC->RCC_IOPENR &= ~(1<<3);
#define GPIOE_PERI_CLOCK_DI() RCC->RCC_IOPENR &= ~(1<<4);
#define GPIOF_PERI_CLOCK_DI() RCC->RCC_IOPENR &= ~(1<<5);
/*Clock disable Macros for sysconf peripheral*/
#define SYSCF_PCLCK_DI() (RCC->APB2ENR &= ~(1<<0));
// to reset GPIOx peripherals
#define GPIOA_REG_RESET() do{(RCC ->AHBRSTR |=( 1<<0)); (RCC ->AHBRSTR &= ~(1<<0));}while(0)
#define GPIOB_REG_RESET() do{(RCC ->AHBRSTR |=( 1<<1)); (RCC ->AHBRSTR &= ~(1<<1));}while(0)
#define GPIOC_REG_RESET() do{(RCC ->AHBRSTR |=( 1<<2)); (RCC ->AHBRSTR &= ~(1<<2));}while(0)
#define GPIOD_REG_RESET() do{(RCC ->AHBRSTR |=( 1<<3)); (RCC ->AHBRSTR &= ~(1<<3));}while(0)
#define GPIOE_REG_RESET() do{(RCC ->AHBRSTR |=( 1<<4)); (RCC ->AHBRSTR &= ~(1<<4));}while(0)
#define GPIOF_REG_RESET() do{(RCC ->AHBRSTR |=( 1<<5)); (RCC ->AHBRSTR &= ~(1<<5));}while(0)
//some generic macros
#define ENABLE 1
#define DISABLE 0
#define SET ENABLE
#define RESET DISABLE
#define GPIO_PIN_SET SET
#define GPIO_PIN_RESET RESET
#endif /* INC_STM32G0XX_H_ *//*
* stm32g0xx_gpio_driver.h
*
* Author: admin
*/
#ifndef INC_STM32G0XX_GPIO_DRIVER_H_
#define INC_STM32G0XX_GPIO_DRIVER_H_
#include "stm32g0xx.h"
typedef struct
{
uint8_t GPIO_PinNumber;
uint8_t GPIO_PinMode;//@GPIO_PIN_MODE
uint8_t GPIO_PinSpeed;//@GPIO_PIN_SPEED
uint8_t GPIO_PinPuPdControl;//@GPIO_PIN_PUPD
uint8_t GPIO_PinOPType;//@GPIO_PIN_OTYPE
uint8_t GPIO_PinAltFunMode;
} GPIO_PinConfig_t;
typedef struct
{
//pointer to hold the base address of the GPIO peripheral
GPIO_RegDef_t *pGPIOx; //hold the base address of the GPIO port to which the pin belongs
GPIO_PinConfig_t GPIO_PinConfig;//holds GPIO pin configuration settings
}GPIO_Handle_t;
//@GPIO_PIN_NUMBER
#define GPIO_PIN_NO_0 0
#define GPIO_PIN_NO_1 1
#define GPIO_PIN_NO_2 2
#define GPIO_PIN_NO_3 3
#define GPIO_PIN_NO_4 4
#define GPIO_PIN_NO_5 5
#define GPIO_PIN_NO_6 6
#define GPIO_PIN_NO_7 7
#define GPIO_PIN_NO_8 8
#define GPIO_PIN_NO_9 9
#define GPIO_PIN_NO_10 10
#define GPIO_PIN_NO_11 11
#define GPIO_PIN_NO_12 12
#define GPIO_PIN_NO_13 13
#define GPIO_PIN_NO_14 14
#define GPIO_PIN_NO_15 15
//@GPIO_PIN_MODES
//GPio possible modes, les 4 premier sont dans documentation (MODER)
#define GPIO_MODE_IN 0 //( sur moder)
#define GPIO_MODE_OUT 1 //( sur moder)
#define GPIO_MODE_ALTFN 2
#define GPIO_MODE_ANALOG 3
//modes en plus
#define GPIO_MODE_IT_FT 4 // Input falling edge pour une interruption
#define GPIO_MODE_IT_RT 5 //rising edge
#define GPIO_MODE_IT_RFT 6 //rising edge falling edge trigger
//possible output types(OTYPEMODER)
//@GPIO_PIN_OTYPE
#define GPIO_OP_TYPE_PP 0//push pull
#define GPIO_OP_TYPE_OD 1//open drain
//possible output speeds(OSPEEDR)
////@GPIO_PIN_SPEED
#define GPIO_SPEED_LOW 0
#define GPIO_SPEED_MEDIUM 1
#define GPIO_SPEED_FAST 2
#define GPIO_SPEED_HIGH 3
//GPIO pin pull up AAND pull down configuration macros
//@GPIO_PIN_PUPD
#define GPIO_NO_PUPD 0
#define GPIO_PU 1
#define GPIO_PD 2/*
* main.c
*
*/
#include "stm32g0xx.h"
#include "stm32g0xx_gpio_driver.h"
void delay(void)
{
for(uint32_t i = 0; i<500000;i++);
}
int main(void)
{
GPIO_Handle_t GpioLed;
GpioLed.pGPIOx = GPIOA;
GpioLed.GPIO_PinConfig.GPIO_PinNumber = GPIO_PIN_NO_5;
GpioLed.GPIO_PinConfig.GPIO_PinSpeed =GPIO_SPEED_FAST;
GpioLed.GPIO_PinConfig.GPIO_PinOPType = GPIO_OP_TYPE_PP;
GpioLed.GPIO_PinConfig.GPIO_PinPuPdControl = GPIO_NO_PUPD;
GPIO_PeriClockControl(GPIOA,ENABLE);
GPIO_Init(&GpioLed);
while(1)
{
GPIO_ToggleOutputPin(GPIOA,GPIO_PIN_NO_5);
delay();
}
return 0;
}image00 : When I try to clear GPIOA MODER register bits, only these one are setted with 0.
image01:the bits corresponding to pin number 5 are not setted with the correct values. (It should be 01)

