[go: up one dir, main page]

0% found this document useful (0 votes)
46 views50 pages

stm32f4 v2

stm32f4 cours

Uploaded by

M. Amin
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
46 views50 pages

stm32f4 v2

stm32f4 cours

Uploaded by

M. Amin
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 50

STM32 F4 Discovery

Ihsen SAAD
Ihsen.saad@enit.rnu.tn

Glossary

 ART Accelerator ™ : ST’s adaptive real-time accelerator


 CMSIS: Cortex™ microcontroller software interface
standard
 MCU: microcontroller unit
 DSC: digital signal controller
 DSP: digital signal processor
 FPU: floating point unit
 RTC: real-time clock
 MPU: memory protection unit
 FSMC: flexible static memory controller
Introduction :

 The STM32F4 microcontroller is designed by the


manufacturer STMicroelectronics with a RISC
architecture 32 bit and an ARM Cortex core.

 It includes several peripherals and memories and other


several improvements with regard to other families.

STM32 F4 series:
Most powerful Cortex-M

Key Features :
STM32F4 versus competitors
(Coremark)

ST’s ART Accelerator™


The adaptive real-time memory accelerator unleashes the Cortex-M4 core’s
maximum processing performance equivalent to 0-wait state execution
Flash up to 168 MHz
Real-time performance
Decompressed
MP3
Access
DMA
User decoder
to the MP3
transfer
interface:
Compressed to
32-bit multi-AHB bus matrix audio
code
DMA data
audio stream
for to
execution
output
transfers
audio stream of
112kByte
by
stage
the
(MP3) SRAM
tocore
decompression
(I2S)
graphical
16kByte
icons
SRAMblock
from Flash
block
to display

STM32F4 features :

- Core: ARM 32-bit Cortex™-M4


CPU,
- Memories : Flash memory,
SRAM memory, Flexible static
memory,..
- LCD parallel interface
- Clock, reset and supply
management
- General-purpose DMA
- Up to 17 timers
- Up to 140 I/O ports
- Up to 15 communication
interfaces : SPI,
I2C,USART,CAN,..
STM32 F4 series
High-performance digital signal controller

Single precision FPU


Ease of use
Better code efficiency
Faster time to market
What is Cortex-M4?
Eliminate scaling and saturation
Easier support for meta-language tools

MCU DSP
Harvard architecture
Ease of use of C
Single-cycle MAC
programming Cortex-M4
Interrupt handling Barrel shifter
Ultra-low power

Superior and innovative peripherals

Audio architecture
HW crypto/hash
PWMs @
Ethernet 168
withMHz
2 USB
andOTG
coprocessor
IEEE 1588v2
2 full2.4
ADC duplex
andMSPS I²S
<1 µA RTC

1
Hardware block diagram
DMA : Direct Memory Access

The devices feature two general-purpose dual-port DMAs (DMA1 and


DMA2) with 8 streams each.
They are able to manage memory-to-memory, peripheral-to-memory and
memory-to-peripheral transfers.
It can be used with the main peripherals :
 SPI and I2C
 USART
 TIMERS
 ADC
 DAC,…

Memories :

 Embedded Flash memory : The STM32F4 microcontroller

embeds a Flash memory of 256 Kbytes, 512 Kbytes, 768 Kbytes

or 1 Mbytes available for storing programs and data.

 Embedded SRAM : The STM32F4 microcontroller embeds up

to 192 Kbytes of system SRAM and 4 Kbytes of backup SRAM.


Maximum integration

 The 1-Mbyte Flash and 192-Kbyte SRAM memories


available in the product accommodate advanced
software stacks and user data, with no need for
external memories

 4-Kbyte SRAM battery back-up: EEPROM used to


save application state, calibration data

 In addition, 528 bytes of OTP memory make it


possible to store critical user data such as
Ethernet MAC addresses or cryptographic keys
1

Multi--AHB bus matrix


Multi

The 32-bit multi-AHB bus matrix interconnects all the masters

(CPU, DMAs, Ethernet, USB) and the slaves (Flash memory,

RAM) and ensures an efficient operation even when several

high-speed peripherals work simultaneously.


Input / Output Peripherals GPIO

The STM32F4 contains100 pins, they are as follows:

 Eight GND pins.

 Two 5V pin.

 Four pins 3V.

 Five I/O ports :A, B, C, D, E and G

External interrupt/event controller


(EXTI)

The external interrupt/event controller consists of 23 edge-

detector lines used to generate interrupt/event requests. Each

line can be independently configured to select the trigger event

(rising edge, falling edge, both)


Inter--integrated circuit interface
Inter
(I²C)

The STM32F4 embeds three I²C bus interfaces that can operate

in multimaster and slave modes. They can support the

Standard- and Fast-modes.

Serial peripheral interface (SPI)

The STM32F4 embeds three SPI bus interfaces in slave and


master modes in full-duplex and simple communication modes,
 The SPI interface specifies 4 signals:
 SCLK :clock.

 MOSI
MOSI:Master Output data, Slave Input data.

 MISO
MISO: Master Input data, Slave Output data.

 SS
SS:Slave Select
Board audio capability

The STM32F4 uses an audio DAC CS43L22 to output sounds.


The STM32F4 controls the audio through the I2C interface and
processes digital signals through analog input signal.

The sound can came independently from different inputs:


ST MEMS microphone MP45DT02
USB connector
Internal memory of the STM32F4

The STM32F4 embeds two 12-bit buffered DACs that can be


used to convert digital signals into analog signal outputs.

Temperature Sensor
The temperature sensor has to generate a voltage that varies

linearly with temperature. The conversion range is between 1.8

V and 3.6 V. The temperature sensor is internally connected to

the ADC1_IN16 input channel which is used to convert the

sensor output voltage into a digital value.


Accelerometer
The stm32f4 contains an accelerometer : LIS302DL which is a
movement sensor. It can detect the movement of the
microcontroller according to the three axes (x, y, z).

STM32 product series


4 product series
STM32 F4 block diagram
Feature highlight
 168 MHz Cortex-M4 CPU
 Floating point unit (FPU)
 ART Accelerator TM
 Multi-level AHB bus matrix
 1-Mbyte Flash,
192-Kbyte SRAM
 1.7 to 3.6 V supply
 RTC: <1 µA typ, sub second
accuracy
 2x full duplex I²S
 3x 12-bit ADC
0.41 µs/2.4 MSPS
 168 MHz timers

STM32 F4 series – applications served

 Points of sale/inventory  Building


management

 Industrial automation  Security/fire/HVAC


and solar panels

 Test and measurement


 Transportation

 Consumer

 Medical
 Communication
STM32F4

GPIO (General Purpose Input Output)


USART (Universal Synchronous Asynchronous Receiver Transmitter)
DAC (Digital to Analog Converter)
DMA (direct Memory Access)
PWM (Pulse Width Modulation)
ADC (Analog to Digital Converter)

System Structure
STM32F4 Discovery schematic

STM32F4 Discovery schematic


STM32F4 Discovery schematic

STM32F4 Discovery schematic


STM32F4 Discovery schematic

STM32F4 Discovery schematic


