Programming GPIOs on STM32F4Discovery Platform

Page 1 sur 49Lecteur de document UniversityLib

Programming GPIOs on STM32F4Discovery Platform

Embedded Systems and Microcontroller Programming · lab

Chapitre 22 Chapitre

PERIPHERIQUE 1: Programmation bas PERIPHERIQUE 1: Programmation bas

niveau des GPIOs

Objectifs

 Utiliser le C embarqué pour:

– Définir les registres relatifs au GPIO par un code en langage C

– Adresser les différents registres

– Manipuler entièrement ou par bits les registres

– Programmer les registres de STM32 par adressage de ses registres en se

référant au mapping de mémoire (Memory Map)

Plateforme embarquée à utiliser: STM32 F4Discovery

4

Architecture de l’STM32

 Architecture de type RISC (Reduced Instructions Set Computer)  Bus des Instructions

et bus des Données sont séparés -> Architecture Harvard.

 CPU CortexM4 fait le calcul à la cadence du Bus (AHB: ARM Hi-Speed Bus).

 Les périphériques, moins rapides, sont montés sur les Bus APB1 et APB2.

 Dans le cas d’un tansfert DMA (Direct Memory Acces) c-à-d d’une adresse mémoire ou

d’un périphérique vers un autre, le DMA devient le maître du bus AHB.

CORTEX-M4 CORTEX-M4 Master 1 Master 1

D-bus

System

I-bus I-bus

B B u u s s M M a a t t r r i i x x

F F / / I I h h s s a a l l F F

FLASH FLASH

SRAM SRAM Slave Slave

GP-DMA GP-DMA Master 2 Master 2

AHB

AHB-APB2 AHB-APB2

AHB-APB1 AHB-APB1

Arbiter

Bridges

APB2

APB1

Peripheral Bus APB2

Peripheral Bus APB1 Peripheral Bus APB1

Architecture détaillée d’un STM32 F40x

CORTEXTM-M4 CPU 24 MHz

JTAG/SW Debug

Nested vect IT Ctrl

1 x Systick Timer

DMA up to 12 Channels

1 x 16-bit PWM Synchronized AC Timer

Up to 16 Ext. ITs

51/80/112 I/Os

1 x SPI

1 x USART/LIN Smartcard/IrDa Modem Control

F

/ I

h s a l F

256KB-512kB Flash Memory

24KB-32kB SRAM

84B Backup Data

FSMC

SRAM/ NOR/ LCD parallel interface

Clock Control

Bridge

ARM® Peripheral Bus

(max 24MHz)

10 x 16-bit Timer

2 x Watchdog (independent & window)

2-channel 12-bit DAC

1 x 12-bit ADC up to 16 channels

Temperature Sensor

s u 6 3 d e e p S

- i

H e t i L ® M R A

) z H M 4 2

Publicité

x a m

(

r e t i b r A

/ x i r t a M

Bridge

s u B

l a r e h p i r e P ® M R A

) z H M 4 2

x a m

