STM32基础(6)外部中断

本文详细介绍了STM32的EXTI外部中断控制器的工作原理,包括边沿检测器配置、中断事件的区别以及EXTI时钟来源。还阐述了STM32F10x系列的EXTI线与GPIO端口的映射关系,并提供了步骤指导,包括SysTick驱动、GPIO操作、按键和LED驱动以及外部中断驱动的编写和中断服务函数的设置。
摘要由CSDN通过智能技术生成

原理

EXTI(External interrupt/event controller)外部中断/事件控制器包含多达 20 个用于产生事件/中断请求的边沿检测器。EXTI 的每根输入线都可单独进行配置,以选择类型(中断或事件)和相应的触发事件(上升沿触发、下降沿触发或边沿触发),还可独立地被屏蔽。

产生中断的目的是把输入信号输入到NVIC中,进一步执行中断服务函数,实现功能,这是软件级别的。

产生事件的目的是传输一个脉冲信号给其他的外设电路,属于硬件级别的,比如可以给定时器TIMER或者ADC等使用。

在 EXTI 框图最顶端可以看到,其外设接口时钟是由 PCLK2,即 APB2 提供,使能 EXTI 时钟的时候一定要注意。

STM32F10x 的 EXTI 供外部 IO 口使用的中断线有 16 根,因为 STM32F103 芯片每个 GPIO 端口均有 16 个管脚,所以把每个端口的 16 个 IO 对应那 16 根中断线 EXTI0-EXTI15。 这样就需要通过AFIO_EXTICRx配置GPIO线上的外部中断/事件来决定对应的中断线映射到哪个 GPIO 端口上,映射配置函数在stm32f10x_gpio.c 和 stm32f10x_gpio.h 中。

步骤

  1. 编写SysTick驱动程序(STM32F1系列通用)
    1. 将固件库文件misc.c添加至工程,misc.c中包含SysTick寄存器的操作函数
    2. 编写头文件:函数声明
    3. 编写驱动文件:初始化函数、延时us函数、延时ms函数
  2. 对GPIO的IDR和ODR寄存器位操作进行封装(STM32F1系列通用)
  3. 编写按键驱动程序
    1. 编写头文件:宏定义连接按键的端口、端口引脚、端口时钟、引脚位带、按键值,函数声明
    2. 编写驱动文件:
      1. 按键初始化函数:开启端口时钟,定义GPIO_InitTypeDef结构体变量并初始化
      2. 按键检测函数:检测到按键被按下,延时10ms消抖,再次确认按键被按下
  4. 编写LED驱动程序
    1. 编写头文件:宏定义连接LED的端口、端口引脚、端口时钟、引脚位带,函数声明
    2. 编写驱动文件:
      1. LED初始化函数:开启端口时钟,定义GPIO_InitTypeDef结构体变量并初始化,拉高引脚电平
  5. 编写外部中断驱动程序
    1. 将固件库文件stm32f10x_exti.c添加至工程,stm32f10x_exti.c中包含EXTI寄存器的操作函数
    2. 编写头文件
      1. 引入位带头文件,函数声明
    3. 编写驱动文件
      1. EXTI初始化函数
      2. 中断服务函数
  6. 主函数:初始化滴答定时器、初始化硬件、设置中断优先级分组、初始化外部中断

代码

//SysTick.h
#ifndef _SYSTICK_H
#define _SYSTICK_H

#include "system.h"

void SysTick_Init(u8 SYSCLK);
void delay_ms(u16 nms);
void delay_us(u32 nus);

#endif

//SysTick.c
#include "SysTick.h"

static u8 fac_us = 0;		//保存倍乘数
static u16 fac_ms = 0;

void SysTick_Init(u8 SYSCLK)
{
	SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);	//将CTRL寄存器的第二位置0,即用外部时钟源
	fac_us = SYSCLK/8;	//72/8
	fac_ms = (
STM32 微控制器支持多种类型的断,包括外部中断EXTI)。外部中断允许处理器响应来自外部设备(如按钮、传感器等)的事件,并通过断处理程序执行相应的操作。 ### STM32 断配置基本步骤: #### 步骤 1: 初始化 GPIO 引脚作为外部中断触发 首先,在 `main.c` 或者 `stm32f4xx_hal_misr.c` 文件初始化GPIO引脚并设置其模式。例如,如果你打算使用PA0作为外部中断触发信号: ```c #include "stm32f4xx_hal.h" void init_GPIO() { GPIO_InitTypeDef GPIO_InitStruct = {0}; /* Configure GPIO Ports */ __HAL_RCC_GPIOA_CLK_ENABLE(); // Enable GPIO Clock GPIO_InitStruct.Pin = GPIO_PIN_0; // Pin 0 of GPIOA GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING; // Set as rising edge interrupt GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); } ``` #### 步骤 2: 配置 EXTI 线路 接下来,需要配置EXTI线路上的断服务功能和对应的断向量: ```c void init_EXTI() { NVIC_InitTypeDef NVIC_InitStructure; /* Enable the EXTI peripheral */ __HAL_RCC_EXTI_CLK_ENABLE(); /* EXTI line configuration */ EXTI_InitTypeDef EXTIInitStructure = {0}; EXTIInitStructure.Line = EXTI_LINE_PA0; // Example for PA0 EXTIInitStructure mode = EXTI_Mode_Interrupt; EXTIInitStructure.Trigger = EXTI_Trigger_Rising; HAL_NVIC_SetPriority(EXTI0_IRQn, 5, 0); HAL_NVIC_EnableIRQ(EXTI0_IRQn); HAL_EXTI_Init(&EXTIInitStructure); } ``` #### 步骤 3: 实现断服务函数 (ISR) 创建一个断服务函数来处理外部中断: ```c static void EXTI0_IRQHandler(void) { static uint8_t flag EXTI0_flag = 0; if (__HAL_GPIO_GET_IT_SOURCE(GPIOA, GPIO_PIN_0)) { // Handle external event here if (!flag) { flag = 1; // Do something when an event occurs on PA0. // For example, print a message or change system state. printf("External event detected on PA0.\n"); } else { flag = 0; // Reset the flag after handling the event to prevent duplicate calls in rapid succession } } else { flag = 0; } __HAL_GPIO_CLEAR_IT(GPIOA, GPIO_PIN_0); // Clear the interrupt source } // In main() function call this function once after initializing EXTI and GPIO HAL_NVIC_StartTick(); ``` ### 关联问题: 1. **如何在STM32配置GPIO作为外部中断触发?** 2. **STM32EXTI断是如何工作的?** 3. **在STM32项目加入外部中断的完整步骤是什么?**
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值