Vous êtes sur la page 1sur 87

Chapitre 3

Les APIs CMSIS des GPIOs

1
Plan

Objectifs
CMSIS ?
Définition des GPIO et registre par CMSIS
Chap3-TP1: utilisation des registres CMSIS
Configuration et sélection des pines
Les APIs CMSIS des GPIOs
APIS CMSIS nécessaires de RCC
TP1_CMSIS

2
Objectifs
Accéder aux registres GPIO (ou Autres) comme
prédéfinis dans la bibliothèque CMSIS

Comprendre les APIs et les utiliser pour programmer


les GPIOs

Générer un projet de configuration par le logiciel


STM32 Cube-MX

3
CMSIS

4
Qu’est-ce que CMSIS

ARM a développé CMSIS: Cortex® Microcontroller Software


Interface Standard

C’est une bibliothèque générique indépendante de l’architecture


matérielle des processeur basés sur Cortex-M

CMSIS Fournit des interfaces logicielles (APIs + Macros+ structures


de données) aux processeurs pour interfacer des périphériques, des
OS temps réels et des Middelwares

Midelwares: Outils d’aide au développement et des logiciels tiers


développés par les utilisateurs et/ou boites de développement pour
faciliter/accélérer le développement

5
Couches de CMSIS

Middelwares Ajoutés par les fabricants qui utilisent CMSIS tels


que ST, NXP, Stellaris(Ti), Atmel, Infineon, AnalogDevices,
freeScale …
pour pouvoir interfacer les périphériques de MCU bâtis à base
6
de Cortex-M
DÉFINITION DES GPIO SOUS
CMSIS

7
Rappel sur le Memory MAP

Adresses de base des


PORTS d’E/S (GPIOs)

8
Comment CMSIS définis les registres ?
 Dans CMSIS on définit une structure sur laquelle pointe les GPIOs de type
GPIO_TypeDef (Périphériques en général: PERIPH_TypeDef).

 L’adresse de chaque structure est l’adresse de base de chaque GPIO


 Un registre sera un champ de la structure. Puisque la taille de chaque champ
est 4 octets, donc automatiquement on trouve les offset des registres % à
cette structure
#define PERIPH_BASE ((uint32_t)0x40000000)
#define AHB1PERIPH_BASE (PERIPH_BASE + 0x00020000)
#define GPIOB_BASE (AHB1PERIPH_BASE + 0x0400)
#define GPIOB ((GPIO_TypeDef *) GPIOB_BASE)

typedef struct{
__IO uint32_t MODER; /* Address offset: 0x00 */
…………….. ………
…………….. ………
__IO uint32_t ODR; /* Address offset: 0x14 */
………………… ……………
} GPIO_TypeDef;
9
Offset des registres GPIOs
 Les offsets sont calculés à partir des tailles des types (uint32_t) qui
sont codées sur 4 octets.

Le premier champ a l’offset 0x00 par rapport l’adresse de la structure et


les autres champs ont des adresses consécutives, incrémentés de 4.
typedef struct{
__IO uint32_t MODER; /* Address offset: 0x00 */
__IO uint32_t OTYPER; /* Address offset: 0x04 */
__IO uint32_t OSPEEDR; /* Address offset: 0x08 */
__IO uint32_t PUPDR; /* Address offset: 0x0C */
__IO uint32_t IDR; /* Address offset: 0x10 */
__IO uint32_t ODR; /* Address offset: 0x14 */
__IO uint16_t BSRRL; /* Address offset: 0x18 */
__IO uint16_t BSRRH; /* Address offset: 0x1A */
__IO uint32_t LCKR; /* Address offset: 0x1C */
__IO uint32_t AFR[2]; /* Address offset: 0x20-0x24 */
} GPIO_TypeDef;
12/11/15 10
Explication des types
Sans CMSIS on définit un registre comme suit:

volatile unsigned int * MODREG;

Avec CMSIS le registre est un champ de la structure