STM32F40x pin and ball definitions
N° Pin Pin GPIO
21 BOOT0 XX
6 NRST RESET NRST
12 PA0 USER
11 PA1 USART2_RTS/USART4_RX/ETH_RMII_REF_CLK/ETH_MII_RX_CLK/TIM5_CH2/TIMM2_CH2/ADC123_IN1
14 PA2 USART2_TX/TIM5_CH3/TIM9_CH1/TIM2_CH3/ETH_MDIO/ADC123_IN2
13 PA3 USART2_RX/TIM5_CH4/TIM9_CH2/TIM2_CH4/OTG_HS_ULPI_D0/ETH_MII_COL/ADC123_IN3
16 PA4 LRCK/AIN1x SPI1_NSS/SPI3_NSS/USART2_CK/DCMI_HSYNC/OTG_HS_SOF/I2S3_WS/ADC12_IN4/DAC1_OUT
15 PA5 SCL/SPC SPI1_SCK/OTG_HS_ULPI_CK/TIM2_CH1_ETR/TIM8_CHIN/ADC12_IN5/DAC2_OUT
18 PA6 SDO SPI1_MISO/TIM8_BKIN/TIM13_CH1/DCMI_PIXCLK/TIM3_CH1/TIM1_BKIN/ADC12_IN6
17 PA7 SDA/SDI/SDO SPI1_MOSI/TIM8_CH1N/TIM14_CH1TIM3_CH2/ETH_MII_RX_DV/TIM1_CH1N/RMII_CRS_DV/ADC12_IN7
43 PA8 MCO1/USART1_CK/TIM1_CH1/I2C3_SCL/OTG_FS_SOF
44 PA9 USB VBUS GREEN USART1_TX/TIM1_CH2/I2C3_SMBA/DCMI_D0/OTG_FS_VBUS
41 PA10 USB ID USART1_RX/TIM1_CH3/OTG_FS_ID/DCMI_D1
2 PA11 USB DM USART1_CTS/CAN1_RX/TIM1_CH4/OTG_FS_DM
3 PA12 USB DP USART1_RTS/CAN1_TX/TIM1_ETR/OTG_FS_DP
42 PA13 SWDIO JTMS-SWDIO
39 PA14 SWCLK JTCK-SWCLK
40 PA15 JTDI/SPI3_NSS/I2S3_WS/TIM2_CH1_ETR/SPI1_NSS
22 PB0 TIM3_CH3/TIM8_CH2N/OTG_HS_ULPI_D1/ETH_MII_RXD2/TIM1_CH2N/ADC12_IN8
21 PB1 TIM3_CH4/TIM8_CH3N/OTG_HS_ULPI_D2/ETH_MII_RXD3/OTG_HS_INTN/TIM1_CH3N/ADC12_IN9
24 PB2
28 PB3 JTDO/TRACESWO/SPI3_SCK/I2S3_CK/TIM2_CH2/SPI1_SCK
25 PB4 NJTRST/SPI3_MISO/TIM3_CH1/SPI1_MISO/I2S3ext_SD
26 PB5 I2C1_SMBA/CAN2_RX/OTG_HS_ULPI_D7/ETH_PPS_OUT/TIM3_CH2/SPI1_MOSI/SPI3_MOSI/DCMI_D10/I2S3_SD
23 PB6 SCL I2C1_SCL/TIM4_CH1/CAN2_TX/OTG_FS_INTN/DCMI_D5/USART1_TX
24 PB7 I2C1_SDA/FSMC_NL/DCMI_VSYNC/USART1_RX/TIM4_CH2
19 PB8 TIM4_CH3/SDIO_D4/TIM10_CH1/DCMI_D6/OTG_FS_SCL/ETH_MII_TXD3/I2C1_SCL/CAN1_RX
20 PB9 SDA SPI2_NSS/I2S2_WS/TIM4_CH4/TIM11_CH1/OTG_FS_SDA/SDIO_D5/DCMI_D7/I2C1_SDA/CAN1_TX
34 PB10 CLK SPI2_SCK/I2S2_CK/I2C2_SCL/USART3_TX/OTG_HS_ULPI_D3/ETH_MII_RX_ER/OTG_HS_SCL/TIM2_CH3
35 PB11 I2C2_SDA/USART3_RX/OTG_HS_ULPI_D4/ETH_RMII_TX_EN/ETH_MII_TX_EN/OTG_HS_SDA/TIM2_CH4
36 PB12 SPI2_NSS/I2S2_WS/I2C2_SMBA/USART3_CK/TIM1_BKIN/CAN2_RX/OTG_HS_ULPI_D5/ETH_RMII_TXD0/ETH_MII_TXD0/OTG_HS_ID
37 PB13 SPI2_SCK/I2S2_CK/USART3_CTS/TIM1_CH1N/CAN2_TX/OTG_HS_ULPI_D6/ETH_RMII_TXD1/ETH_MII_TXD1/OTG_HS_VBUS
38 PB14 SPI2_MISO/TIM1_CH2N/TIM12_CH1/OTG_HS_DMUSART3_RTS/TIM8_CH2N/I2S2ext_SD
39 PB15 SPI2_MOSI/I2S2_SD/TIM1_CH3N/TIM8_CH3N/TIM12_CH2/OTG_HS_DP
8 PC0 PowerOn OTG_HS_ULPI_STP/ADC123_IN10
7 PC1 ETH_MDC/ADC123_IN11
10 PC2 SPI2_MISO/OTG_HS_ULPI_DIR/TH_MII_TXD2/I2S2ext_SD/ADC123_IN12
9 PC3 DOUT/AIN4x SPI2_MOSI/I2S2_SD/OTG_HS_ULPI_NXT/ETH_MII_TX_CLK/ADC123_IN13
20 PC4 ETH_RMII_RX_D0/ETH_MII_RX_D0/ADC12_IN14

N° Pin Pin GPIO


