Chap3 - Driver - GPIO (Mode de Compatibilité)
Chap3 - Driver - GPIO (Mode de Compatibilité)
Chap3 - Driver - GPIO (Mode de Compatibilité)
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
3
CMSIS
4
Qu’est-ce que CMSIS
5
Couches de CMSIS
7
Rappel sur le Memory MAP
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).
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.
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)
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.
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;
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.
typedef enum{
GPIO_OType_PP = 0x00,
GPIO_OType_OD = 0x01
}GPIOOType_TypeDef;
29
Paramètre 5: GPIOPuPd_TypeDef
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
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
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
*/
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));
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
*/
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.
*/
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.
*/
48
API5: GPIO_ReadInputData le code
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.
*/
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.
*/
54
API7: GPIO_ReadOutputData le
code
55
API8:
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.
*/
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.
*/
61
API#10: void GPIO_WriteBit (GPIO_TypeDef* GPIOx,
uint16_t GPIO_Pin, BitAction BitVal)
62
API#10: GPIO_WriteBit
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 */
66
API #11: GPIO_WriteBit le code
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.
*/
69
API#12: GPIO_ToggleBits ,
70
API#13:
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
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
81
RCC API#2 : RCC_AHB1PeriphClockCmd
82
PROGRAMMATION AVEC LES
APIS (CHAP4_APIS_TP1)
83
Exemple
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
86
TP1_CMSIS_API
87