typedef struct{
__IO uint32_t MODER;
….
} GPIO_TypeDef;;

typedef unsigned char uint8_t;


typedef unsigned short uint16_t;
typedef unsigned int uint32_t;

#define __IO volatile


11
Définir les adresses de base des GPIO
A partir du memory map, on définit les adresses de base comme suit:
#define PERIPH_BASE ((uint32_t)0x40000000)
#define AHB1PERIPH_BASE PERIPH_BASE + 0x00020000)
/*!< AHB1 peripherals */
#define GPIOA_BASE AHB1PERIPH_BASE + 0x0000)
#define GPIOB_BASE AHB1PERIPH_BASE + 0x0400)
#define GPIOC_BASE AHB1PERIPH_BASE + 0x0800)
#define GPIOD_BASE AHB1PERIPH_BASE + 0x0C00)
#define GPIOE_BASE AHB1PERIPH_BASE + 0x1000)
#define GPIOF_BASE AHB1PERIPH_BASE + 0x1400)
#define GPIOG_BASE AHB1PERIPH_BASE + 0x1800)
#define GPIOH_BASE AHB1PERIPH_BASE + 0x1C00)
#define GPIOI_BASE AHB1PERIPH_BASE + 0x2000)

12
Définir une macro pour chaque GPIO
Cette macro définit les GPIO comme étant des pointeurs sur la
structure de données définissant les registres (GPIO_TypeDef)

Tenant compte de cette définition, l’accès au différents


registres se fait par l’opérateur de sélection «  ».
Ex: GPIOBMODER = 0x00CF0000;

13
CHAP4_TP1: UTILISATION
DES REGISTRES CMSIS

14
Énoncée
Clignoter la diode LED connectée à PD12 en utilisant les registres
prédéfinis dans CMSIS en modifiant l’exercice du chapitre 2 ci-dessous?
// SPEED = 50 Mhz bits 25-24 = 0-1
int main() { *DSPEED &= 0xFCFFFFFF;
// Enable GPIOD Clock *DSPEED |= 0x01000000;
*AHB1_ENR |= 1<<3;
// Bits 25-24 = 00
// Configuration MODREG
*PUPPDR &= 0xFCFFFFFF;
// bits 25-24 = 01
while(1){
*MODREG &= 0xFCFFFFFF;
*DODR |= 1<<12;
*MODREG |= 0x01000000;
// Bit 12 = 0
tempo(0xffffff);
*DOTYPE &= ~(1<<12); *DODR &= ~(1<<12);
tempo(0xffffff);
}
} 15
Réponse // SPEED = 50 Mhz bits 25-24
int main() { = 0-1
//*DSPEED &= 0xFCFFFFFF;
// Enable GPIOD Clock // GPIOD->OSPEEDR
*DSPEED |= 0x01000000; &= 0xFCFFFFFF;
// *AHB1_ENR |= 1<<3; // remplacer?
....................................................
GPIOD->OSPEEDR |= 0x01000000;
RCC->AHB1ENR |= 1<<3; //CMSIS
………………………………………………..
……………………………………
// Configuration MODREG // bits

25-24 = 01 //GPIOD->PUPDR
*PUPPDR &= 0xFCFFFFFF;
&= 0xFCFFFFFF;
// *MODREG &= 0xFCFFFFFF; ……………………………………….
GPIOD->MODER
…………………………………………. &= 0xFCFFFFFF; while(1){
// *MODREG |= 0x01000000; // *DODR |= 1<<12;
GPIOD->ODR |= 1<<12;
………………………………………….. …………………………………………………….
GPIOD->MODER |= 0x01000000;
// Bit 12 = 0 tempo(0xffffff);
// *DOTYPE &= ~(1<<12); // *DODR &= ~(1<<12);
GPIOD->ODR &= ~(1<<12);
………………………………… ……………………………………
GPIOD->OTYPER &= ~(1<<12);
tempo(0xffffff);
} 16
}
Exécuter et vérifier l’exemple