19 PC5 ETH_RMII_RX_D1/ETH_MII_RX_D1/ADC12_IN15
47 PC6 I2S2_MCK/TIM8_CH1/SDIO_D6/USART6_TX/DCMI_D0/TIM3_CH1
48 PC7 I2S3_MCK/TIM8_CH2/SDIO_D7/USART6_RX/DCMI_D1/TIM3_CH2
45 PC8 MCLK TIM8_CH3/SDIO_D0/TIM3_CH3/USART6_CK/DCMI_D2
46 PC9 I2S_CKIN/MCO2/TIM8_CH4/SDIO_D1/I2C3_SDA/DCMI_D3/TIM3_CH4
37 PC10 SCLK SPI3_SCK/I2S3_CK/UART4_TX/SDIO_D2/DCMI_D8/USART3_TX
38 PC11 UART4_RX/SPI3_MISO/SDIO_D3/DCMI_D4/USART3_RX/I2S3ext_SD
35 PC12 SDIN UART5_TX/SDIO_CK/DCMI_D9/SPI3_MOSI/I2S3_SD/USART3_CK
12 PC13 RTC_AF1
9 PC14 OSC32_IN OSC32_IN
10 PC15 OSC32_OUT OSC32_OUT
36 PD0 FSMC_D2/CAN1_RX
33 PD1 FSMC_D3/CAN1_TX
34 PD2 TIM3_ETR/UART5_RXSDIO_CMD/DCMI_D11
31 PD3 FSMC_CLK/USART2_CTS
32 PD4 FSMC_NOE/USART2_RTS
29 PD5 RESET FSMC_NWE/USART2_TX
30 PD6 OverCurrent FSMC_NWAIT/USART2_RX
27 PD7 RED USART2_CK/FSMC_NE1/FSMC_NCE2
40 PD8 FSMC_D13/USART3_TX
41 PD9 FSMC_D14/USART3_RX
42 PD10 FSMC_D15/USART3_CK
43 PD11 FSMC_A16/USART3_CTS
44 PD12 GREEN FSMC_A17/TIM4_CH1/USART3_RTS
45 PD13 ORANGE FSMC_A18/TIM4_CH2
46 PD14 RED FSMC_D0/TIM4_CH3
47 PD15 BLUE FSMC_D1/TIM4_CH4
17 PE0 INT1 TIM4_ETR/FSMC_NBL0/DCMI_D2
18 PE1 INT2 FSMC_NBL1/DCMI_D3
15 PE2 CS_I2C/SPI TRACECLK/FSMC_A23/ETH_MII_TXD3
16 PE3 TRACED0/FSMC_A19
13 PE4 TRACED1/FSMC_A20/DCMI_D4
14 PE5 TRACED2/FSMC_A21/TIM9_CH1/DCMI_D6
11 PE6 TRACED3/FSMC_A22/TIM9_CH2/DCMI_D7
25 PE7 FSMC_D4/TIM1_ETR
26 PE8 FSMC_D5/TIM1_CH1N
27 PE9 FSMC_D6/TIM1_CH1
28 PE10 FSMC_D7/TIM1_CH2N
29 PE11 FSMC_D8/TIM1_CH2
30 PE12 FSMC_D9/TIM1_CH3N
31 PE13 FSMC_D10/TIM1_CH3
32 PE14 FSMC_D11/TIM1_CH4
33 PE15 FSMC_D12/TIM1_BKIN
7 PH0 OSC_IN OSC_IN
8 PH1 OSC_OUT OSC_OUT
Developement tools

ST has made a list of some of the compilers you can chose


from but I have limited this list to the following five:
 Atollic TrueStudio
 RKit-ARM with Ride7
 Rowley CrossWorks
 IAR Embedded Workbench for ARM
 Keil MDK-ARM with Keil uVision
 CooCox IDE

CooCox IDE free compiler

The CooCox IDE also relies on the GNU GCC compiler which device support
is constantly being updated. The IDE itself is also Eclipse based and it
integrates nicely with many different programmer and debugger adapters, fx the
ST-Link.

The CooCox IDE were released, adding support for the STM32F4 family. This
makes it a great compiler suite for use with the STM32F4-DISCOVERY board.

To use them in CooCox you should simply create a new project with the
booting files and then add all of the sources, including the libraries from lower
level folders. Finally you should remember to add the include paths and
symbols/definitions and you should be good to go.

The CooCox IDE requires the GNU GCC to be installed as a seperate package.
On Windows this is a bit more complicated, though GNU GCC has already
been crosscompiled by many different people.
Download:
http://www.labsud.org/stm32_discovery_coocox_gnuc_arm_codesourcery_decouverte_test/
One time installation and configuration

1. Download ARM GCC


2. Download CoIDE
3. Download STM32 ST-LINK Utility
3. Install ARM GCC
4. Install CoIDE
5. Configure CoIDE to point to ARM GCC
6. Install STM32 ST-LINK Utility
7. Plug in USB cable from PC to ST-LINK on discovery board

CoIDE environment

1. Project explorer view: the project explorer view gives you a view of your current
project.
2. Editor: the editor window your code is displayed and can be edited.
3. Panel pane: in the panel pane extra panels can be stored, normally the Help and
Outline pane can be viewed here.
4. Console and problems view: The console and show status information on
compiling and debugging.
GPIO on the STM32F4 Discovery

General Purpose Input Output (GPIO)

The STM32F407VGT6 has 100 pins, and 80 of them can be


used as general-purpose inputs or outputs. The GPIO pins are
arranged into 5 channels (A, B, C, D, and E), with 16 pins each.
Each channel has a separate clock on the AHB1 bus which must
be enabled to use those pins.

GPIO on the STM32F4 Discovery

Each pin has several qualities that are defined by setting bits in their
corresponding registers:
 Mode: input, output, analog or alternate function (SPI, USB, Timer,
etc.)
 Output type: push-pull or open-drain.
 Output speed: 2MHz, 25MHz, 50MHz or 100MHz.
 Pull-up or pull-down: none, pull-up or pull-down.
 Alternate function low: sets the alternate function for pins 0 – 7.
 Alternate function high: sets the alternate function for pins 8 – 15.

The reset (default) values for most pins are: input, push-pull, 2MHz, no pull-up/down,
AF0. See RM0090 6.4.11 (p.153) for the few exceptions. Good coding practice would
involve resetting the GPIO channel if subsequent code expects the reset values.
Note: Analog pins are not 5V tolerant.
GPIO on the STM32F4 Discovery

Each pin can be used with one of the 15 possible alternate functions
shown in RM0090 Figure 14 (p.141):

GPIO Configuration

The GPIO ports require a clock to


operate, by default this clock is not
connected to the peripheral and
needs to be configured. On the
STM32F4xx the GPIO ports are
connected to the AHB1 bus (the first
out of 3 advanced high-performance
buses). Enabling the clock:

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
GPIO Configuration
From the figure above, the namesake of “open-drain” is
obvious to anyone who is familiar with MOSFETs. A MOSFET
has three terminals called: gate, source, and drain. In an open-
drain configuration, the source is grounded, the gate is driven
internally, and the drain is open (i.e. not connected to anything).

An open-drain output can only sink current. Its two states are
low and high-impedance. When M1 is on, the output is set to
0V. When M1 is off, the output is not driven high nor low. Most
applications, including I2C buses, use an external pull-up
resistor on any open-drain outputs. Another useful application
for open-drain outputs is having multiple external devices drive
a single, active-low interrupt pin on a microcontroller.

GPIO Configuration
The GPIO’s clock can be anything of the following:
 GPIO_Speed_2MHz
 GPIO_Speed_25MHz
 GPIO_Speed_50MHz
 GPIO_Speed_100MHz

On the STM32F4 the GPIO can have up to 4 modes (check the datasheet for which modes
are available for which pin):
 GPIO_Mode_OUT for digital output
 GPIO_Mode_IN for digital input
 GPIO_Mode_AN for analog input
 GPIO_Mode_AF for the alternate functions (like SPI, I²C, USART, …)

The type indicates the hardware configuration of the pin which can be:
 GPIO_OType_PP, a push-pull is driving the output
 GPIO_OType_OD, the output is open-drain

Next we can configure pull up, pull down resistors or nothing at all for each pin:
 GPIO_PuPd_NOPULL, no resistor connected
 GPIO_PuPd_UP, pin is connected to a pull up resistor
 GPIO_PuPd_DOWN, pin is connect to a pull down resistor
GPIO Configuration
Example :
Let us assume that we would like to configure pins 11 and 12 of PortD
as digital outputs at full speed, with a push-pull and no pull up or pull
down:
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOD, &GPIO_InitStructure);

The CooCox GPIO peripheral is a great library for easy setup. The GPIO_InitTypeDef is a
structure defined in the ST’s library and it contains all the properties you can configure on the
corresponding peripheral: Speed, Mode, Type and Pull up/pull down resistors.

