STM32F100RB processor GPIO notes rev 2 ST Microelectronics company ARM based processors are considered microcontrollers because in addition to the CPU and memory they include timer functions and extensive input and output functions such as A/D, D/A, General Purpose IO (GPIO), USB, SPI, I2C, etc. The STM32F100RB has GPIO ports A, B, C, D. Each port can have up to 16 bits that are connected to physical pins of the IC although only a total of 51 bits are used (limited by the 64 physical pins on the IC). Bits used for each port are: Port A 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12, (13), (14), (15) Port B 0, 1, 2, (3), (4), 5, 6, 7, 8, 9,10, 11, 12, 13, 14, 15 Port C 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 Port D (0), (1), 2 Bits in parenthesis do not default to GPIO and often will be used for other functions such as bits 0 and 1 on Port D default to connect to an external crystal to run the high speed oscillator or to connect an external clock source. See Table 4, page 24 of the STM32F100 reference data sheet for the physical pin numbers associated with each port bit. ARM based microcontrollers use memory mapped I/O to access I/O hardware. Memory addresses (byte addresses) range from 0x00000000 to 0xFFFFFFFF (hexadecimal notation or zero to 4,294,967,295 base 10). The processor has a 32 bit word length or 4 bytes per word meaning that there are 1,073,741,823 word addresses for memory. The word address sequence starts at zero and goes by multiples of four, i.e. 0, 4, 8, 12, 16, etc. To get data from a GPIO port an instruction must be executed that reads data from a memory address and transfers it to a register in the CPU (a load instruction) while writing to a memory address transfers data from a CPU register to hardware at the specified word address (a store instruction does this). Each GPIO port has seven 32-bit registers associated with it (i.e. 7 memory word addresses) that have the following names, function, and address offset within the group: offset name function 0x00 CRL Port configuration register low (port bits 7-0 ) 0x04 CRH Port configuration register high (port bits 15-8) 0x08 IDR Port input data register 0x0C ODR Port output data register 0x10 BSRR Port bit set/reset register 0x14 BRR Port bit reset register 0x18 LCKR Port configuration lock register The base address for each port (i.e. the address of the CRL register for a port) is given in Figure 7 on page 30 of the STM32F100RB data sheet (as shown here) and in table 1 page 36 of the STM32F100 reference manual. Thus the CRL register of port A has an address of 0x40010800.
You should read pages 100 to 105 in the STM32F100 reference manual. The functional description on page 100 is reproduced here Here is a summary of what each of the 7 registers does: CRL - control register, configures the lower 8 bits (of 16) for a port CRH - control register, configures the upper 8 bits (of 16) for a port IDR - read from this register to get 16 bits of data from a port. Read a word and the lower 16 bits are the data. ODR - write a word to this register to output data. The lower 16 bits are output depending on the mode set in the control register. BSRR used to set or reset output port bits. The lower 16 bits of this register are used to set corresponding output port bits to one. The upper 16 bits of this register are used to reset (clear) corresponding output port bits to zero. When a word is written to this register, bit positions with zero will not affect the output port data. Bit positions with a one in them will change the corresponding output port data bit. If a lower bit and a corresponding upper bit are both ones, the set operation takes precedent over resetting. BRR - used to reset (clear) output port bits. The lower 16 bits of this register are used to clear the corresponding output port bits. When a word is written to this register, bit positions with zero will not affect the output port data. Bit positions with a one in them will change the corresponding output port data bit. LCKR this register is used to lock the configuration of the port bits. This register likely will not need to be written to for the class project.
From pages 111 to 114 of the STM32F100 reference manual:
(see page 114 of the STM32F100 reference manual for details on the lock register if needed) Using the GPIO ports To create software for the ENGR-355 project use the blinky.c program as a starting point. Compile it, download to the Discovery board to confirm that the USB download link is working, and then modify it for your application. The setup and header files that come with blinky.c contain definitions for the GPIO registers that can be used. In file stm32f10x.h a data structure named GPIO_TypeDef is defined that identifies the registers for each GPIO port: Since each register is 32 bits or 4 bytes, CRL has an address of 0x00 within the structure, CRH has an address of 0x04, IDR is 0x08, etc.
To arrive at an actual address for a GPIO register the base addresses for peripherals is established (note line 1274 where 0x40000000 is defined): In line 1282 APB2PERIPH_BASE is created and is 0x40100000. Then a base address for each GPIO port is created: The address for the first port A register, i.e. GPIOA_BASE, is thus 0x40100800. A pointer to the start of registers for each port is created like this: The address of a specific port register can then be expressed as GPIOA->CRL for example. In the blinky.c file, an inline function is created to configure GPIO port C for output to two LEDs like this: Four bits (one hex digit) are required to configure each I/O bit as detailed in 7.2.1 and 7.2.2 shown 4 pages back in this document. Note on line 33 above that the configuration for each bit is a hex 3 or 0011 in binary. The lower two bits being ones specifies output mode, maximum speed. The upper two bits specify a push-pull style output circuit (active pull up and active pull down). In line 32 the lower 8 bits are set to zero and then in line 33 the lower 8 bits are set to 0x33.
Example code for driving an LCD display was handed out. This code is for a Freescale KL25Z series ARM processor. Like the STM32F100 it has a 32 bit CPU but the addresses used for peripherals, the registers used and how they work, are different. In the example code for the LCD a data structure and its address are defined somewhat like that described above for the STM32F100 but different names are used for the port registers and the port registers work a little different. Here are the register names and a synopsis of their function: PDDR - Port data direction register. Used to establish if a port pin is an input or output. PDOR - Port data output register. Data, one or zero, written to a pin set for output establishes the output data. PSOR - Port set output register. A 1 written to a bit will cause the output to be a one. PCOR - Port clear output register. A 1 written to a bit will cause the output to be a zero. There are other port registers, but they don t appear in the example. Use the example code to understand the commands and timing needed to communicate with the display but use port and register names defined for the STM32F100.