17
CHAP4_TP2: CLIGNOTEZ LES 4 LEDS
EN MÊME TEMPS EN UTILISANT LES
REGISTRES CMSIS?

18
CHAP4_TP3: DÉFILER LES 4 LEDS EN
UTILISANT LES REGISTRES CMSIS?

19
CHAP4_TP4: UTILISER LE BOUTON
USER POUR INVERSER LES LEDS
DEUX À DEUX À CHAQUE APPUIE (EN
UTILISANT LES REGISTRES CMSIS)?

20
CONFIGURATION ET
SÉLECTION DES PINES

21
Principe
CMSIS définit des structures et des énumérations qui seront
passées en paramètres aux différentes fonctions (APIs)
d’interface lors de la programmation des GPIOs.

La structure de base est: GPIO_InitTypeDef.

Les champs de cette structure sont des énumérations qui


spécifient pour une pine ou un ensemble de pines, la vitesse,
le type de sortie, le type de résistance de Pull et le mode
GPIO utilisé (AF ou GP)

22
La structure GPIO_InitTypeDef

typedef struct{
uint32_t GPIO_Pin;
GPIOMode_TypeDef GPIO_Mode;
GPIOSpeed_TypeDef GPIO_Speed;
GPIOOType_TypeDef GPIO_OType;
GPIOPuPd_TypeDef GPIO_PuPd;

}GPIO_InitTypeDef;

23
Explication des champs de
GPIO_InitTypeDef

24
Paramètre 1: GPIO_Pin
Masques pour la sélection des pines
Les pines sont manipulés par des opérations de masquage (|, &, ! et ^ )
Des masques sont prédéfinis pour toutes les pines d’E/S

25
Masques pour la sélection des pines

(exemple d’utilisation)
GPIOTypeDef* GPIOA;
unsigned char bitstatus;

if ((GPIOA ->IDR & GPIO_Pin_6) != (unsigned int)0x0000)


{
bitstatus = (unsigned char) 1;
}

26
Paramètre 2: GPIOMode_TypeDef
Enumération pour définir les modes d’E/S
Un type énuméré en langage C représente des constantes
enregistrés en mémoire.

Exemple:
GPIOMode_TypeDef mon_mode;
mon_mode = GPIO_Mode_Out;
Ceci est interprété comme étant la valeur 0x01;
27
Paramètre 3: GPIOSpeed_TypeDef
Énumération pour les fréquences de montée en sortie
typedef enum{
GPIO_Speed_2MHz = 0x00,
GPIO_Speed_25MHz = 0x01,
GPIO_Speed_50MHz = 0x02,
GPIO_Speed_100MHz = 0x03
}GPIOSpeed_TypeDef;
 Le langage C interprète le champ GPIO_Speed_50Mhz comme la
valeur 2 et le GPIO_Speed_100Mhz comme la valeur 3.

Les valeurs des champs constants sont incrémentées automatiquement


si la valeur d’un champ n’est pas spécifiée.
28
Paramètre 4: GPIOOType_TypeDef

Énumération qui spécifie si la sortie est push-pull ou Open Drain

typedef enum{
GPIO_OType_PP = 0x00,
GPIO_OType_OD = 0x01
}GPIOOType_TypeDef;

29
Paramètre 5: GPIOPuPd_TypeDef

Énumération qui permet de choisir l’activation ou non des


résistances de pull

typedef enum{
GPIO_PuPd_NOPULL = 0x00,
GPIO_PuPd_UP = 0x01,
GPIO_PuPd_DOWN = 0x02
}GPIOPuPd_TypeDef;

30
Comment utiliser cette structure ?
On définit une variable de type cette structure

On remplie les champs de la structure

On passe la variable structure à la fonction de configuration


prédéfinie par CMSIS

31
Exemple: Configurer PC8 et PC9 en mode
Output Push pull avec un speed de 25MHz
typedef struct{
uint32_t GPIO_Pin;
GPIOMode_TypeDef GPIO_Mode;
GPIOSpeed_TypeDef GPIO_Speed;
GPIOOType_TypeDef GPIO_OType;
GPIOPuPd_TypeDef GPIO_PuPd;
}GPIO_InitTypeDef;

GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz ;
GPIO_InitStructure.GPIO_Otype = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
// appel de pilote de config
gpio_init(GPIOC, & GPIO_InitStructure);
32
LES APIS CMSIS DES GPIOS

33
Les 14 APIS CMSIS pour GPIO
Toutes les définitions précédentes, ainsi que La déclaration des différentes
fonctions sont faites dans le fichier stm32f4xx_gpio.h
L’implémentation est faite dans le fichier stm32f4xx_gpio.c

Les fonctions sont classées comme suit:


 Les APIS de configuration et d’initialisation: GPIO_DeInit,
GPIO_Init, GPIO_StructInit et GPIO_PinLockConfig

 Les APIs de lecture et d’écriture: GPIO_ReadInputDataBit,


GPIO_ReadInputData,G PIO_ReadOutputDataBit,
GPIO_ReadOutputData, GPIO_SetBits, GPIO_ResetBits,
GPIO_WriteBit, GPIO_Write et GPIO_ToggleBits

 L’API de configuration des fonctions alternées: GPIO_PinAFConfig

34
API1: GPIO_DeInit

35
API1: GPIO_DeInit
void GPIO_DeInit(GPIO_TypeDef* GPIOx);

/**
*@brief Deinitializes the GPIOx registers to their default reset values.
*@note By default, The GPIO pins are configured in input floating mode
*@param GPIOx: where x can be (A..I) to select the GPIO peripheral.
* @retval None
*/

 Cette fonction permet de remettre tous les registres des GPIO à l’état de
reset par appel à la fonction RCC_AHB1PeriphResetCmd du
périphérique RCC (reset and clock control).
Cette dernière opère sur le registre RSTR par la mise du bit correspondant
à 0 puis à 1.
RCC->AHB1RSTR |= 1<<3; RCC->AHB1RSTR &= ~(1<<3);
Exercice: Vérifier ceci sur keil
36
API1: GPIO_DeInit, Corps de l’API
void GPIO_DeInit (GPIO_TypeDef* GPIOx){
/* Check the parameters */
assert_param(IS_GPIO_ALL_PERIPH(GPIOx));

if (GPIOx == GPIOA) {
RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOA, ENABLE);
RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOA, DISABLE);
}
else if (GPIOx == GPIOB) {
RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOB, ENABLE);
RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOB, DISABLE);
}
else if (GPIOx == GPIOC)
…….
…..
}
}
37
API2: GPIO_Init (GPIO_TypeDef* GPIOx,

GPIO_InitTypeDef* GPIO_InitStruct)

38
API2: GPIO_Init
void GPIO_Init (GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)
/**
*@brief Initializes the GPIOx peripheral according to the specified parameters in the
GPIO_InitStruct.
*@param GPIOx: where x can be (A..I) to select the GPIO peripheral.
*@param GPIO_InitStruct: pointer to a GPIO_InitTypeDef structure that contains
* @retval None
*/

 Cette fonction permet d’initialiser le GPIO comme spécifié dans la


variable GPIO_InitStruct. Qui doit être remplie en suivant la démarches de
la section précédente
Exercice: Vérifier ceci sur keil

