Notes d'étude STM32CubeMX (3) -EXTI (interruption externe) utilisation de l'interface

1. Nouvelle construction

1. Ouvrez le logiciel STM32CubeMX et cliquez sur "Nouveau projet"

2. Choisissez MCU et package

3. Configurez les
paramètres de l'horloge RCC, sélectionnez HSE (horloge haute vitesse externe),

sélectionnez Configuration de l'horloge pour le résonateur à cristal / céramique (oscillateur à cristal / résonateur en céramique) , configurez l'horloge système SYSCLK à 72 MHz,
modifiez la valeur de HCLK à 72, et appuyez sur Entrée. Modifiez automatiquement toutes les configurations

4. C'est
une étape très importante pour configurer le mode de débogage , sinon le
paramètre SYS du débogueur ne sera pas reconnu après le premier programme de programmation , sélectionnez Déboguer comme Serial Wire

Deux, interruption externe EXTI

2.1 Configuration des paramètres

Lors de la System Coresélection des GPIOparamètres.

Trouvez la broche correspondante du bouton dans la figure de droite et sélectionnez-la GPIO_EXTIx.
Ici, le xmoyen monté sur plusieurs lignes d'interruption, est monté sur une telle interruption GPIO_EXTI0 0.

  • Ouvrir front descendant déclenché interruption: à savoir, lorsque la touche est enfoncée niveau lorsqu'il est déclenché par un haut en bas, puis la GPIO modechoisiExternal Interrupt Mode with Falling edge trigger detection

  • Ouvrir front montant interruptions déclenchées: à savoir, lorsque le bouton de déverrouillage est enfoncé après que les changements de niveau de déclenchement de faible à élevé, la GPIO modesélectionExternal Interrupt Mode with Rising edge trigger detection

  • Les interruptions déclenchées par front montant sont activées en descendant: cela se déclenche lorsque vous appuyez à nouveau lorsque vous relâchez la gâchette , puis GPIO modesélectionnezExternal Interrupt Mode with Rising/Falling edge trigger detection

  • S'il s'agit d'un matériel externe de traction ou de retrait, ne GPIO Pull-up/Pull-downsélectionnez No pull-up and no pull-downni pull-up ni pull-down.

  • Si le matériel n'est pas une traction externe, GPIO Pull-up/Pull-downsélectionnez Pull-upune résistance pullup interne.

    Configuration Les NVIC
    règles de regroupement de priorité d'interruption sont Priority Groupdéfinies par défaut sur quatre bits, ne changent généralement pas.
    Vérifiez la configuration externe, interrompez simplement 0 et 13, et configurez la priorité de préemption Preemption Priorityet en réponse à la priorité Sub Priority.

    • Préemptez la priorité, plus le nombre est petit, plus la priorité est élevée
    • Si la priorité de préemption est la même, déterminez la sous-priorité. De même, plus le nombre est petit, plus la priorité est élevée

2.2 Générer du code

Noms des éléments de chemin et

sélection des entrées des éléments d'un environnement de développement d'application IDE MDK-ARM V5

chaque périphérique génère un ’.c/.h’fichier séparé
non hook: tout le code d'initialisation est généré dans main.c
vérifié: fichier de code d'initialisation généré dans le périphérique associé. Par exemple, le code d'initialisation GPIO est généré dans gpio.c.
Cliquez sur GÉNÉRER LE CODE pour générer du code

2.3 Modifier la fonction de rappel d'interruption

Ouvrez le stm32f1xx_it.cfichier de routine de service d'interruption, recherchez le service d'interruption de routine de service d'interruption EXTI0 EXTI0_IRQHandler()
à l'intérieur de la fonction s'appelle le gestionnaire d'interruption externe GPIO HAL_GPIO_EXTI_IRQHandler()

