Anda di halaman 1dari 5

Upon any reset event all GPIOs are floating inputs.

This prevents any damage to GPIOs in the


event of emergency.
All GPIO registers are needed to be accessed with 32 bit words. This is mandatory.
Reserved bits for any GPIO register are kept at reset values i.e. 0.
For every GPIO port there are seven registers but the only the first four are the most
important ones.
These important GPIO registers per port are CRL, CRH, IDR and ODR. The rest three registers
for GPIO ports can be avoided at the beginning.
For bit set and for bit clear, operations REGx |= (1 << bit) and REGx &= ~ (1 << bit)
respectively are very handy and efficient.
Some IOs are 5V tolerant and are label FT in datasheets and other docs. The rest of the IOs
are not that tolerant and so 3.3V operation should always be ensured. STM32 has a
maximum VDD tolerance of 4V but this value shouldnt be used in any situation for safe
operation. Best is to avoid 5V use with GPIOs whenever possible. This will help in avoiding
accidental damage to the micro due to common mistakes.
Unused GPIO pins should be kept at reset state or tied to ground with 10k resistors so that
they remain either as floating inputs or safely connected to ground though its not a must.
IO pins can source or sink currents up to 25mA. Thus direct LED drive is possible with them.
CRL/H registers essential set GPIO pin operating mode independently as according to the
table below:

CRL sets GPIOs from 0 7 while CRH sets from 8 15. All IO ports are 16 bit wide unlike
common 8 bit micros like PIC or AVR.
CRL Register:

CRH Register:

As can be seen from port configuration table, right after reset CRL and CRH both have a
value of 0x44444444. This value means floating input mode.
IDR registers are responsible for digital inputs while ODR registers are responsible for digital
outputs. In both registers the upper 16 bits are always kept 0 because GPIOs are 16 bits wide
while their representative registers are 32 bit wide. Thus only the lower 16 nibbles are of
concern. The code writing convention will be 0x0000xxxx for IDRs and ODRs. The upper
nibbles are reserved and thus set as zeroes.
Just like CRL and CRH, IDR and ODR should be accessed as 32 words.
CRL and CRH should be initialized first before using ODR or IDR registers of a GPIO port.
ODR Register:

IDR Register:

Reset values of IDR and ODR are both zero. This ensures initial logic low state for ODR and
float state for IDR.

After each device reset, all peripheral clocks are disabled (except for the SRAM and FLITF).
Before using a peripheral you have to enable its clock in the RCC_AHBENR, RCC_APB1ENR or
RCC_APB2ENR register. These registers are important and should always be set before using
an internal peripheral.
APB2 peripheral clock enable register (RCC_APB2ENR):

APB1 peripheral clock enable register (RCC_APB1ENR):

AHB peripheral clock enable register (RCC_AHBENR):

The above registers should be set first before anything else.


MikroC for ARM has a built-in library for GPIO. Though such libraries are easy to get started
with even without getting an insight of the internal registers, they are both space and
execution time consuming things. Thus for simple works best is avoid them unless their use
makes a big program easy to understand and deal with.

Example program in MikroC for ARM to change the delay time of a blinking LED with a button.
The program will just blink an LED connected to PB15 with an on time and off time of 200ms unless
the button connected to PA0 is pressed. When the button is pressed the delay time is altered to
600ms instead of 200ms. 600ms delay is maintain until the button is released.
A STM32F108C8 micro embedded in a mini ARM development board from LC Technology was use in
this demo.

void setup();
void bit_set(unsigned long *reg, unsigned char bit_value);
void bit_clear(unsigned long *reg, unsigned char bit_value);
unsigned long get_bits(unsigned long *reg, unsigned long mask);
void main()
{
unsigned int dly = 600;
setup();
while(1)
{
if(get_bits(&GPIOA_IDR, 0x00000001))
{
dly = 200;
}
else
{
dly = 600;
}
bit_set(&GPIOB_ODR, 15);
Vdelay_ms(dly);
bit_clear(&GPIOB_ODR, 15);
Vdelay_ms(dly);
};
}
void setup()
{
//Enable clock only for the required peripherals
RCC_APB2ENR = 0x0000000C;
// All IO Control Registers are set to reset state
// to make them floating inputs
GPIOA_CRL = 0x44444444;
GPIOA_CRH = 0x44444444;
GPIOB_CRL = 0x44444444;
GPIOB_CRH = 0x44444444;
GPIOC_CRL = 0x44444444;
GPIOC_CRH = 0x44444444;
GPIOD_CRL = 0x44444444;
GPIOD_CRH = 0x44444444;
//Just clear the bits needed to be changed

//Set registers and chip peripherals

//Button not pressed

//Button pressed

//Write 1 on bit 15 for GPIOB


//Wait for some time
//Write 0 on bit 15 for GPIOB
//Wait for some time

GPIOA_CRL &= 0xFFFFFFF0;


GPIOB_CRH &= 0x0FFFFFFF;
//Set PA0 as pull-up input and PB15 as push-pull output
GPIOA_CRL |= 0x00000008;
GPIOB_CRH |= 0x10000000;
GPIOA_ODR |= 0x00000001;
}
void bit_set(unsigned long *reg, unsigned char bit_value)
{
*reg |= (1 << bit_value);
}
void bit_clear(unsigned long *reg, unsigned char bit_value)
{
*reg &= (~(1 << bit_value));
}
unsigned long get_bits(unsigned long *reg, unsigned long mask)
{
return (*reg & mask);
}

Reference: STM32 Reference Manual


Author: Shawon M. Shahryiar
https://www.facebook.com/groups/microarena/
https://www.facebook.com/MicroArena?ref=hl
sshahryiar@gmail.com
+8801970046495

04.01.2014

Anda mungkin juga menyukai