39
API2: GPIO_Init, extrait de code
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)
{
uint32_t pinpos = 0x00, pos = 0x00 , currentpin = 0x00;
currentpin = (GPIO_InitStruct->GPIO_Pin) & pos;
if (currentpin == pos) {
GPIOx->MODER &= ~(GPIO_MODER_MODER0 << (pinpos * 2));
GPIOx->MODER |=(((uint32_t)GPIO_InitStruct->GPIO_Mode)<<(pinpos*2));
…………………………………. ……………………….. ……………………….
/* Speed mode configuration */
GPIOx->OSPEEDR &= ~(GPIO_OSPEEDER_OSPEEDR0 << (pinpos * 2));
GPIOx->OSPEEDR |= ((uint32_t)(GPIO_InitStruct->GPIO_Speed)<<(pinpos*2));

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


GPIOx->PUPDR &= ~(GPIO_PUPDR_PUPDR0 << ((uint16_t)pinpos * 2));
GPIOx->PUPDR |= (((uint32_t)GPIO_InitStruct->GPIO_PuPd) <<(pinpos * 2));
…………………………………. ……………………….. ……………………….
}

40
API3: void GPIO_StructInit (GPIO_InitTypeDef* GPIO_InitStruct)

41
API3: GPIO_StructInit
void GPIO_StructInit (GPIO_InitTypeDef* GPIO_InitStruct)
/**
*@brief Fills each GPIO_InitStruct member with its default value.
*@param GPIO_InitStruct: pointer to a GPIO_InitTypeDef structure which will be
initialized.
* @retval None
*/

 Cette fonction permet de remettre la structure passé en paramètre à la


fonction GPIO_Init à sa valeur par défaut. Ceci est important lorsque on
veut configurer deux GPIO différents en utilisant la même variable
GPIO_InitStruct
Exercice: Vérifier ceci sur keil

42
API3: GPIO_StructInit, le code
void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct){
/* Reset GPIO init structure parameters values */
GPIO_InitStruct->GPIO_Pin = GPIO_Pin_All;
GPIO_InitStruct->GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStruct->GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStruct->GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct->GPIO_PuPd = GPIO_PuPd_NOPULL;
}

43
API4:
uint8_t GPIO_ReadInputDataBit( GPIO_TypeDef* GPIOx,
uint16_t GPIO_Pin)

44
API4: GPIO_ReadInputDataBit
uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
/**
* @brief Reads the specified input port pin.
* @param GPIOx: where x can be (A..I) to select the GPIO peripheral.
* @param GPIO_Pin: specifies the port bit to read. This parameter can be
GPIO_Pin_x where x can be (0..15).
* @retval The input port pin value.
*/

 Cette fonction permet de lire la valeur numérique sur la pine configurée


en entrée appartenant au port passé comme deuxième paramètre.

C’est la valeur du bit lue à partir du registre IDR du GPIO en question


Exercice: Vérifier ceci sur keil

45
API4: GPIO_ReadInputDataBit code
uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx,
uint16_t GPIO_Pin)
{
uint8_t bitstatus = 0x00;
/* Check the parameters */
assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
assert_param(IS_GET_GPIO_PIN(GPIO_Pin));
if ((GPIOx->IDR & GPIO_Pin) != (uint32_t)Bit_RESET)
{
bitstatus = (uint8_t)Bit_SET;
} else {
bitstatus = (uint8_t)Bit_RESET;
}
return bitstatus; typedef enum {
} Bit_RESET = 0,
Bit_SET
46
} BitAction;
API 5:
uint16_t GPIO_ReadInputData (GPIO_TypeDef* GPIOx)

47
API5: GPIO_ReadInputData
uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx)
/**
* @brief Reads the specified GPIO input data port.
* @param GPIOx: where x can be (A..I) to select the GPIO peripheral.
* @retval The input port pin value.
*/

 Cette fonction permet de lire la valeur numérique sur le port configuré en


entrée passé comme deuxième paramètre.
Exercice: Vérifier ceci sur keil

48
API5: GPIO_ReadInputData le code

uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx){


/* Check the parameters */
assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
return ((uint16_t)GPIOx->IDR);
}

49
API6:
uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)

50
API6: GPIO_ReadOutputDataBit
uint8_t GPIO_ReadOutputDataBit (GPIO_TypeDef* GPIOx, uint16_t
GPIO_Pin)
/**
* @brief Reads the specified Output port pin.
* @param GPIOx: where x can be (A..I) to select the GPIO peripheral.
* @param GPIO_Pin: specifies the port bit to read. This parameter can be
GPIO_Pin_x where x can be (0..15).
* @retval The Output port pin value.
*/

 Cette fonction permet de lire la valeur numérique sur la pine configurée