pour ouvrir le stm32f1xx_hal_gpio.cfichier, recherchez le prototype de gestionnaire d'interruption externe HAL_GPIO_EXTI_IRQHandler(), son rôle principal est de déterminer les interruptions de ligne de date, effacer le indicateur d'interruption, puis appelez la fonction de rappel d'interruption HAL_GPIO_EXTI_Callback().

/ * REMARQUE: Cette fonction ne doit pas être modifiée, lorsque le rappel est nécessaire,
le HAL_GPIO_EXTI_Callback peut être implémenté dans le fichier utilisateur
* /
Cette fonction ne doit pas être modifiée, si vous devez utiliser la fonction de rappel, veuillez réimplémenter la fonction dans le fichier utilisateur.

HAL_GPIO_EXTI_Callback()Selon l'invite officielle, nous devrions redéfinir la fonction, qui __weakest un indicateur affaibli. La fonction avec ceci est une fonction affaiblie, c'est-à-dire que vous pouvez écrire une fonction avec exactement le même nom et les mêmes paramètres ailleurs, et le compilateur ignorera cette fonction. À la place UNUSED(GPIO_Pin), exécutez la fonction que vous avez écrite; et , ceci est une définition sans erreur. Lorsque le numéro de port GPIO entrant n'est pas traité de quelque manière que ce soit, le compilateur ne signale pas d'avertissement. En fait, nous n'avons plus besoin de nous soucier de la fonction de service d'interruption lorsque nous développons. Nous devons seulement trouver la fonction de rappel d'interruption et la réécrire. Il y a un autre aspect très pratique de cette fonction de rappel qui n'est pas reflété ici. Lorsque plusieurs interruptions sont activées, STM32CubeMX organise automatiquement les fonctions de service de plusieurs interruptions ensemble et appelle une fonction de rappel, c'est-à-dire que quel que soit le nombre d'interruptions, il suffit de réécrire une fonction de rappel et de juger le numéro de port entrant OK.

Ensuite, nous stm32f1xx_it.cajoutons simplement le bas de ce documentHAL_GPIO_EXTI_Callback()

/* USER CODE BEGIN 1 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
    
    
	if(GPIO_Pin==KEY1_Pin)
	{
    
    
        // 自定义应用程序
        HAL_GPIO_TogglePin(LED_G_GPIO_Port,LED_G_Pin);
	}
}
/* USER CODE END 1 */

2.3 Comparaison de la bibliothèque HAL et du code de la bibliothèque standard

STM32CubeMX utilise le code généré par la bibliothèque HAL:

#define KEY2_Pin GPIO_PIN_13
#define KEY2_GPIO_Port GPIOC
#define KEY2_EXTI_IRQn EXTI15_10_IRQn
#define KEY1_Pin GPIO_PIN_0
#define KEY1_GPIO_Port GPIOA
#define KEY1_EXTI_IRQn EXTI0_IRQn

/**
  * @brief GPIO Initialization Function
  * @param None
  * @retval None
  */
static void MX_GPIO_Init(void)
{
    
    
    GPIO_InitTypeDef GPIO_InitStruct = {
    
    0};

    /* GPIO Ports Clock Enable */
    __HAL_RCC_GPIOC_CLK_ENABLE();
    __HAL_RCC_GPIOA_CLK_ENABLE();

    /*Configure GPIO pin : KEY2_Pin */
    GPIO_InitStruct.Pin = KEY2_Pin;
    GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(KEY2_GPIO_Port, &GPIO_InitStruct);

    /*Configure GPIO pin : KEY1_Pin */
    GPIO_InitStruct.Pin = KEY1_Pin;
    GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(KEY1_GPIO_Port, &GPIO_InitStruct);

    /* EXTI interrupt init*/
    HAL_NVIC_SetPriority(EXTI0_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(EXTI0_IRQn);

    HAL_NVIC_SetPriority(EXTI15_10_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);
}

/**
  * @brief This function handles EXTI line0 interrupt.
  */
void EXTI0_IRQHandler(void)
{
    
    
    /* USER CODE BEGIN EXTI0_IRQn 0 */

    /* USER CODE END EXTI0_IRQn 0 */
    HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
    /* USER CODE BEGIN EXTI0_IRQn 1 */

    /* USER CODE END EXTI0_IRQn 1 */
}

/**
  * @brief This function handles EXTI line[15:10] interrupts.
  */
void EXTI15_10_IRQHandler(void)
{
    
    
    /* USER CODE BEGIN EXTI15_10_IRQn 0 */

    /* USER CODE END EXTI15_10_IRQn 0 */
    HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_13);
    /* USER CODE BEGIN EXTI15_10_IRQn 1 */

    /* USER CODE END EXTI15_10_IRQn 1 */
}