(

Power Supply Reg 1.8V POR/PDR/PVD

XTAL oscillators 32KHz + 4~25MHz

Int. RC oscillators 40KHz + 8MHz

PLL

RTC / AWU

1 x CEC

4 x USART/LIN Smartcard / IrDa Modem Control

2 x SPI

2 x I2C

Tools and Software

 Outils de développements

– IAR Embedded Workbench

– kEIL µVision IDE

– Raisonnance Ride7

– MikroC Pro for ARM

– CooCox (riche en exemples)

L’outil à utiliser: http://www.keil.com/uvision/

– Circle OS (couche applicative de l’OS circleOS)

– La plupart des outils sont bâtis autour de CMSIS - Cortex Microcontroller

Software Interface Standard: http://www.keil.com/pack/doc/CMSIS/General/html/index.html

7

 E/S bidirectionnels de STM32

GPIO standard (tolère une valeur de 5v en entrée) et génère une sortie de 3v

GPIOs délivre un courant 25mA

Temps de montée en sorite configurable (max 50 MHz)

Toutes les broches peuvent être programmeés comme entrée analogique

Toutes les broches peuvent être programmeés en fonctions alternés (USARTx, TIMx, I2Cx, SPIx,…)

Toute entrée pourrait être configurée comme source d’interruption

9 ports de GPIO standard (GPIOA..GPIOI) (1 port = 16 broches d’E/S)

Registres de contrôle des GPIOs

 Pour la manipulation des 9 GPIOx(x=A..I), nous avons recours à l’utilisation

des registres de contrôle suivants :

– GPIOx_MODER : registre utilisé pour sélectionner la direction (Entrée ou Sortie),

Fonction alternée et analogique (input, output, AF, analog)

– GPIOx_OTYPER : Registre utilisé pour sélectionner le type de sortie PP(pushpull – GPIOx_OTYPER : Registre utilisé pour sélectionner le type de sortie PP(pushpull

) ou OD (open-drain)

– GPIOx_OSPEEDR : Registre utilisé pour sélectionner la vitesse quelque soit la

direction I/O

– GPIOx_PUPDR : Registre utilisé pour la sélection du mode PU ou PD ( pull-

up/pull-down) quelque soit la direction I/O

Registres des données

– GPIOx_IDR (x=A..I): récupérer les données entrantes du

port x, accédé en lecture seule

– GPIOx_ODR (x=A..I): envoyer les données en sorties du

port x, accédé en écriture et en lecture

Rq: Il existe d’autres registres GPIO non traités dans ce

chapitre

GPIO port mode register (GPIOx_MODER) (x = A..I)

GPIO port output type register (GPIOx_OTYPER) (x = A..I)

GPIO port output speed register (GPIOx_OSPEEDR) (x = A..I)

GPIO port pull-up/pull-down register (GPIOx_PUPDR) (x = A..I/)

Address offset: 0x0C

GPIO port input data register (GPIOx_IDR) (x = A..I)

GPIO port output data register (GPIOx_ODR) (x = A..I)

Les Autres Registres GPIO

 GPIO port bit set/reset register  (GPIOx_BSRR) (x = A..I)

 GPIO port configuration lock register

(GPIOx_LCKR) (x = A..I) (GPIOx_LCKR) (x = A..I)

 GPIO alternate function low register

Publicité

(GPIOx_AFRL) (x = A..I)

GPIO alternate function high register

(GPIOx_AFRH) (x = A..I)

L’adresse d’un registre d’un périphérique donnée est la somme de:  l’adresse de base d’un périphérique  l’adresse d’offset du registre

l’adresse de base du périphérique est définie dans le memory map (Table 10 page 71 du datasheet STM32F40x) (Table 10 page 71 du datasheet STM32F40x)

Les adresses d’offset des registres sont définies dans la description des registres du RM (Table 32 pages 203/204 du fichier « Reference Manual » de STM32F40x)

Remarque: Les adresses de base des GPIOs et d’offset des principaux registres sont présentées par la suite

Memory MAP: Table 10 page 71 du datasheet STM32F40x

Adresses de base des PORTS d’E/S (GPIOs)

@ d’offset des registres GPIOs Table 32 pages 203/204 du « Reference Manual » de STM32F40x

Suite …

Suite …

Exemples de calcul des adresses

Calculer les adresses des registres suivants:

GPIOC_ODR GPIOA_AFRH GPIOB_PUPDR GPIOB_PUPDR

28

Exemples de calcul des adresses

Calculer les adresses des registres suivants:

GPIOC_ODR = GPIOC_BASE + OFFSET_ODR = 0x4002 0800 + 0x14 = 0x4002 0814 = 0x4002 0814

GPIOA_AFRH = GPIOA_BASE + OFFSET_AFRH = 0x4002 0000 + 0x24 = 0x4002 0024

GPIOH_PUPDR = 0x4002 1C00 + 0x0C

= 0x4002 1C0C

29

RCC ( Reset Clock Control) est le contrôleur de la circuiterie de Reset et d’horloge.

Permet de synchroniser les trois bus du Cortex-M4 (AHB, APB1 et APB2) avec le bus interne du système: le bus matrix

Les GPIOs sont montés sur le bus AHB1. Tout GPIO(composant en général) doit être activé par RCC avant utilisation.

L’avantage de RCC est la possibilité d’activer, suivant le besoin de l’application, les composants nécessaires à l’application.

En conséquent, une meilleure gestion de la consommation du système embarqué.

RCC AHB1 peripheral clock enable register (RCC_AHB1ENR)

RCC AHB1 peripheral clock enable register (RCC_AHB1ENR) @ RCC_AHB1ENR = @base_RCC + @offset AHB1ENR  

= 0x4002 3800 + 0x30 = 0x4002 3830

RCC AHB1 peripheral reset register (RCC_AHB1RSTR)

@ RCC_AHB1RSTR = @base_RCC + @offset AHB1RSTR 

= 0x4002 3800 + 0x10 = 0x4002 3810

Ce registre permet de remettre à l’état initial le périphérique à utiliser par une écriture de 1. Suite à cette écriture de 1, il faut écrire 0 pour que le périphérique sorte de son état de reset.

Applications: 4 Leds et Bouton utilisateurs de STM32f4Discovery

TP1: Clignotement de la LED connectée au PD12 connectée au PD12

Principe de programmation des registres (1/5)

Un programme C qui utilise uniquement les registres d’un périphérique pourrait être vu comme étant une fonction des registres mis en jeu.

PROG = f(registres)

La programmation dans ce cas consiste à : La programmation dans ce cas consiste à :

 ETAPE 1: Définir les registres à utiliser: chaque registre est équivalent

à une adresse donc un pointeur en langage C

 ETAPE 2: Initialiser ces pointeurs par les adresses adéquates

 ETAPE 3: Lecture et/ou écriture des contenus des registres

- Lecture: lire l’état du système

- Ecriture: commander le système

Principe de programmation des registres (2/5) ETAPE 1: Définir les adresses des registres

Les périphériques à utiliser dans notre cas sont :

RCC (Reset and Clock Control): pour l’activation de l’horloge

- Le registre à utiliser de l’RCC est RCC_AHB1ENR + RCC_AHB1RSTR

GPIOD: pour commander la broche PD12 connectée au LED4

- Les registres à utiliser du périphérique GPIOD sont MODREG , DOTYPE , DSPEED, PUPPDR et ODR (de même pour les autres)

RCC adresse de base: RCC adresse de base: 0x4002 3800

GPIOD adresse de base: GPIOD adresse de base: @ 0x4002 0C00

AHB1ENR: @offset= 0x30

AHB1RSTR: @offset= 0x10

MODREG : @offset= 0x00

ODR: @offset= 0x14

@ AHB1RSTR = 0x40023810

@ DMODREG = 0x40020C00

@ AHB1ENR = 0x40023830

@DODR= 0x40020C14

Principe de programmation des registres (3/5) ETAPE 2: définir des pointeurs et les initialiser

Définition et initialisation des pointeurs des registres

volatile unsigned int* MODREG = (unsigned int *) 0x40020C00;

volatile unsigned int * DOTYPE = (unsigned int *) 0x40020C04;

volatile unsigned int * DSPEED = (unsigned int *) 0x40020C08;

volatile unsigned int * DODR = (unsigned int *) 0x40020C14; volatile unsigned int * DODR = (unsigned int *) 0x40020C14;

Publicité

volatile unsigned int * PUPPDR = (unsigned int *) 0x40020C0C;

//RCC_AHB1ENR

volatile unsigned int *AHB1_ENR =(unsigned int*) 0x40023830; //RCC_AHB1RSTR volatile unsigned int *AHB1_RSTR =(unsigned int*) 0x40023810;

Remarque: volatile neutralise l’effet de l’optimisation (taille du code + Speed) sur les variables déclarées. Ici les @ des registres.

Principe de programmation des registres (4/5) ETAPE 3: Lecture/écriture dans les registres

Réinitialiser le GPIOD Activer l’horloge de GPIOD

Mettre le Bit3 de AHB1_RSTR à 1 puis 0 Mettre le Bit3 de AHB1_ENR à 1

Configurer la PD12 en mode General Purpose Output Push Pull (GP Output 50 Mhz):

Bits [25-24] Bit [12] =0 Bits [25-24] Bit [12] =0 =01

Bits [25-24] Bits [25-24] =01=50Mhz

Bits [25-24] Bits [25-24] =01

Principe de programmation des registres (4/5) ETAPE 3: Lecture/écriture dans les registres (suite …)

int main() {

// SET GPIOD DENIT

*AHB1_RSTR |= 1<<3;

// RESET GPIOD DENIT

*AHB1_RSTR &= ~(1<<3);

….. …. …. ….. ….. …..

// Enable GPIOD Clock *AHB1_ENR |= 1<<3; *AHB1_ENR |= 1<<3;

// Configuration MODREG

// bits 25-24 = 01 *MODREG &= 0xFCFFFFFF; *MODREG |= 0x01000000; // Bit 12 = 0 *DOTYPE &= ~(1<<12);

// SPEED = 50 Mhz bits 25-24 = 0-1 // SPEED = 50 Mhz bits 25-24 = 0-1

*DSPEED &= 0xFCFFFFFF; *DSPEED |= 0x01000000;

// Bits 25-24 = 00 *PUPPDR &= 0xFCFFFFFF;

Principe de programmation des registres (5/5) ETAPE 3 suite: Lecture/écriture dans les registres

Activer l’état de la sortie PD12 :

Mettre le bit 12 à 1 dans le registre DODR

Insérrer un delay en utilisant la boucle for

Ecriture dans le registre DODR

Désactiver l’état de la sortie PD12 :

Mettre le bit 12 à 0 dans le registre DODR

Insérrer un delay en utilisant la boucle for

Ecriture dans le registre DODR

Principe de programmation des registres (5/5) ETAPE 3: Lecture/écriture dans les registres (suite …)

while(1){

*DODR |= 1<<12; tempo(0xffffff);

*DODR &= ~(1<<12); tempo(0xffffff);

}

Code complet de l’application (1/2)

volatile unsigned int * MODREG = (unsigned int *) 0x40020C00; volatile unsigned int * DOTYPE = (unsigned int *) 0x40020C04; volatile unsigned int * DSPEED = (unsigned int *) 0x40020C08; volatile unsigned int * DODR = (unsigned int *) 0x40020C14; volatile unsigned int * PUPPDR = (unsigned int *) 0x40020C0C;

//RCC_AHB1ENR //RCC_AHB1ENR volatile unsigned int * AHB1_ENR = (unsigned int *) 0x40023830;

//RCC_AHB1RSTR volatile unsigned int * AHB1_RSTR = (unsigned int *) 0x40023810;

void tempo(volatile unsigned int CNT){

for(; CNT > 0 ;CNT --);

}

Code de l’application (2/2)

int main() { // SET GPIOD DENIT

*AHB1_RSTR |= 1<<3; // RESET GPIOD DENIT *AHB1_RSTR &= ~(1<<3);

// Enable GPIOD Clock

*AHB1_ENR |= 1<<3; // Configuration MODREG

// bits 25-24 = 01

*MODREG &= 0xFCFFFFFF; *MODREG |= 0x01000000; // Bit 12 = 0 *DOTYPE &= ~(1<<12);

// SPEED = 50 Mhz bits 25-24 = 0-1 *DSPEED &= 0xFCFFFFFF; *DSPEED |= 0x01000000;

// Bits 25-24 = 00 *PUPPDR &= 0xFCFFFFFF;

while(1){

*DODR |= 1<<12; tempo(0xffffff); *DODR &= ~(1<<12); tempo(0xffffff);

}

}

LEDS en même Clignotez les 4 4 LEDS en même Clignotez les temps? ? temps? ?

Défiler les 4 4 leds Défiler les

leds ??

Utiliser le bouton USER pour Utiliser le bouton USER pour

inverser les leds inverser les

deux à deux à leds deux à deux à

chaque appui ? chaque appui ?