en sortie appartenant au port passé comme deuxième paramètre. C’est la
valeur du bit lue à partir dur registre ODR du GPIO en question.

 C’est le même traitement que GPIO_ReadInputDataBit sauf que


celui là traite le cas de l’ODR à la place de l’IDR
Exercice: Vérifier ceci sur keil
51
API6: GPIO_ReadOutputDataBit,
uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx,
uint16_t GPIO_Pin)
{
uint8_t bitstatus = 0x00;
/* Check the parameters */
assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
assert_param(IS_GET_GPIO_PIN(GPIO_Pin));
if ((GPIOx->ODR & GPIO_Pin) != (uint32_t)Bit_RESET)
{
bitstatus = (uint8_t)Bit_SET;
} else {
bitstatus = (uint8_t)Bit_RESET;
} typedef enum {
return bitstatus;
Bit_RESET = 0,
}
Bit_SET
} BitAction; 52
API7:
uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx)

53
API7: GPIO_ReadOutputData
uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx)
/**
* @brief Reads the specified GPIO Output data port.
* @param GPIOx: where x can be (A..I) to select the GPIO peripheral.
* @retval The Output port pin value.
*/

 Cette fonction permet de lire la valeur numérique sur le port configuré en


sortie passé en paramètre.
Exercice: Vérifier ceci sur keil

54
API7: GPIO_ReadOutputData le
code

uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx){


/* Check the parameters */
assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
return ((uint16_t)GPIOx->ODR);
}

55
API8:

void GPIO_SetBits (GPIO_TypeDef* GPIOx, uint16_t PIO_Pin)

56
API8: GPIO_SetBits
void GPIO_SetBits (GPIO_TypeDef* GPIOx,
uint16_t GPIO_Pin)
/** @brief Sets the selected data port bits.
* @note This functions uses GPIOx_BSRR register to allow atomic read/modify
* accesses. In this way, there is no risk of an IRQ occurring between the
read and the modify access.
* @param GPIOx: where x can be (A..I) to select the GPIO peripheral.
* @param GPIO_Pin: specifies the port bit to read. This parameter can be any
combination GPIO_Pin_x where x can be (0..15).
* @retval None.
*/

 Cette fonction permet de positionner à 1 la pine passée en paramètre


lorsqu’elle est configurée en sortie. C’est l’équivalent d’écrire 1 dans le bit
du registre ODR correspondant de façon atomique.
Exercice: Vérifier ceci sur keil
57
API8: GPIO_SetBits le code
void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
{
/* Check the parameters */
assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
assert_param(IS_GPIO_PIN(GPIO_Pin));
GPIOx->BSRRL = GPIO_Pin;
}

58
API9:
void GPIO_ResetBits (GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)

59
API9: GPIO_ResetBits
void GPIO_ResetBits (GPIO_TypeDef* GPIOx,
uint16_t GPIO_Pin)
/** @brief Clears the selected data port bits.
* @note This functions uses GPIOx_BSRR register to allow atomic read/modify
* accesses. In this way, there is no risk of an IRQ occurring between the
read and the modify access.
* @param GPIOx: where x can be (A..I) to select the GPIO peripheral.
* @param GPIO_Pin: specifies the port bit to read. This parameter can be any
combination of GPIO_Pin_x where x can be (0..15).
* @retval None.
*/

 Cette fonction permet de positionner à 0 la pine passée en paramètre


lorsqu’elle est configurée en sortie. C’est l’équivalent d’écrire 0 dans le bit
du registre ODR correspondant de façon atomique.
Exercice: Vérifier ceci sur keil
60
API8: GPIO_ResetBits le code
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
{
/* Check the parameters */
assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
assert_param(IS_GPIO_PIN(GPIO_Pin));
GPIOx->BSRRH = GPIO_Pin;
}