/**
  * @brief  This function handles EXTI interrupt request.
  * @param  GPIO_Pin: Specifies the pins connected EXTI line
  * @retval None
  */
void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)
{
    
    
    /* EXTI line interrupt detected */
    if (__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != 0x00u)
    {
    
    
        __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);
        HAL_GPIO_EXTI_Callback(GPIO_Pin);
    }
}

Utilisez le code de bibliothèque standard STM32:

#define KEY1_INT_GPIO_PORT         GPIOA
#define KEY1_INT_GPIO_CLK          (RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO)
#define KEY1_INT_GPIO_PIN          GPIO_Pin_0
#define KEY1_INT_EXTI_PORTSOURCE   GPIO_PortSourceGPIOA
#define KEY1_INT_EXTI_PINSOURCE    GPIO_PinSource0
#define KEY1_INT_EXTI_LINE         EXTI_Line0
#define KEY1_INT_EXTI_IRQ          EXTI0_IRQn

#define KEY1_IRQHandler            EXTI0_IRQHandler


#define KEY2_INT_GPIO_PORT         GPIOC
#define KEY2_INT_GPIO_CLK          (RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO)
#define KEY2_INT_GPIO_PIN          GPIO_Pin_13
#define KEY2_INT_EXTI_PORTSOURCE   GPIO_PortSourceGPIOC
#define KEY2_INT_EXTI_PINSOURCE    GPIO_PinSource13
#define KEY2_INT_EXTI_LINE         EXTI_Line13
#define KEY2_INT_EXTI_IRQ          EXTI15_10_IRQn

#define KEY2_IRQHandler            EXTI15_10_IRQHandler

 /**
  * @brief  配置嵌套向量中断控制器NVIC
  * @param  无
  * @retval 无
  */
static void NVIC_Configuration(void)
{
    
    
  NVIC_InitTypeDef NVIC_InitStructure;
  
  /* 配置NVIC为优先级组1 */
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
  
  /* 配置中断源:按键1 */
  NVIC_InitStructure.NVIC_IRQChannel = KEY1_INT_EXTI_IRQ;
  /* 配置抢占优先级 */
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  /* 配置子优先级 */
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  /* 使能中断通道 */
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
  
  /* 配置中断源:按键2,其他使用上面相关配置 */  
  NVIC_InitStructure.NVIC_IRQChannel = KEY2_INT_EXTI_IRQ;
  NVIC_Init(&NVIC_InitStructure);
}

 /**
  * @brief  配置 IO为EXTI中断口,并设置中断优先级
  * @param  无
  * @retval 无
  */
