STM32 Microcontroller- GPIO Driver Development (Part-1)
GPIO Driver Development
There are two files which we need to consider before developing any peripheral.
1.Driver file
2.Application file
Driver File
This is a header file which contains Microcontroller specific details such as:
*The base addresses of various memories present in the microcontroller such as (Flash, SRAM1, SRAM2, ROM, etc).
*The base addresses of various bus domains such as (AHBx domain, APBx domain).
*The base addresses of various peripherals present in different bus domains of the microcontroller.
*Clock Management macros(i.e, clock enable and clock disable micros)
*Interrupts definition.
*Peripheral Register definition structures.
*Peripheral Register bit definition
Define Base Addresses of various memories in the header file
#define FLASH_BASEADDR 0x0800 0000U
#define SRAM1_BASEADDR 0x2000 0000U
#define SRAM2_BASEADDR 0x2000 1C00U
#define ROM_BASEADDR 0x1FFF 0000U
Refer STM32F407 Reference Manual to know the addresses and more detail about the controller.
Define Base Addresses of various bus domains(AHBx, APBx) in the header file
As we discussed in our previous blog, all the memory address will start and end up from 0x0000 0000 to 0xFFFF FFFF. In that Peripherals address starts from location 0x4000 0000, here Peripherals refers to GPIO, ADC, DAC, Timers etc. The Peripheral base is divided into four section they are
- APB1PERIPH_BASE
- APB2PERIPH_BASE
- AHB1PERIPH_BASE
- AHB1PERIPH_BASE
*Different Peripherals are hanging on different buses.
*AHB bus is used for those peripherals which need high speed data communication(e.x, Camera interfaces,GPIO, Ethernet)
*APB bus is used for those peripherals for which low speed communication would suffice.
#define PERIPH_BASE 0x4000 0000U
#define APB1PERIPH_BASE PERIPH_BASE
#define APB2PERIPH_BASE 0x4001 0000U
#define AHB1PERIPH_BASE 0x4002 0000U
#define AHB2PERIPH_BASE 0x5000 0000U
Define Base Addresses of various peripherals in different bus domain in the header file
#define GPIOA_BASEADDR (AHB1PERIPH_BASE + 0x0000)
#define GPIOB_BASEADDR (AHB1PERIPH_BASE + 0x0400)
#define GPIOC_BASEADDR (AHB1PERIPH_BASE + 0x0800)
#define GPIOD_BASEADDR (AHB1PERIPH_BASE + 0x0C00)
#define GPIOE_BASEADDR (AHB1PERIPH_BASE + 0x1000)
#define GPIOF_BASEADDR (AHB1PERIPH_BASE + 0x1400)
#define GPIOG_BASEADDR (AHB1PERIPH_BASE + 0x1800)
#define GPIOH_BASEADDR (AHB1PERIPH_BASE + 0x1C00)
#define GPIOI_BASEADDR (AHB1PERIPH_BASE + 0x2000)
GPIO ports are hanging to the AHB bus and offset has to be added to get the particular GPIO port address. For Ex: GPIOB base address is 0x4002 0400, AHB1 base address is 0x4002 0000. If we add AHB1 base address with 0400 we get GPIOB base address. In the same way, we need to add the peripherals base address, which we are working on. If we are working on SPI peripheral, then need to add the SPI base address.
Define Peripheral structure for the GPIO registers
typedef struct
{
uint32_t MODEER;
uint32_t OTYPER;
uint32_t OSPEEDR;
uint32_t PUPDR;
uint32_t IDR;
uint32_t ODR;
uint32_t BSRR;
uint32_t LCKR;
uint32_t_AFR[2];
}GPIO_RegDef_t;
If we refer to any peripheral, there will be many registers to control, set, and toggle. In order to work with the GPIO peripheral, we need to include all these registers.
GPIO_RegDef_t *pGPIOA = ((GPIO_RegDef_t*)GPIOA_BASEADDR)
In order to access the registers, we have to create a pointer variable and then initialize that pointer variable to the base address of port GPIOA.
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-1208825570894522"
crossorigin="anonymous"></script>
Comments
Post a Comment