Creating the 1st Project


Open CooCox CoIDE and in the start-up screen click on "Create a New Project".
Creating the 1st Project
The next screen will appear and select "Chip" and press the Next button. Finally select
the microprocessor you are working with. In my case I am using the discovery board
so I will select the STM32F407VG chip. Then click the finish button.

Create a first project with blinking leds

In our first project we’ll create a small program that is capable to blink the
four leds on the discovery board and we’ll demonstrate
semihosting. Semihosting is a mechanism that enables code running on
an ARM target to communicate and use the I/O facilities on a host
computer that is running a debugger. In other words send data back over
the ST-LINK back to your computer.

1. Click Create Project and name it Blinker


2. Choose Chip (board could also do if your board is listed)
3. Choose ST and STM32F407VG; click Finish
4. In the Repository window’s Peripherals, click on GPIO (M4 CMSIS Core, CMSIS
BOOT and RCC are auto-selected)
5. Again in the Repository window, click on Semihosting (C Library and Retarget
printf are auto-selected)
Create a first project with blinking leds

Selected Peripherals

Create a first project with blinking leds

Now to get the clock running at desired speed all of this code needs to be called
before the main program starts. This done by editing the startup_stm32f4xx.c file
and uncommenting the SystemInit prototype first:
/*----------Function prototypes-----------------------------------------------*/
extern int main(void); /*!< The entry point for the application. */
extern void SystemInit(void); /*!< Setup the microcontroller system(CMSIS) */
void Default_Reset_Handler(void); /*!< Default reset handler */
static void Default_Handler(void); /*!< Default exception handler */

and then calling it just before main() is called in the Default_Reset_Handler:

#ifdef __FPU_USED
/* Enable FPU.*/
__asm(" LDR.W R0, =0xE000ED88\n"
" LDR R1, [R0]\n"
" ORR R1, R1, #(0xF << 20)\n"
" STR R1, [R0]");
#endif

/* Call the application's entry point.*/


SystemInit();
main();
}
Create a first project with blinking leds

Now your code should run at full speed, this is the first step for every project
you create. Next we want to use the semihosting to send data back over the
debugger to the PC, to achieve this, we must rewrite printf or more concrete its
PrintChar method. Open the printf.c file and edit the PrintChar method and
add a call to SH_SendChar just before the method’s closing bracket (remember
to include the semihosting.h!):
9 #include "semihosting/semihosting.h"
1
0 /**
1 * @brief Transmit a char, if you want to use printf(),
1 * you need implement this function
1 *
2 * @param pStr Storage string.
1 * @param c Character to write.
3 */
1 void PrintChar(char c)
4 {
1 /* Send a char like: To enable the semihosting over the
5 while(Transfer not completed);
1 Transmit a char; debugger, right click your project and
6 */ select ‘Configure’, got to the ‘Debugger’
1 SH_SendChar(c);
tab and enable the check box for
7 }
‘Semihosting Enable’.

Create a first project with blinking leds


This concludes the ‘difficult’ part, now comes the fun part; let’s actually create
some code. Put the following code in your main.c and start the debugger:
#include <stdio.h>
#include "stm32f4xx_rcc.h"
#include "stm32f4xx_gpio.h"

GPIO_InitTypeDef GPIO_InitStruct; If everything went well should see


int main(void) {
all four leds blinking at a pace of
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); about 3 seconds and you should
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_15 | GPIO_Pin_14 | GPIO_Pin_13 see the following output in the
| GPIO_Pin_12;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
semihosting console of CoIDE:
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOD, &GPIO_InitStruct);

printf("Hello World!\r\n");

while (1) {
static int count = 0;
static int i;

for (i = 0; i < 10000000; ++i)


;
GPIO_ToggleBits(GPIOD, GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15);
printf("%d\r\n", ++count);
}
}
Example for GPIO

Description:
This example describes how to toggle the GPIO pins connected on AHB bus.
PD12, PD13, PD14 and PD15 (configured in output pushpull mode) toggles in a
forever loop.
 Set PD12, PD13, PD14 and PD15 by setting corresponding bits in BSRRL register
 Reset PD12, PD13, PD14 and PD15 by setting corresponding bits in BSRRH
register

#include "stm32f4xx_rcc.h"
#include "stm32f4xx_gpio.h«
Example for GPIO
GPIO_InitTypeDef GPIO_InitStructure;
void Delay(__IO uint32_t nCount);
int main(void)
{
SystemInit();
/* GPIOD Periph clock enable */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
/* Configure PD12, PD13, PD14 and PD15 in output pushpull mode */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13| GPIO_Pin_14| GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
Description:
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOD, &GPIO_InitStructure);
This example describes how to toggle the GPIO pins connected on AHB bus.
while(1)
PD12,
{ PD13, PD14 and PD15 (configured in output pushpull mode) toggles in a
/* PD12 to be toggled */
forever loop.
GPIO_SetBits(GPIOD, GPIO_Pin_12); Delay(0x3FFFFF);
 Set /* PD13 to be toggled
PD12, PD13, */ PD14 and PD15 by setting corresponding bits in BSRRL register
GPIO_SetBits(GPIOD, GPIO_Pin_13); Delay(0x3FFFFF);
 Reset /* PD14PD12, PD13,
to be toggled */ PD14 and PD15 by setting corresponding bits in BSRRH
GPIO_SetBits(GPIOD, GPIO_Pin_14); Delay(0x3FFFFF);
register
/* PD15 to be toggled */
GPIO_SetBits(GPIOD, GPIO_Pin_15); Delay(0x7FFFFF);
GPIO_ResetBits(GPIOD, GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15);
Delay(0xFFFFFF);
}
}

void Delay(__IO uint32_t nCount)


{
while(nCount--)
{
}
}
Debugging

In order to debug we need some code from the Simple GPIO example:
#include "stm32f4xx_rcc.h"
#include "stm32f4xx_gpio.h"

int main()