61
API#10: void GPIO_WriteBit (GPIO_TypeDef* GPIOx,
uint16_t GPIO_Pin, BitAction BitVal)

62
API#10: GPIO_WriteBit

 Cette fonction permet de positionner à 1 ou à 0 la pine passée en


paramètre lorsqu’elle est configurée en sortie. C’est une écriture d’une
valeur passée en paramètre dans le registre ODR à la position BitVal
Exercice: Vérifier ceci sur keil

63
API #10: GPIO_ResetBits le code
void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t
GPIO_Pin, BitAction BitVal)
{
/* Check the parameters */
assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
assert_param(IS_GET_GPIO_PIN(GPIO_Pin));
assert_param(IS_GPIO_BIT_ACTION(BitVal));
if (BitVal != Bit_RESET) {
GPIOx->BSRRL = GPIO_Pin;
} else {
GPIOx->BSRRH = GPIO_Pin ;
} typedef enum {
} Bit_RESET = 0,
Bit_SET
} BitAction; 64
API#11:
void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal)

65
API#11: GPIO_WriteBit
void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal)

/**
• @brief Writes data to the specified GPIO data port.
• * @param GPIOx: where x can be (A..I) to select the
GPIO peripheral.
• * @param PortVal: specifies the value to be written
to the port output data register.
• * @retval None */

 écrit la valeur PortVal dans le registre ODR du port passé en


paramètre
Exercice: Vérifier ceci sur keil

66
API #11: GPIO_WriteBit le code

void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t


PortVal)
{
/* Check the parameters */
assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
GPIOx->ODR = PortVal;
}

67
API#12:
void GPIO_ToggleBits (GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)

68
API#12: GPIO_ToggleBits
void GPIO_ToggleBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
/**
* @brief Toggles the specified GPIO pins...
* @param GPIOx: where x can be (A..I) to select the GPIO peripheral.
* @param GPIO_Pin: specifies the port bits to be toggled. This parameter can be
any combination of GPIO_Pin_x where x can be (0..15).
* @retval None.
*/

 Cette fonction permet d’inverser l’état des bits appartenant au registre


ODR du port GPIOx. L’état des pines configurées en sortie correspondante
seront inversés.
Exercice: Vérifier ceci sur keil

69
API#12: GPIO_ToggleBits ,

void GPIO_ToggleBits(GPIO_TypeDef* GPIOx,


uint16_t GPIO_Pin)
{
/* Check the parameters */
assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
GPIOx->ODR ^= GPIO_Pin;
}

70
API#13:

void GPIO_PinAFConfig (GPIO_TypeDef* GPIOx, uint16_t GPIO_PinSource,


uint8_t GPIO_AF)

71
API#13: GPIO_PinAFConfig
void GPIO_PinAFConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_PinSource, uint8_t
GPIO_AF)
/**
* @brief Changes the mapping of the specified pin.
* @param GPIOx: where x can be (A..I) to select the GPIO peripheral.
* @param GPIO_PinSource: specifies the pin for the Alternate function.
* This parameter can be GPIO_PinSourcex where x can be (0..15).
* @param GPIO_AFSelection: selects the pin to used as Alternate function.
* @retval None.
*/

 Cette fonction opère sur les deux registres AFR pour connecter une pine
à la fonction alternée adéquate.
 Elle sera étudiée ultérieurement

72
API#13: GPIO_PinAFConfig

void GPIO_PinAFConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_PinSource, uint8_t


GPIO_AF)
{
uint32_t temp = 0x00; uint32_t temp_2 = 0x00;
/* Check the parameters */
assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
assert_param(IS_GPIO_PIN_SOURCE(GPIO_PinSource));
assert_param(IS_GPIO_AF(GPIO_AF));
temp = ((uint32_t)(GPIO_AF) << ((uint32_t)((uint32_t)GPIO_PinSource &
(uint32_t)0x07) * 4)) ;
GPIOx->AFR[GPIO_PinSource >> 0x03] &= ~((uint32_t)0xF <<
((uint32_t)((uint32_t)GPIO_PinSource & (uint32_t)0x07) * 4)) ;
temp_2 = GPIOx->AFR[GPIO_PinSource >> 0x03] | temp;
GPIOx->AFR[GPIO_PinSource >> 0x03] = temp_2;
}