void EXTI_Key_Config(void)
{
    
    
	GPIO_InitTypeDef GPIO_InitStructure; 
	EXTI_InitTypeDef EXTI_InitStructure;

	/*开启按键GPIO口的时钟*/
	RCC_APB2PeriphClockCmd(KEY1_INT_GPIO_CLK,ENABLE);
												
	/* 配置 NVIC 中断*/
	NVIC_Configuration();
	
    /*--------------------------KEY1配置-----------------------------*/
	/* 选择按键用到的GPIO */	
    GPIO_InitStructure.GPIO_Pin = KEY1_INT_GPIO_PIN;
    /* 配置为浮空输入 */	
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(KEY1_INT_GPIO_PORT, &GPIO_InitStructure);

	/* 选择EXTI的信号源 */
    GPIO_EXTILineConfig(KEY1_INT_EXTI_PORTSOURCE, KEY1_INT_EXTI_PINSOURCE); 
    EXTI_InitStructure.EXTI_Line = KEY1_INT_EXTI_LINE;
	
    /* EXTI为中断模式 */
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    /* 上升沿中断 */
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
    /* 使能中断 */	
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);
	
    /*--------------------------KEY2配置-----------------------------*/
    /* 选择按键用到的GPIO */	
    GPIO_InitStructure.GPIO_Pin = KEY2_INT_GPIO_PIN;
    /* 配置为浮空输入 */	
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(KEY2_INT_GPIO_PORT, &GPIO_InitStructure);

    /* 选择EXTI的信号源 */
    GPIO_EXTILineConfig(KEY2_INT_EXTI_PORTSOURCE, KEY2_INT_EXTI_PINSOURCE); 
    EXTI_InitStructure.EXTI_Line = KEY2_INT_EXTI_LINE;
	
    /* EXTI为中断模式 */
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    /* 下降沿中断 */
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
    /* 使能中断 */	
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);
}

void KEY1_IRQHandler(void)
{
    
    
    //确保是否产生了EXTI Line中断
	if(EXTI_GetITStatus(KEY1_INT_EXTI_LINE) != RESET) 
	{
    
    
		// LED1 取反		
		LED1_TOGGLE;
        //清除中断标志位
		EXTI_ClearITPendingBit(KEY1_INT_EXTI_LINE);     
	}  
}

void KEY2_IRQHandler(void)
{
    
    
    //确保是否产生了EXTI Line中断
	if(EXTI_GetITStatus(KEY2_INT_EXTI_LINE) != RESET) 
	{
    
    
		// LED2 取反		
		LED2_TOGGLE;
        //清除中断标志位
		EXTI_ClearITPendingBit(KEY2_INT_EXTI_LINE);     
	}  
}

__HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE();Correspondant au RCC_APB2PeriphClockCmd(KEY1_GPIO_CLK|KEY2_GPIO_CLK,ENABLE);
HAL_GPIO_Init(KEY1_GPIO_Port, &GPIO_InitStruct);correspondant GPIO_Init(KEY1_GPIO_PORT, &GPIO_InitStructure);
HAL_NVIC_SetPriority(EXTI0_IRQn, 0, 0);HAL_NVIC_EnableIRQ(EXTI0_IRQn);correspondant à NVIC_Init(&NVIC_InitStructure);EXTI_Init(&EXTI_InitStructure);
__HAL_GPIO_EXTI_GET_IT(GPIO_Pin)un correspondant EXTI_GetITStatus(KEY1_INT_EXTI_LINE)
__HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin)un correspondantEXTI_ClearITPendingBit(KEY1_INT_EXTI_LINE)

Trois, les questions nécessitant une attention

Code utilisateur à ajouter USER CODE BEGIN Net USER CODE END Nentre, sinon la prochaine utilisation après que STM32CubeMX régénère le code, il sera supprimé.


Écrit par Leung le 12 janvier 2021

• Référence: Didacticiel 2 de la série STM32CubeMX : Interruption externe (EXIT)
    [STM32Cube_05] Utiliser le bouton de détection d'interruption EXIT (configuration NVIC + mécanisme de gestion des interruptions de la bibliothèque HAL)
    "Embedded-STM32 Development Guide" Partie 2 Bases - Chapitre 3 Boutons (bibliothèque HAL)
    STM32CubeMX tutoriel de combat réel (trois) -interruption externe (fonction interruption et HAL_Delay pour éviter les fosses)

Je suppose que tu aimes

Origine blog.csdn.net/qq_36347513/article/details/112508465
conseillé
Classement