{
// Initialise the peripheral clock.
RCC->AHB1ENR |= RCC_AHB1Periph_GPIOD; Starting the debugger (Ctrl-F5)
// Initialise the GPIO port. changes the IDE context and presents
GPIOD->MODER |= GPIO_Mode_OUT; the debugging interface with the
GPIOD->OSPEEDR |= GPIO_Speed_25MHz; application stopped at the first line of
GPIOD->OTYPER |= GPIO_OType_PP;
GPIOD->PUPDR |= GPIO_PuPd_NOPULL; code:

// Toggle Port D, pin 0 indefinitely.


while (1)
{
GPIOD->BSRRL = GPIO_Pin_0;
GPIOD->BSRRH = GPIO_Pin_0;
}

Debugging Pressing F5 runs the application to the


next breakpoint. As I have not set any
breakpoints
In order to debug we need some code from thethis shouldGPIO
Simple run theexample:
application
indefinitely and indeed it does. Hooking
up the scope to pin 0 of port D shows the
following output:

Single stepping is achieved using F10 and


F11. So re-running the application and
pressing F10 should single step over the
current line of code and indeed it does.
The registers window also highlights the
ARM registers that were changed by
executing the last instruction:
Example : user button
void Initialize_Button()
{
Initialize Button
/* GPIOA Periph clock enable */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
/* Configure PA0 input mode */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}

Initialize_Button(); Main
while(1)
{
if (GPIO_ReadInputDataBit(GPIOA , GPIO_Pin_0)!=0)
{
GPIO_SetBits(GPIOD, GPIO_Pin_12); Delay(1000);
}
else
{
GPIO_ResetBits(GPIOD, GPIO_Pin_12); Delay(1000);
}
}

Example : Robot with ultrasonic sensor (1/2)

Réf : HC-SR04

2cm<distance<4m
Example : Robot with ultrasonic sensor (2/2)

void pulse(void){
functions developeds GPIO_WriteBit(GPIOA,GPIO_Pin_8,Bit_SET);
Wait(15);
GPIO_WriteBit(GPIOA,GPIO_Pin_8,Bit_RESET);
Ultrason.c : }

bool isnewvalue( uint32_t *distance){


if (newvalue){
newvalue = FALSE;
void EXTI3_IRQHandler(void){
*distance = (11*TmpCapteur)/1000;
if (EXTI_GetFlagStatus(EXTI_Line3) != RESET) return TRUE;
{ }
EXTI_ClearFlag(EXTI_Line3); return FALSE;
} }

if (GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_3) == Bit_SET )
{
TIM_Cmd(TIM2,ENABLE);
}
if (GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_3) == Bit_RESET )
{
TIM_Cmd(TIM2,DISABLE);
TmpCapteur=TIM_GetCounter(TIM2);
TIM_SetCounter(TIM2,0);
newvalue = TRUE;
}
}

Example : accelerometer : LIS302DL

exercise #include "stm32_ub_lis302dl.h"


change the code to have: int main(void
 If y> 250 Then LED_RED is On {
LED_RED else is off int16_t x,y,z; SystemInit();
 If y <-250 Then LED_GREEN is UB_LIS302_Init(SCALE_2G); // init
On LED_GREEN else is off while(1)
 If x> 250 Then LED_BLUE is On {
LED_BLUE else is off UB_LIS302_Read(); // read LIS302
 If x<-250 Then LED_ORANGE is x=LIS302.x_achse;
On LED_ORANGE else is off y=LIS302.y_achse;
z=LIS302.z_achse;
}
}
Example : LCD 2 lines x 16 characters 1/2

Example : LCD 2 lines x 16 characters 2/2

lcd_init();
lcd_set_xy(0,0);
lcd_out("Hello World !!");
lcd_set_xy(3,1);
lcd_out("Ihsen SAAD");
Analog--to
Analog to--digital converters (ADCs)

ADC
CHN 1&2 3
# PORT
Three 12-bit analog- 0 PA0 PA0
to-digital converters 1 PA1 PA1
are embedded and 2 PA2 PA2
each ADC shares 3 PA3 PA3
up to 16 external 4 PA4 PF6
channels, 5 PA5 PF7
performing 6 PA6 PF8
conversions in the 7 PA7 PF9
single-shot or scan 8 PB0
mode. In scan 9 PB1 PF3
mode, automatic 10 PC0 PC0
11 PC1 PC1
conversion is
12 PC2 PC2
performed on a
13 PC3 PC3
selected group of 14 PC4 PF4
analog inputs. 15 PC5 PF5
Example: ADC input
AHB1
three 12-bit ADCs

ADC
CHN 1&2 3
# PORT
0 PA0 PA0
1 PA1 PA1
2 PA2 PA2
3 PA3 PA3
4 PA4 PF6
5 PA5 PF7
6 PA6 PF8
APB2

7 PA7 PF9
8 PB0
9 PB1 PF3
10 PC0 PC0
11 PC1 PC1
12 PC2 PC2
13 PC3 PC3
14 PC4 PF4
15 PC5 PF5

Example: ADC input

Configuration
ADC_InitTypeDef ADC_init_structure; //Structure for adc confguration
GPIO_InitTypeDef GPIO_initStructre; //Structure for analog input pin

//Clock configuration
//The ADC1 is connected the APB2 peripheral bus thus we will use its clock source
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
//Clock for the ADC port!! Do not forget about this one ;)
RCC_AHB1PeriphClockCmd(RCC_AHB1ENR_GPIOCEN,ENABLE);

//Analog pin configuration


//The channel 10 is connected to PC0
GPIO_initStructre.GPIO_Pin = GPIO_Pin_0;
//The PC0 pin is configured in analog mode
GPIO_initStructre.GPIO_Mode = GPIO_Mode_AN;
//We don't need any pull up or pull down
GPIO_initStructre.GPIO_PuPd = GPIO_PuPd_NOPULL;
//Affecting the port with the initialization structure
GPIO_Init(GPIOC,&GPIO_initStructre);
//ADC structure configuration
ADC_DeInit();
//data converted will be shifted to right
ADC_init_structure.ADC_DataAlign = ADC_DataAlign_Right;
//Input voltage is converted into a 12bit number giving a maximum value of 4096
ADC_init_structure.ADC_Resolution = ADC_Resolution_8b;
//the conversion is continuous, the input data is converted more than once
ADC_init_structure.ADC_ContinuousConvMode = ENABLE;
// conversion is synchronous with TIM1 and CC1
ADC_init_structure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
//no trigger for conversion
ADC_init_structure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
ADC_init_structure.ADC_NbrOfConversion = 1;
//The scan is configured in one channel
ADC_init_structure.ADC_ScanConvMode = DISABLE;
//Initialize ADC with the previous configuration
ADC_Init(ADC1,&ADC_init_structure);
//Enable ADC conversion
ADC_Cmd(ADC1,ENABLE);
//Select the channel to be read from
ADC_RegularChannelConfig(ADC1,ADC_Channel_10,1,ADC_SampleTime_480Cycles);

int adc_convert(){
ADC_SoftwareStartConv(ADC1);//Start the conversion
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));//Processing the conversion
return ADC_GetConversionValue(ADC1); //Return the converted data
}

Universal synchronous/asynchronous
receiver transmitters (USART)

USART1 The STM32F405xx and STM32F407xx embed


CK PA8 four universal synchronous/asynchronous
TX PA9 PB6 receiver transmitters (USART1, USART2,
RX PA10 PB7
CTS PA11
USART3 and USART6) and two universal
RTS PA12 asynchronous receiver transmitters (UART4 and
USART2 UART5).
CTS PA0 PD3 These six interfaces provide asynchronous
RTS PA1 PD4
TX PA2 PD5
communication, IrDA SIR ENDEC support,
RX PA3 PD6 multiprocessor communicationmode, single-wire
CK PA4 PD7 half-duplex communication mode and
USART3 have LIN Master/Slavecapability. The USART1
TX PB10 PC10 PD8
and USART6 interfaces are able to
RX PB11 PC11 PD9
CK PB12 PC12 PD10 communicate at speeds of up to 10.5 Mbit/s. The
CTS PB13 PD11 other available interfaces communicate at
RTS PB14 PD12 up to 5.25 Mbit/s
Universal synchronous/asynchronous
receiver transmitters (USART)

Example: Bluetooth HC-06(1/3)

CoIDE Setup : CoIDE component


USART3  M4 CMSIS Core
TX PB10 PC10 PD8
 CMSIS BOOT
RX PB11 PC11 PD9
 RCC
CK PB12 PC12 PD10
 GPIO
CTS PB13 PD11
RTS PB14 PD12
 USART
