chap3 gpio addr reg

Post on 01-Feb-2016

92 Views

Category:

Documents

3 Downloads

Preview:

Click to see full reader

DESCRIPTION

STM32F4

TRANSCRIPT

Chapitre 3Chapitre 3

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 -> Archit ecture 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 B us 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.

I-bus

Fla

sh

I/

FFla

sh

I/

F

Bu

sM

atr

ixB

usM

atr

ix

System

D-busCORTEX-M4

Master 1

CORTEX-M4Master 1

GP-DMAMaster 2

GP-DMAMaster 2

SRAMSlave

SRAMSlave

FLASHFLASH

Fla

sh

I/

FFla

sh

I/

F

AHB-APB2AHB-APB2

AHB-APB1AHB-APB1

AHB

Bridges

APB1

APB2

ArbiterPeripheral Bus APB1 Peripheral Bus APB1

Peripheral Bus APB2

Architecture détaillée d’un STM32 F40x

CORTEXTM-M4 CPU24 MHz

FSMCSRAM/ NOR/ LCD parallel interface

JTAG/SW Debug

Power SupplyReg 1.8V

POR/PDR/PVD

DMA

Nested vect IT Ctrl

1 x Systick Timer

AR

M ®

Lite

Hi-S

peed

36u

sM

atrix

/ A

rbite

r (m

ax 2

4MH

z) XTAL oscillators32KHz + 4~25MHz

Int. RC oscillators40KHz + 8MHz

PLL

24KB-32kB SRAM

Fla

sh I/

F

256KB-512kBFlash Memory

84B Backup Data

AR

Per

iphe

ral B

us(m

ax 2

4MH

z)

2 x I2C

4 x USART/LINSmartcard / IrDaModem Control

51/80/112 I/Os

Up to 16 Ext. ITs

DMAup to 12 Channels

1 x USART/LINSmartcard/IrDaModem Control

1 x SPI

Bridge

Bridge

AR

M

Mat

rix /

Arb

iter

RTC / AWU

ARM® Peripheral Bus(max 24MHz)

Clock Control

2-channel 12-bit DAC

1 x 12-bit ADCup to 16 channels

Temperature Sensor

2 x Watchdog(independent & window)

10 x 16-bit Timer

2 x SPI

1 x CEC1 x 16-bit PWM Synchronized AC Timer

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/

7

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

– La plupart des outils sont bâtis autour de CMSIS - C ortex MicrocontrollerSoftware Interface Standard: http://www.keil.com/pack/doc/CMSIS/General/html/ind ex.html

� 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 ) 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 d ans 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)

Address offset: 0x0C

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

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

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

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

� GPIO port configuration lock register�(GPIOx_LCKR ) (x = A..I)

Les Autres Registres GPIO

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

� GPIO alternate function low register �(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 « ReferenceManual » 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 datasheetSTM32F40x

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_ODRGPIOA_AFRHGPIOB_PUPDR

28

GPIOB_PUPDR

Exemples de calcul des adresses

Calculer les adresses des registres suivants:

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

29

= 0x4002 0814

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

GPIOH_PUPDR = 0x4002 1C00 + 0x0C= 0x4002 1C0C

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_AHB1RSTR = @base_RCC + @offset AHB1RSTR� = 0x4002 3800 + 0x10 = 0x4002 3810

RCC AHB1 peripheral reset register(RCC_AHB1RSTR)

�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 PD12connecté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: GPIOD adresse de base:RCC adresse de base:0x4002 3800

AHB1ENR: @offset= 0x30

@ AHB1ENR = 0x40023830

GPIOD adresse de base:@ 0x4002 0C00

MODREG : @offset= 0x00

ODR: @offset= 0x14

@ DMODREG = 0x40020C00

@DODR= 0x40020C14

AHB1RSTR: @offset= 0x10

@ AHB1RSTR = 0x40023810

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;

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

//RCC_AHB1ENR

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

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

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

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

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

Réinitialiser le GPIODActiver l’horloge de GPIOD

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

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

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;

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

// SPEED = 50 Mhz bits 25-24 = 0-1*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;

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

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

Ecriture dans le registre DODR

Désactiver l’état de la sortie PD12 :Mettre le bit 12 à 0 dans le registre EODR

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;

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

//RCC_AHB1ENR//RCC_AHB1ENR

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

//RCC_AHB1ENR

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

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

*DSPEED &= 0xFCFFFFFF;

*DSPEED |= 0x01000000;

// Bits 25-24 = 00

*PUPPDR &= 0xFCFFFFFF;

while(1){// Enable GPIOD Clock

*AHB1_ENR |= 1<<3;

// Configuration MODREG

// bits 25-24 = 01

*MODREG &= 0xFCFFFFFF;

*MODREG |= 0x01000000;

// Bit 12 = 0

*DOTYPE &= ~(1<<12);

while(1){

*DODR |= 1<<12;

tempo(0xffffff);

*DODR &= ~(1<<12);

tempo(0xffffff);

}

}

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

Défiler les 4 Défiler les 4 ledsleds ??

Utiliser le bouton USER pour Utiliser le bouton USER pour inverser les inverser les ledsleds deux à deux à deux à deux à

chaque chaque appui appui ? ?

top related