73
APIS NÉCESSAIRES DE RCC

74
RCC API#1:
void RCC_AHB1PeriphResetCmd (uint32_t RCC_AHB1Periph,
FunctionalState NewState)

75
RCC API#1 : RCC_AHB1PeriphResetCmd

76
suite
Cette fonction permet d’activer ou désactiver le
périphérique utilisé selon la valeur du paramètre NewState
Si NewState = ENABLE, le périphérique est en état de
reset
Si NewState = DISABLE, le périphérique sort de l’état de
reset
il faut que NewState soit DISABLE pour reprendre l’état
normal, le reset se fait durant un seul cycle.

77
RCC API#1 : RCC_AHB1PeriphResetCmd
void RCC_AHB1PeriphResetCmd (uint32_t RCC_AHB1Periph,
FunctionalState NewState)
{
/* Check the parameters */
assert_param(IS_RCC_AHB1_RESET_PERIPH(RCC_AHB1Periph));
assert_param(IS_FUNCTIONAL_STATE(NewState));
if (NewState != DISABLE)
{
RCC->AHB1RSTR |= RCC_AHB1Periph;
} else {
RCC->AHB1RSTR &= ~RCC_AHB1Periph;
}
}

78
RCC API#2
void RCC_AHB1PeriphClockCmd(uint32_t RCC_AHB1Periph,
FunctionalState NewState)

79
RCC API#2 : RCC_AHB1PeriphClockCmd

80
suite
Cette fonction permet d’activer ou désactiver l’horloge du
périphérique utilisé selon la valeur de paramètre NewState

Si NewState = ENABLE, l’horloge est activée

Si NewState = DISABLE, l’horloge est désactivée

il faut que NewState soit ENABLE pour reprendre le


périphérique puisse fonctionner

81
RCC API#2 : RCC_AHB1PeriphClockCmd

void RCC_AHB1PeriphClockCmd(uint32_t RCC_AHB1Periph,


FunctionalState NewState)
{
/* Check the parameters */
assert_param(IS_RCC_AHB1_CLOCK_PERIPH(RCC_AHB1Periph));
assert_param(IS_FUNCTIONAL_STATE(NewState));
if (NewState != DISABLE) {
RCC->AHB1ENR |= RCC_AHB1Periph;
} else {
RCC->AHB1ENR &= ~RCC_AHB1Periph;
}
}

82
PROGRAMMATION AVEC LES
APIS (CHAP4_APIS_TP1)

83
Exemple

Clignoter la diode LED connectée à PD12 en utilisant


les registres prédéfinis dans CMSIS en modifiant
l’exercice du chapitre 3 ci-dessous?

84
Exemple (solution)
GPIO_InitTypeDef ma_structure;
void tempo(volatile unsigned int CNT)
int main() {
RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOD,ENABLE);
RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOD,DISABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD,ENABLE);

ma_structure.GPIO_Pin = GPIO_Pin_12;
ma_structure.GPIO_Mode = GPIO_Mode_OUT;
ma_structure.GPIO_OType = GPIO_OType_PP;
ma_structure.GPIO_Speed = GPIO_Speed_50MHz;
ma_structure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOD, &ma_structure);

85
Exemple (solution suite)
while(1){
GPIO_SetBits (GPIOD,GPIO_Pin_12);
tempo(0xffffff);
GPIO_ResetBits (GPIOD,GPIO_Pin_12);
tempo(0xffffff);
}
}// fin du main

void tempo(volatile unsigned int CNT){


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

86
TP1_CMSIS_API

Comment en modifiant 3 lignes de code dans


l’exemple précédent on peut clignoter 2 leds
ou plus ?

87