Example: Bluetooth HC-06(2/3)
GPIO_InitTypeDef GPIO_InitStructure; GPIO configuration
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC,ENABLE);
// Configure USART TX/RX as Alternate function
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_Init(GPIOC,&GPIO_InitStructure);
USARTx configured as follow:
// Connect USART pins to AF - BaudRate = 115200 baud
GPIO_PinAFConfig(GPIOC,GPIO_PinSource10,GPIO_AF_USART3); - Word Length = 8 Bits
GPIO_PinAFConfig(GPIOC,GPIO_PinSource11,GPIO_AF_USART3); - One Stop Bit
- No parity
- Hardware flow control disabled
(RTS and CTS signals)
USART configuration - Receive and transmit enabled
USART_InitStructure.USART_BaudRate = 9600;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART3, &USART_InitStructure);
USART_Cmd(USART3, ENABLE);

Example: Bluetooth HC-06(3/3)


int putchar(USART_TypeDef* USARTx, int c){
while (USART_GetFlagStatus(USARTx , USART_FLAG_TXE) == RESET);
USART_SendData(USARTx,c);
//USART1 ->DR = (c & 0xff);
return 0;
}

int getchar(USART_TypeDef* USARTx){


while (USART_GetFlagStatus(USARTx , USART_FLAG_RXNE) == RESET);
return USART_ReceiveData(USARTx);
}

int main(void)
{
Usart3_Config();
char a;

while(1)
{
a=getchar(USART3);
putchar(USART3,a);
}
}
Nested vectored interrupt controller (NVIC)
Interrupts are important in microcontrollers. With them you are able to stop executing
main program and jump to some predefined area if there is something important.
There is an interrupt called each time data arrive to MCU. Different peripheral can
trigger interrupt, like data come to USART, ADC finished conversion, timer overflow,
and more. NVIC is used to dynamically tell which interrupt is more important and for
enabling or disabling interrupts. It supports up to 256 different interrupt vectors.
There are four Data Fields in the InitStructure to set up:
 NVIC_IRQChannel
 NVIC_IRQChannelPreemptionPriority
 NVIC_IRQChannelSubPriority
 NVIC_IRQChannelCmd

Priority can be a value between 0 and 15. A lower value means higher priority. Please
refer to the above mentioned programming manual (DM00046982.PDF, Page
40) for information about Preemption- and SubPriority.
The Stdperiph manual provides a channel list. Timer 1 has four different channels. To
generate an update interrupt we need to use the channel TIM1_UP_TIM10_IRQn.
Priorities are not important because we are not generating more than one interrupt.

This is defined in “misc.h” file in CMSIS pack.


Nested vectored interrupt controller (NVIC)
//USART interrupts are most important
//USART1 is more important than USART2, so it has lower sub priority number
NVIC_InitTypeDef NVIC_InitStruct;

NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;
NVIC_Init(&NVIC_InitStruct);

NVIC_InitStruct.NVIC_IRQChannel = USART2_IRQn;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
NVIC_Init(&NVIC_InitStruct);

//This will handle ALL interrupts which are enabled for USART1
void USART1_IRQHandler(void) {
//Check if interrupt was because data is received
if (USART_GetITStatus(USART1, USART_IT_RXNE)) {
//Do your stuff here

//Clear interrupt flag


USART_ClearITPendingBit(USART1, USART_IT_RXNE);
}
}

Example : USART interruption


void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void USART3_IRQHandler(void)
{
if ((USART3->SR & USART_FLAG_RXNE) != (u16)RESET)
{
incomingByte = USART_ReceiveData(USART3);

if(incomingByte == cmdL) {
GPIO_WriteBit(GPIOD,GPIO_Pin_14,Bit_SET);
GPIO_WriteBit(GPIOD,GPIO_Pin_12,Bit_RESET);// current command
}
else if(incomingByte == cmdR) {
GPIO_WriteBit(GPIOD,GPIO_Pin_14,Bit_RESET);
GPIO_WriteBit(GPIOD,GPIO_Pin_12,Bit_SET);
}
}
}
STM32F4 External interrupts tutorial(1/4)
Each STM32F4 device has 23 external interrupt or event sources. They are split into 2
sections. First interrupt section is for external pins (P0 to P15) on each port, and other section
is for other events, like RTC interrupt, Ethernet interrupt, USB interrupt and so on.

EXTI
GPIOA GPIOB GPIOC GPIOD GPIOE GPIOF GPIOG GPIOH GPIOI GPIOJ GPIOK
LINE
LINE 0 PA0 PB0 PC0 PD0 PE0 PF0 PG0 PH0 PI0 PJ0 PK0
LINE 1 PA1 PB1 PC1 PD1 PE1 PF1 PG1 PH1 PI1 PJ1 PK1
LINE 2 PA2 PB2 PC2 PD2 PE2 PF2 PG2 PH2 PI2 PJ2 PK2
LINE 3 PA3 PB3 PC3 PD3 PE3 PF3 PG3 PH3 PI3 PJ3 PK3
LINE 4 PA4 PB4 PC4 PD4 PE4 PF4 PG4 PH4 PI4 PJ4 PK4
LINE 5 PA5 PB5 PC5 PD5 PE5 PF5 PG5 PH5 PI5 PJ5 PK5
LINE 6 PA6 PB6 PC6 PD6 PE6 PF6 PG6 PH6 PI6 PJ6 PK6
LINE 7 PA7 PB7 PC7 PD7 PE7 PF7 PG7 PH7 PI7 PJ7 PK7
LINE 8 PA8 PB8 PC8 PD8 PE8 PF8 PG8 PH8 PI8 PJ8 PK8
LINE 9 PA9 PB9 PC9 PD9 PE9 PF9 PG9 PH9 PI9 PJ9 PK9
LINE 10 PA10 PB10 PC10 PD10 PE10 PF10 PG10 PH10 PI10 PJ10 PK10
LINE 11 PA11 PB11 PC11 PD11 PE11 PF11 PG11 PH11 PI11 PJ11 PK11
LINE 12 PA12 PB12 PC12 PD12 PE12 PF12 PG12 PH12 PI12 PJ12 PK12
LINE 13 PA13 PB13 PC13 PD13 PE13 PF13 PG13 PH13 PI13 PJ13 PK13
LINE 14 PA14 PB14 PC14 PD14 PE14 PF14 PG14 PH14 PI14 PJ14 PK14
LINE 15 PA15 PB15 PC15 PD15 PE15 PF15 PG15 PH15 PI15 PJ15 PK15

STM32F4 External interrupts tutorial(2/4)


Interrupt lines GPIO as Interrupt
I will show now how to configure GPIO pin to be an interrupt and how to handle it in
your code with CMSIS function.
We have 16 interrupt lines. They are line0 to line15 and they also represent pin
number. This means, PA0 is connected to Line0 and PA13 is connected to Line13.
You have to know that PB0 is also connected to Line0 and PC0 also and so on. This is
for all pins on board, All Px0 (where x is GPIO name) pins are connected to Line0 and
let’s say all Px3 are connected to Line3 on the Interrupt channel.
All pins with same number are connected to line with same number. They are
multiplexed to one line.
IMPORTANT: You can not use two pins on one line simultaneously:
 PA0 and PB0 and PC0 and so on, are connected to Line0, so you can use only one
