4. Objectifs
Utiliser le C embarqué pour:
– Définir les registres relatifs au GPIO dans un code C
– Adresser les différent registres
– Manipuler entièrement ou par bits les registres
– Programmer en dure le STM32 en se référant au mapping de mémoire
7. Architecture de l’STM32
Architecture de type RISC (Reduced Instruction Set Computer) Bus des Instructions
et bus des Données sont séparés -> Architecture Harvard.
CPU CortexM3 fait les calculs à 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 transfert DMA (Direct Memory Acces) c-à-d d’une adresse mémoire
ou d’un périphérique vers une autre adresse, le DMA devient le maître du bus AHB.
BusMatrix
System
D-bus
I-bus
CORTEX-M3
Master 1
GP-DMA
Master 2
SRAM
Slave
FLASH
Flash
I/F
AHB-APB2
AHB-APB1
AHB
Bridges
APB1
APB2
Arbiter
Peripheral Bus APB1
Peripheral Bus APB2
8. Architecture détaillée d’un STM32 F10x
CORTEXTM-M3 CPU
24 MHz
ARM®
Peripheral
Bus
(max
24MHz)
2 x I2C
4 x USART/LIN
Smartcard / IrDa
Modem Control
51/80/112 I/Os
Up to 16 Ext. ITs
FSMC
SRAM/ NOR/ LCD parallel interface
JTAG/SW Debug
Power Supply
Reg 1.8V
POR/PDR/PVD
DMA
up to 12 Channels
Nested vect IT Ctrl
1 x USART/LIN
Smartcard/IrDa
Modem Control
1 x SPI
Bridge
Bridge
1 x Systick Timer
ARM
®
Lite
Hi-Speed
Bus
Matrix
/
Arbiter
(max
24MHz
)
RTC / AWU
ARM® Peripheral Bus
(max 24MHz)
XTAL oscillators
32KHz + 4~25MHz
Int. RC oscillators
40KHz + 8MHz
PLL
24KB-32kB SRAM
Flash
I/F
256KB-512kB
Flash Memory
Clock Control
84B Backup Data
2-channel 12-bit DAC
1 x 12-bit ADC
up to 16 channels
Temperature Sensor
2 x Watchdog
(independent & window)
10 x 16-bit Timer
2 x SPI
1 x CEC
1 x 16-bit PWM
Synchronized AC Timer
9. Tools and Software
8
Outils de développements
– Raisonnance Ride7
– MikroC Pro for ARM
– Circle OS (couche applicative de l’OS circleOS)
Exemples disponibles en :
– www.mikroe.com
– www.stm32circle.com
10.
11. 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
7 ports de GPIO standard (GPIOA..GPIOG) (1 port = 16 broches d’E/S)
12. Bit
Set/Reset
Registers
Input
Data
Register
Output
Data
Register
Read / Write
I/O
pin
Analog Input
Alternate Function Input
Alternate Function Output
To On-chip Peripherals
From On-chip Peripherals
Push-Pull or
Open Drain
TTL Schmitt
Trigger
OUTPUT
CONTROL
ON
VDD or VDD_FT(1)
VSS
VDD
VSS
OFF
0
Input Driver
Output Driver
Read
Configuration Mode CNF1 CNF0 MOD1 MOD0
Input Floating
(Reset State)
0 1
Input Pull-Up(2)
Input Pull-Down(2)
1 0
Output
Push-Pull
0 0
01: 10 MHz
10: 2 MHz
11: 50 MHz
Output
Open-Drain
0 1
AF Push-Pull 1 0
AF
Open-Drain
1 1
Analog Input 0 0
00
Write
ON/OFF
ON/OFF
Pull
-
UP
Pull
-
Down
VDD
VSS
or disabled
(2) Input Pull-Up and Input Pull-Down are
differentiated by the PxODR.y bit
field.
Registre de configuration
GPIOx_CR_L/H
Un GPIO n’est opérationnel que si l’horloge relative est activée
13. Registres des GPIOs
Pour la manipulation des GPIOs, nous avons recours à l’utilisation
des registres suivants:
– Registres de configuration:
• (GPIOx_CRL) (x=A..G): définir le mode de fonctionnement des la partie
LSB (8 pins) du port x.
• (GPIOx_CRH) (x=A..G): définir le mode de fonctionnement de la partie
MSB (8 pins) du port x.
– Registres des données:
• GPIOx_IDR (x=A..G): récupérer les données entrantes du port x
• GPIOx_ODR (x=A..G): envoyer les données en sorties du port x
14. Port configuration register low:
(GPIOx_CRL) (x=A..G)
Bits N° Name Description
Bits 31:30, 27:26,
23:22, 19:18, 15:14,
11:10, 7:6, 3:2
CNFy[1:0]: Port x configuration bits
(y= 0 .. 7)
In input mode (MODE[1:0]=00):
00: Analog mode
01: Floating input (reset state)
10: Input with pull-up / pull-down
11: Reserved
In output mode (MODE[1:0] > 00):
00: General purpose output push-pull
01: General purpose output Open-drain
10: Alternate function output Push-pull
11: Alternate function output Open-drain
Bits 29:28, 25:24,
21:20, 17:16, 13:12,
9:8, 5:4, 1:0
MODEy[1:0]: Port x mode bits
(y= 0 .. 7)
00: Input mode (reset state)
01: Output mode, max speed 10 MHz.
10: Output mode, max speed 2 MHz.
11: Output mode, max speed 50 MHz.
Address offset: 0x00h
Reset Value : 0x4444 4444
15. Port configuration register high
(GPIOx_CRH) (x=A..G)
Bits N° Name Description
Bits 31:30, 27:26,
23:22, 19:18, 15:14,
11:10, 7:6, 3:2
CNFy[1:0]: Port x configuration bits
(y= 8 .. 15)
In input mode (MODE[1:0]=00):
00: Analog mode
01: Floating input (reset state)
10: Input with pull-up / pull-down
11: Reserved
In output mode (MODE[1:0] > 00):
00: General purpose output push-pull
01: General purpose output Open-drain
10: Alternate function output Push-pull
11: Alternate function output Open-drain
Bits 29:28, 25:24,
21:20, 17:16, 13:12,
9:8, 5:4, 1:0
MODEy[1:0]: Port x mode bits
(y= 8 .. 15)
00: Input mode (reset state)
01: Output mode, max speed 10 MHz.
10: Output mode, max speed 2 MHz.
11: Output mode, max speed 50 MHz.
Address offset: 0x04h
Reset Value : 0x4444 4444
16. Port input data register
(GPIOx_IDR) (x=A..G)
Bits N° Name Description
Bits 31:16 Reserved always read as 0.
Bits 15:0 IDRy[15:0]: Port input data (y= 0 .. 15)
These bits are read only and can be accessed in
Word mode only. They contain the input
value of the corresponding I/O port.
Address offset: 0x08h
Reset Value : 0x0000 xxxx
17. Port output data register
(GPIOx_ODR) (x=A..G)
Bits N° Name Description
Bits 31:16 Reserved always read as 0.
Bits 15:0
ODRy[15:0]: Port output data
(y= 0 .. 15)
These bits can be read and written by software and
can be accessed in Word mode only.
Note: For atomic bit set/reset, the ODR bits can be
individually set and cleared by writing to
the GPIOx_BSRR register (x = A .. G).
Address offset: 0x0Ch
Reset Value : 0x0000 0000
18.
19. L’adresse d’un registre d’un périphérique donné 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
(page 34 du datasheet du STM32F103B) (page 38 STM32F103E)
Les adresses d’offset des registres sont définies dans la description
des registres du RM (page 188 de la « Reference Manual » qui est
commun au Primer 1 et 2)
Remarque: Les adresses de base des GPIOs et d’offset des
principaux registres sont présentées par la suite
22. Exemples de calcul des adresses
21
L’adresse du GPIOA_CRL est : 0x4001 0800 + 0x00= 0x4001 0800
L’adresse du GPIOC_LCKR est : 0x4001 1000 + 0x18= 0x4001 1018
23.
24. RCC ( Reset Clock Control) est le contrôleur de la circuiterie de Reset
et d’horloge.
Permet de synchroniser les trois bus du Cortex-M3 (AHB, APB1 et
APB2)
Les GPIOs sont montés sur le bus APB2. 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é.
25.
26. APB2 peripheral clock enable register (RCC_APB2ENR):
Adresse de base du RCC : @ 0x4002 1000 pour Primer2 et Primer 1
Bits N° Name Description
Bits [31:19] Reserved ,must be kept at reset value (0)
Bit 18 TIM17EN
TIM17 Timer clock enable
0: No effect
1: Enable TIM17
Address offset: 0x18h
Reset Value : 0x00000000
… …. …
Bit4 GPIOC
GPIOC clock enable
0: No effect
1: Enable GPIOC
Registre d’activation de l’horloge de GPIO:
RCC_APB2ENR:
27.
28. Application
La carte primer 2 contient deux diodes LEDs connectées
respectivement aux broches PE0 et PE1
Ecrire un programme permettant de clignoter ces deux LEDs ?
29. Principe de programmation des registres (1/4)
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 à :
ETAPE 1: Définir les registres à utiliser: chaque registre est équivalent
à une adresse donc à un pointeur en langage C
ETAPE 2: Initialiser ces pointeurs aux 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
30. Principe de programmation des registres (2/4)
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 du RCC est RCC_APB2ENR
GPIOE: pour commander les broches PE0 et PE1
- Les registres à utiliser du périphérique GPIOE sont CRL et ODR
RCC adresse de base:
@ 0x4002 1000
APB2ENR:
@offset= 0x18
@APB2ENR= 0x40021018
GPIOE adresse de base:
@ 0x4001 1800
CRL: @offset= 0x00
ODR: @offset= 0x0C
@ECRL= 0x40011800
@EODR= 0x4001180C
31. Principe de programmation des registres (3/4)
ETAPE 2: définir des pointeurs et les initialiser
Définition et initialisation des pointeurs des registres
32. Configurer les broches PE0 et PE1 en mode:
General purpose output push-pull
Output mode, max speed 10 MHz
Activer l’état de sortie des broches PE0 et PE1:
Mettre le bit 0 à 1 dans le registre EODR
Mettre le bit 1 à 1 dans le registre EODR
Insérrer un delay en utilisant la boucle for
Désactiver l’état de sortie des broches PE0 et PE1:
Mettre le bit 0 à 0 dans le registre EODR
Mettre le bit 1 à 0 dans le registre EODR
Insérrer un delay en utilisant la boucle for
Principe de programmation des registres (4/4)
ETAPE 3: Lecture/écriture dans les registres
Ecriture dans le
registre ECRL
Ecriture dans le
registre EODR
Ecriture dans le
registre EODR
Ecriture dans le registre APB2_ENR
Activer l’horloge de GPIOE
33. Principe de programmation des registres (4/4)
ETAPE 3: Lecture/écriture dans les registres
Remarque:
volatile
neutralise
l’effet
de
l’optimisation
(taille
du
code
+
Speed)
sur
les
variables
déclarées.
Ici
les
@
des
registres.
34. Code complet de l’application (1/2)
// ETAPE2: Définition des registres par des
pointeurs
volatile unsigned int* ECRL;
volatile unsigned int* EODR;
volatile unsigned int* APB2_ENR;
// Définition du prototype de la fonction de
temporisation
void tempo(volatile unsigned int);
void main() {
// ETAPE2: initialiser les registres par leurs
adresses
APB2_ENR = (unsigned int*) 0x40021018;
ECRL = (unsigned int*) 0x40011800;
35. Code de l’application (2/2)
// ETAPE3: Ecriture dans les registres DATA
(EODR)
while(1) {
*EODR |= 1<<0; // allumer LED0
*EODR |= 1<<1; // allumer LED1
tempo(0xFFFFF); // temporisation
*EODR &= ~(1<<0); // Etteindre LED0
*EODR &= ~(1<<1); // etteindre LED1
tempo(0xFFFFF); // temporisation
} // fin while(1)
} // fin main
// implémentation de la fonction de
temporisation
void tempo(volatile unsigned int CNT){
for(;CNT > 0 ;CNT --);
37. Principe de l’application
La broche PA8 est connectée à un Bouton poussoir sur la carte primer
2.
Clignoter 20 fois les diodes LEDS pilotées par PE0 et PE1 lorsque la
broche PA8 est activée
38. Configurer la broche PA8 en mode Floating input (reset state)
Clignoter 20 fois LED0 et LED1
Tester l’état de la broche PA8:
Si l’état de PA8 égal à 1 :
Si l’état de PA8 égal à 0 on doit rester bloqué dans l’étape de test
Configurer les broches PE0 et PE1 (comme précédement)
Activer l’horloge relative au port A et au port E
Séquencement du programme
Définir les adresses des registres à utilser
39. Code de l’application (1/3)
// Exemple 2: avec Bouton PA8
// ETAPE2: Définition des registres par des
pointeurs
volatile unsigned int* ECRL;
volatile unsigned int* EODR;
volatile unsigned int* APB2_ENR;
volatile unsigned int* AIDR; // pointeur sur
GPIOA_IDR
volatile unsigned int* ACRH; // pointeur sur
GPIOA_CRH
void tempo(volatile unsigned long);
40. Code de l’application (2/3)
void main() {
unsigned int i;
APB2_ENR = (unsigned int*) 0x40021018; // ETAPE2:
initialiser les registres par leurs adresses
ECRL = (unsigned int*) 0x40011800;
EODR = (unsigned int*) 0x4001180C;
AIDR = (unsigned int*) 0x40010808;
ACRH = (unsigned int*) 0x40010804;
* APB2_ENR |= 1<<2; // ETAPE3: Activer l'horloge pour
GPIOA et GPIOE
* APB2_ENR |= 1<<6;
// // ETAPE3: Configurer RE0 et RE1 en mode Output Push-
Pull 10 Mhz
*ECRL = *ECRL & 0xFFFFFF00;
*ECRL = *ECRL | 0x00000011;
// configurer PA8 comme entrée flottante
41. Code de l’application (3/3)
// ETAPE3: Ecriture dans les registres DATA (EODR)
while(1) {
while((*AIDR & 0x100) == 0x00) ;// TEST sur
PA8
for(i=0 ; i<20; i++){
*EODR |= 1<<0; // allumer LED0
*EODR |= 1<<1; // allumer LED1
tempo(0x1FFFFF); // temporisation
*EODR &= ~(1<<0); // Etteindre LED0
*EODR &= ~(1<<1); // Etteindre LED1
tempo(0x1FFFFF); // temporisation
} } // fin while(1)
} // fin main
void tempo(volatile unsigned long CNT) {
for(;CNT > 0 ;CNT --); }
43. Application
Exercice
Utiliser les entrées UP et DOWN du JOYSTICK, pour commander la
diode D4:
- Si l’entrée UP est à 1, D4 est allumée
- Si l’entrée DOWN est à 1, D4 est éteinte
Notes de l'éditeur
Suivant la configuration des bits CNF1, CNF0, MOD1 et MOD0 des registres GPIOx_CR_L et GPIOx_CR_H chaque broche d’un port donnée pourrait être configurée comme suit:
Pour les entrées analogiques le trigger est off l’entrée sera acheminée vers l’ADC
Pou r l’entrée flottante le schmitt est on, n’importe quelle entrée pourrait être capturée (même certains effet électromagnétiques)
Les entrées pull-up et pull-down sont des potentiels fixes par défaut (0 ou 5v).
output push-pull (tension de sortie est soit 0v, soit 3.3v)
Output open drain (tension de sortie varie entre 0 et R.I v) d’où une résistance R doit être ajoutée en sortie.
AF push-pull: Alternate function push-pull. Exemple d’utilisation UART
AF open drain : Alternate function open drain. Exemple d’utilisation bus I2C.
Suivant la configuration des bits CNF1, CNF0, MOD1 et MOD0 des registres GPIOx_CR_L et GPIOx_CR_H chaque broche d’un port donnée pourrait être configurée comme suit:
Pour les entrées analogiques le trigger est off l’entrée sera acheminée vers l’ADC
Pou r l’entrée flottante le schmitt est on, n’importe quelle entrée pourrait être capturée (même certains effet électromagnétiques)
Les entrées pull-up et pull-down sont des potentiels fixes par défaut (0 ou 5v).
output push-pull (tension de sortie est soit 0v, soit 3.3v)
Output open drain (tension de sortie varie entre 0 et R.I v) d’où une résistance R doit être ajoutée en sortie.
AF push-pull: Alternate function push-pull. Exemple d’utilisation UART
AF open drain : Alternate function open drain. Exemple d’utilisation bus I2C.
Le periph RCC est composé de plusieurs registres. Deux registres sont indispensables dans les travaux pratiques:
- RCC_APB2RSTR: permet de réinitialiser les périphs sélectionnées aux valeurs par défaut. Cette action est recommendé avant toute utilisation d’un periph donnée
-