pin at one time to handle interrupt from there.
 PA0 and PA5 are connected to different lines, they can be used at the same time.
Each line can trigger an interrupt on rising, falling or rising falling edge on signal.
Interrupt handlers
OK, now you have selected your pin you want to use. But you have to handle interrupt
somehow. This process is described below.
STM32F4 External interrupts tutorial(3/4)
GPIO as Interrupt
STM32F4 has 7 interrupt handlers for GPIO pins. They are in table below:
IRQ HANDLER DESCRIPTION
EXTI0_IRQn EXTI0_IRQHandler Handler for pins connected to line 0
EXTI1_IRQn EXTI1_IRQHandler Handler for pins connected to line 1
EXTI2_IRQn EXTI2_IRQHandler Handler for pins connected to line 2
EXTI3_IRQn EXTI3_IRQHandler Handler for pins connected to line 3
EXTI4_IRQn EXTI4_IRQHandler Handler for pins connected to line 4
EXTI9_5_IRQn EXTI9_5_IRQHandler Handler for pins connected to line 5 to 9
EXTI15_10_IRQn EXTI15_10_IRQHandler Handler for pins connected to line 10 to 15

This table show you which IRQ you have to set for NVIC (first column) and function
names to handle your interrupts (second column). You have probably also figured, that
only lines 0 to 4 have own IRQ handler. Yes, lines 5-9 have the same interrupt handler
and this is also for lines 10 to 15.
After you set settings for EXTI, you have to add them into NVIC.

STM32F4 External interrupts tutorial(4/4)


Example #include "stm32f4xx.h"
#include "stm32f4xx_exti.h"
In this example, we will set pin PD0 to be a GPIO interrupts. #include "stm32f4xx_syscfg.h"
/* Configure pins to be interrupts */ #include "misc.h "
GPIO_InitTypeDef GPIO_InitStruct;
EXTI_InitTypeDef EXTI_InitStruct;
NVIC_InitTypeDef NVIC_InitStruct;

/* Enable clock for GPIOD */


RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
/* Enable clock for SYSCFG */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);

/* Set pin as input */


GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_Init(GPIOD, &GPIO_InitStruct);
STM32F4 External interrupts tutorial(4/4)
Example
In this example, we will set pin PD0
/* Tell to be
system that ayou
GPIO interrupts.
will use PD0 for EXTI_Line0 */
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOD, EXTI_PinSource0);

/* PD0 is connected to EXTI_Line0 */


EXTI_InitStruct.EXTI_Line = EXTI_Line0;
/* Enable interrupt */
EXTI_InitStruct.EXTI_LineCmd = ENABLE;
/* Interrupt mode */
EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
/* Triggers on rising and falling edge */
EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
/* Add to EXTI */
EXTI_Init(&EXTI_InitStruct);
/* Add IRQ vector to NVIC */
/* PD0 is connected to EXTI_Line0, which has EXTI0_IRQn vector */
NVIC_InitStruct.NVIC_IRQChannel = EXTI0_IRQn;
/* Set priority */
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x00;
/* Set sub priority */
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0x00;
/* Enable interrupt */
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
/* Add to NVIC */
NVIC_Init(&NVIC_InitStruct);

Timer peripherals

The STM32F4 embeds 14 timers :


 two advanced-control timers,
 eight general-purpose timers,
 two basic timers ,
 two watchdog timers.

There are 14 timers with varying abilities.


(DM00037051, Table 3, p.29)
Timer peripherals
Advanced-control timers (TIM1, TIM8)
The advanced-control timers (TIM1, TIM8) can be seen as three-phase PWM
generators multiplexed on 6 channels. They have complementary PWM outputs with
programmable inserted dead times. They can also be considered as complete general-
purpose timers.
Their 4 independent channels can be used for:
 Input capture
 Output compare
 PWM generation (edge- or center-aligned modes)
 One-pulse mode output
If configured as 16-bit PWM generators, they have full modulation capability (0-
100%).
TIM1 and TIM8 support independent DMA request generation.

Basic timers TIM6 and TIM7


These timers are mainly used for DAC trigger and waveform generation. They can
also be used as a generic 16-bit time base.
TIM6 and TIM7 support independent DMA request generation.

Timer peripherals

General-purpose timers (TIMx)


 TIM2, TIM3, TIM4, TIM5
The STM32F40x include 4 full-featured general-purpose timers. They all feature 4
independent channels for input capture/output compare, PWM or one-pulse mode
output. This gives up to 16 input capture/output compare/PWMs on the largest
packages.
The TIM2, TIM3, TIM4, TIM5 general-purpose timers can work together, or with the
other general-purpose timers and the advanced-control timers TIM1 and TIM8 via the
Timer Link feature for synchronization or event chaining.
Any of these general-purpose timers can be used to generate PWM outputs.
TIM2, TIM3, TIM4, TIM5 all have independent DMA request generation. They are
capable of handling quadrature (incremental) encoder signals and the digital outputs
from 1 to 4 hall-effect sensors.
 TIM9, TIM10, TIM11, TIM12, TIM13, and TIM14
TIM10, TIM11, TIM13, and TIM14 feature one independent channel, whereas TIM9
and TIM12 have two independent channels for input capture/output compare, PWM or
one-pulse mode output. They can be synchronized with the TIM2, TIM3, TIM4, TIM5
full-featured general-purpose timers. They can also be used as simple time bases.
Pin AF 1 AF 2 AF 3 pin and ball definitions
TIM1/2 TIM3/4/5 TIM8/9/10/11
PA0
PA1
TIM2_CH1_ETR
TIM2_CH2
TIM5_CH1
TIM5_CH2
TIM8_ETR Timer
PA2 TIM2_CH3 TIM5_CH3 TIM9_CH1
PPx: Pins Pack 1 to 3, for 3 possible channel outputs
PA3 TIM2_CH4 TIM5_CH4 TIM9_CH2
PA5 TIM2_CH1_ETR TIM8_CH1N on timer.
PA6 TIM1_BKIN TIM3_CH1 TIM8_BKIN
PA7 TIM1_CH1N TIM3_CH2 TIM8_CH1N
PA8 TIM1_CH1
PA9 TIM1_CH2
PA10 TIM1_CH3
PA11 TIM1_CH4
PA12 TIM1_ETR
TIM2_CH1 Pin AF 1 AF 2 AF 3
PA15
TIM2_ETR TIM1/2 TIM3/4/5 TIM8/9/10/11
PB0 TIM1_CH2N TIM3_CH3 TIM8_CH2N PD12 TIM4_CH1
PB1 TIM1_CH3N TIM3_CH4 TIM8_CH3N PD13 TIM4_CH2
PB3 TIM2_CH2 PD14 TIM4_CH3
PB4 TIM3_CH1 PD15 TIM4_CH4
PB5 TIM3_CH2 PE0 TIM4_ETR
PB6 TIM4_CH1 PE5 TIM9_CH1
PB7 TIM4_CH2 PE6 TIM9_CH2
PB8 TIM4_CH3 TIM10_CH1
PE7 TIM1_ETR
PB9 TIM4_CH4 TIM11_CH1
PE8 IM1_CH1N
PB10 TIM2_CH3
PE9 TIM1_CH1
PB11 TIM2_CH4
PE10 TIM1_CH2N
PB12 TIM1_BKIN
PE11 TIM1_CH2
PB13 TIM1_CH1N
PE12 TIM1_CH3N
PB14 TIM1_CH2N TIM8_CH2N
PE13 TIM1_CH3
PB15 TIM1_CH3N TIM8_CH3N
PE14 TIM1_CH4
PC6 TIM3_CH1 TIM8_CH1
PE15 TIM1_BKIN
PC7 TIM3_CH2 TIM8_CH2
PF6 TIM10_CH1
PC8 TIM3_CH3 TIM8_CH3
PF7 TIM11_CH1
PC9 TIM3_CH4 TIM8_CH4

pin and ball definitions


Timer
PPx: Pins Pack 1 to 3, for 3 possible channel outputs
on timer.
CHANNEL 1 CHANNEL 2 CHANNEL 3 CHANNEL 4
ER
PP1 PP2 PP3 PP1 PP2 PP3 PP1 PP2 PP3 PP1 PP2 PP3
TIM 1 PA8 PE9 - PA9 PE10 - PA10 PE13 - PA11 PE14 -
TIM 2 PA0 PA5 PA15 PA1 PB3 - PA2 PB10 - PA3 PB11 -
TIM 3 PA6 PB4 PC6 PA7 PB5 PC7 PB0 PC8 - PB1 PC9 -
TIM 4 PB6 PD12 - PB7 PD13 - PB8 PD14 - PB9 PD15 -
TIM 5 PA0 PH10 - PA1 PH11 - PA2 PH12 - PA3 PI0 -
TIM 8 PC6 PI5 - PC7 PI6 - PC8 PI7 - PC9 PI2 -
TIM 9 PA2 PE5 - PA3 PE6 - - - - - - -
TIM
PB8 PF6 - - - - - - - - - -
10
TIM
PB9 PF7 - - - - - - - - - -
11
TIM
PB14 PH6 - PB15 PH9 - - - - - - -
12
TIM
PA6 PF8 - - - - - - - - - -
13
TIM
PA7 PF9 - - - - - - - - - -
14
Timer Configuration
A hardware timer is essentially an independent counter that counts from zero to its maximum
value at a given speed and generates various events. It runs in the background independently
from your program and its value typically follows the sequence depicted below:
If you look back at the excel spreadsheet,
visually this will show you that RCC_APB1 is
associated with TIM2. Next we need to
configure the timer to trigger every 1
second. To do this we will configure a Count
Up mode. As you can see in the code below
we have set the Prescaler to 42000-1 which
will configure the clock frequency to 84
MHz/42 kHz = 2kHz. Then we will configure
the Count Up timer to trigger on a period of
2000 cycles. Taking our Timer frequency of RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
2kHz / 2000 cycles = 1 second. Then we load // This will configure the clock to 2 kHz
TIM_InitStruct.TIM_Prescaler = 42000 - 1;
the values and enable the TIM2 Timer.
// Count-up timer mode
TIM_InitStruct.TIM_CounterMode = TIM_CounterMode_Up;
// 2 kHz down to 1 Hz = 1 second
TIM_InitStruct.TIM_Period = 2000 - 1;
// Divide clock by 1
TIM_InitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
// Set to 0, not used
TIM_InitStruct.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM2, &TIM_InitStruct);
/* TIM2 enable counter */
TIM_Cmd(TIM2, ENABLE);

Example : green LED to blink with the Timer


Now all we need to do is write some code to monitor the TIM2 Timer so once the Period
expires we toggle the green LED. In this case we could use an interrupt, but I will just
monitor the status of the TIM2 flag. If TIM_FLAG_Update of TIM2 Timer = 1 we know
the period of 2000 has been reached. At this time we can clear the flag and toggle the
green LED.

if (TIM_GetFlagStatus(TIM2, TIM_FLAG_Update) != RESET)


{
TIM_ClearFlag(TIM2, TIM_IT_Update);
GPIO_ToggleBits(GPIOD, GPIO_Pin_12);
}
Example : Using STM32 timers in PWM mode

The STM32 hardware timers are


separate hardware blocks that can
count from 0 to a given value
triggering some events in between.
In the PWM mode the timer
controls the output of 1 or more
output channels. When the counter
value reaches 0, maximum or
a compare value defined for each int period = 500;
void InitializeTimer()
channel, the output value of the {
channel can be changed. Various RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,
ENABLE);
configuration options define which TIM_TimeBaseInitTypeDef timerInitStructure;
events change the value and how it timerInitStructure.TIM_Prescaler = 40000;
timerInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
is changed. timerInitStructure.TIM_Period = period;
timerInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
timerInitStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM4, &timerInitStructure);
TIM_Cmd(TIM4, ENABLE);
}

Example : Using STM32 timers in PWM mode


On the STM32F4Discovery board the
main LEDs are connected to pins PD12-
PD15 having channels 1-4 of timer 4 as
the alternate function #2.

We will now configure the timer to


generate 80% impulses on LED4 (i.e. void InitializePWMChannel()
{
active for 4/5 of the period and TIM_OCInitTypeDef outputChannelInit = {0,};
inactive for the next 1/5). This is outputChannelInit.TIM_OCMode = TIM_OCMode_PWM1;
outputChannelInit.TIM_Pulse = 400;
done by configuring the channel 1 in outputChannelInit.TIM_OutputState = TIM_OutputState_Enable;
the PWM mode with a compare outputChannelInit.TIM_OCPolarity = TIM_OCPolarity_High;
value of 400 (out of period 500) and TIM_OC1Init(TIM4, &outputChannelInit);
selecting alternate function 2 (AF2) TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable);
for the pin PD12: GPIO_PinAFConfig(GPIOD, GPIO_PinSource12, GPIO_AF_TIM4);
void InitializeLEDs() }
{ int main()
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); {
GPIO_InitTypeDef gpioStructure; InitializeLEDs();
gpioStructure.GPIO_Pin = GPIO_Pin_12; InitializeTimer();
InitializePWMChannel();
gpioStructure.GPIO_Mode = GPIO_Mode_AF; for (;;)
gpioStructure.GPIO_Speed = GPIO_Speed_50MHz; {
GPIO_Init(GPIOD, &gpioStructure); }
} }
Example : Using STM32 timers in PWM mode

We can easily configure the timer to generate pulse signal on another channel. The
period will have to be the same, however the compare value can be different:

We will now configure the


void InitializePWMChannel2() timer to generate 20%
{ impulses on LED3 (i.e. active
TIM_OCInitTypeDef outputChannelInit = {0,};
outputChannelInit.TIM_OCMode = TIM_OCMode_PWM1;
for 1/5 of the period and
outputChannelInit.TIM_Pulse = 100; inactive for the next 4/5). This
outputChannelInit.TIM_OutputState = TIM_OutputState_Enable; is done by configuring the
outputChannelInit.TIM_OCPolarity = TIM_OCPolarity_High;
channel 2 in the PWM mode
TIM_OC2Init(TIM4, &outputChannelInit); with a compare value of 100
TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Enable); (out of period 500) and
GPIO_PinAFConfig(GPIOD, GPIO_PinSource13, GPIO_AF_TIM4);
selecting alternate function 2
} (AF2) for the pin PD13:

Research area
Balancing robot with STM32F4

Parallel Robot with STM32F4


development control for quadricopter

Web server

You might also like