引脚是什么为什么要初始化引脚?
在嵌入式系统中,引脚是微控制器或微处理器上的物理引脚,用于连接外部设备、传感器或其他芯片。每个引脚都有特定的功能和用途,例如输入、输出、模拟输入、电源供应等。在你提供的代码中,使用了STM32系列微控制器的引脚配置。
初始化引脚的目的在于:
-
确定引脚的功能: 微控制器的引脚通常具有多个功能,比如输入、输出、模拟信号输入等。通过初始化,你可以明确引脚在特定时刻的功能。
-
配置引脚的电气特性: 引脚的电气特性包括输出速率、上拉/下拉电阻等。通过初始化,你可以设置引脚的这些特性,以适应特定的应用场景。
-
确保正确的电气状态: 初始化过程中,你可以设定引脚的初始状态,确保系统启动时引脚处于正确的电气状态。在代码中,通过
GPIO_SetBits(GPIOB, GPIO_Pin_5 | GPIO_Pin_1)
将引脚5和引脚1设置为高电平,关闭LED,可能是确保LED在初始化后处于关闭状态。
总的来说,初始化引脚是为了确保它们在系统运行时以正确的方式工作,并满足特定的应用需求。
为什么要设置为高电平?
在嵌入式系统中,特定的硬件设计和连接要求可能导致在初始化过程中需要将引脚设置为高电平或低电平。在代码中,通过 GPIO_SetBits(GPIOB, GPIO_Pin_5 | GPIO_Pin_1)
将引脚5和引脚1设置为高电平,关闭LED。
为什么判断时要使用 GPIO_ReadOutputDataBit(GPIOB, GPIO_Pin_5) == 0
在提供的代码中,GPIO_ReadOutputDataBit(GPIOB, GPIO_Pin_5) == 0
的条件语句检查引脚5(对应LEDR)的输出状态是否为低电平。
-
GPIO_ReadOutputDataBit(GPIOB, GPIO_Pin_5)
: 这个函数是用于读取指定引脚的输出状态的函数。在这里,它读取GPIOB中引脚5(LEDR)的输出状态。 -
== 0
: 这是一个比较运算符,检查表达式左侧的值是否等于右侧的值。在这里,它检查引脚5的输出状态是否等于0,即低电平。
因此,GPIO_ReadOutputDataBit(GPIOB, GPIO_Pin_5) == 0
的整个条件语句的含义是:如果LEDR(引脚5)的输出状态为低电平(0),则执行条件语句块内的代码。
为什么要设置中断?
在嵌入式系统中,中断是一种机制,用于实时响应硬件事件或异步事件。通过配置中断,系统可以在出现特定事件时立即执行相应的中断服务程序(ISR,Interrupt Service Routine),而不必通过轮询或其他方式不断地检查事件状态。配置中断的目的包括:
-
实时响应事件: 中断允许系统在发生特定事件时立即进行响应,而无需等待主程序轮询或定时检查。这对于需要快速响应的实时应用非常重要,如控制系统、通信系统等。
-
提高系统效率: 通过使用中断,系统可以在等待事件的同时执行其他任务,提高了系统的效率。相比于轮询方式,中断减少了对系统资源的浪费。
-
事件驱动编程: 配置中断允许采用事件驱动的编程模型,其中系统对外部事件作出响应,而不是通过持续轮询。这样的编程方式通常更加模块化和易于维护。
-
优先级管理: 中断允许设置不同中断的优先级,确保在系统中同时发生多个事件时能够按照优先级顺序处理。这对于确保关键事件的及时处理非常关键。
-
省电: 在某些情况下,通过中断响应事件,系统可以保持在低功耗状态,只有在需要时才唤醒主程序执行。这有助于节省能量。
在提供的代码中,配置中断的目的是为了处理键盘输入(KEY1、KEY2)和定时器中断(TIM6)。这样,当用户按下按键或者定时器溢出时,系统能够立即作出响应,而不必等待这些事件在主程序中被轮询检测到。
中断初始化代码详解
以下这段代码是用于配置嵌套向量中断控制器(NVIC)的初始化函数。在嵌入式系统中,NVIC用于管理中断,通过设置优先级和使能中断来控制中断的触发和处理。
-
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
: 设置优先级分组为优先级组1。这里的优先级分组影响了中断优先级的划分方式。 -
配置外部中断(EXTI)中断优先级:
针对
EXTI0_IRQn
,即KEY1的外部中断,设置主优先级为1,次优先级为1。针对EXTI15_10_IRQn
,即KEY2的外部中断,设置主优先级为1,次优先级为2。 -
配置定时器中断(TIM6)优先级:
针对
TIM6_IRQn
,设置主优先级为1,次优先级为0。 -
NVIC_Config.NVIC_IRQChannelCmd = ENABLE;
: 使能相应中断。 -
NVIC_Init(&NVIC_Config);
: 对以上配置进行初始化,将配置应用到实际的中断控制器中。
总体而言,这段代码的目的是初始化中断控制器,设置不同中断的优先级和使能状态,以确保在系统运行时可以正确响应和处理各种中断。
cpp
void nvic_init(void)
{
NVIC_InitTypeDef NVIC_Config;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); // 设置优先级分组为优先级组1
// KEY1
NVIC_Config.NVIC_IRQChannel = EXTI0_IRQn;
NVIC_Config.NVIC_IRQChannelPreemptionPriority = 1; // 设置主优先级为1
NVIC_Config.NVIC_IRQChannelSubPriority = 1; // 设置次优先级为1
NVIC_Config.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_Config);
// KEY2
NVIC_Config.NVIC_IRQChannel = EXTI15_10_IRQn;
NVIC_Config.NVIC_IRQChannelPreemptionPriority = 1; // 设置主优先级为1
NVIC_Config.NVIC_IRQChannelSubPriority = 2; // 设置次优先级为2
NVIC_Config.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_Config);
// TIM6
NVIC_Config.NVIC_IRQChannel = TIM6_IRQn;
NVIC_Config.NVIC_IRQChannelPreemptionPriority = 1; // 设置主优先级为1
NVIC_Config.NVIC_IRQChannelSubPriority = 0; // 设置次优先级为0
NVIC_Config.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_Config);
}
详细解释一下优先级顺序
**KEY1外部中断(EXTI0_IRQn):**主优先级:1 次优先级:1
**KEY2外部中断(EXTI15_10_IRQn):**主优先级:1 次优先级:2
**定时器中断(TIM6_IRQn):**主优先级:1 次优先级:0
这 里采用的优先级设置是简单的优先级分组方式,使用了一个主优先级和一个次优先级。在这种设置下,主优先级决定了各中断之间的相对优先级,而次优先级则用于区分相同主优先级的不同中断。
优先级顺序是:定时器中>KEY1外部中断>KEY2外部中断
这意味着在同时发生这三个中断时,系统会首先处理定时器中断,然后是KEY1外部中断,最后是KEY2外部中断。希望这次能够清晰地解释。
为什么要启用时钟和为什么要配置外部中断线
启用时钟:
在嵌入式系统中,启用时钟是为了激活相应外设或功能模块的时钟。微控制器的不同功能模块(如GPIO、外部中断控制器、定时器等)都需要时钟信号来驱动其工作。因此,在使用这些功能之前,需要确保相应的时钟已经被启用。
cpp
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, ENABLE);
这行代码启用了GPIOA、GPIOC和复用引脚(AFIO)的时钟。GPIOA和GPIOC是用于配置按键引脚的GPIO端口,而AFIO是用于配置外部中断线的复用引脚。
配置外部中断线
外部中断线配置的目的是将实际的物理引脚与外部中断线关联起来,使得当引脚状态变化时能够触发相应的中断。在这里,主要是将按键的物理引脚与外部中断线关联。
对于KEY1,GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0)
将GPIOA的引脚0(即PA0)与外部中断线0关联起来。
对于KEY2,GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource13)
将GPIOC的引脚13(即PC13)与外部中断线13关联起来。
外部中断线配置的详细参数包括中断线的选择、中断模式(中断或事件模式)、触发方式(上升沿、下降沿等)等。配置外部中断线是为了让系统能够在按键状态变化时及时地产生中断。
STM32的八种GPIO模式
-
输入模式 (Input Mode):
- GPIO引脚被配置为输入,用于读取外部信号。
- 引脚电压将根据外部信号的状态变化而变化。
- 在此模式下,引脚的状态由外部电路决定。
-
输出模式 (Output Mode):
- GPIO引脚被配置为输出,可以向外部设备提供信号。
- 开发者可以通过相应的寄存器设置引脚的状态,例如将引脚设置为高电平或低电平。
-
推挽输出模式 (Push-Pull Output Mode):
- GPIO引脚被配置为推挽输出,可以提供高电平和低电平信号。
- 引脚可以主动推送(提供)高电平或拉低(提供)低电平。
- 适用于需要提供相对较大电流的场景,如驱动LED或驱动其他数字电路。
-
开漏输出模式 (Open-Drain Output Mode):
- GPIO引脚被配置为开漏输出,通常与外部上拉电阻结合使用。
- 在高电平状态下,引脚处于高阻态,而在低电平状态下,引脚将连接到地。
- 适用于需要实现电平的共享或与其他开漏设备连接的场景。
-
复用功能输入模式 (Alternate Function Input Mode):
- GPIO引脚被配置为某个外设的输入,例如UART、SPI或I2C。
- 引脚的功能由复用寄存器设置,以选择相应的外设功能。
-
复用功能输出模式 (Alternate Function Output Mode):
- GPIO引脚被配置为某个外设的输出。
- 类似于复用功能输入模式,引脚的功能由复用寄存器设置。
-
模拟输入模式 (Analog Mode):
- GPIO引脚被配置为模拟输入,用于连接模拟传感器或其他模拟设备。
- 在此模式下,引脚可以读取模拟电压值。
-
中断模式 (Interrupt Mode):
- GPIO引脚被配置为触发中断,当引脚状态变化时,可以触发中断服务程序。
- 适用于需要在引脚状态变化时执行特定操作的场景,如按钮按下触发中断
什么是中断的通道
cpp
NVIC_Config.NVIC_IRQChannel = TIM6_IRQn;
这行代码是在配置中断控制器(NVIC - Nested Vectored Interrupt Controller)的相关设置,具体是在配置 TIM6 定时器的中断通道。
具体而言,NVIC_Config.NVIC_IRQChannel = TIM6_IRQn;
这一行代码设置了中断通道为 TIM6 定时器中断。在这里,TIM6_IRQn
表示 TIM6 定时器的中断通道。
NVIC
: Nested Vectored Interrupt Controller,中文称为嵌套向量中断控制器。它是用于管理中断的硬件模块。
NVIC_IRQChannel
: 表示中断通道,即中断的来源。在这里,它被设置为 TIM6 定时器中断。
TIM6_IRQn
: 表示 TIM6 定时器的中断通道编号。这个编号是根据具体的微控制器型号和型号的,不同型号的 STM32 微控制器可能具有不同的中断通道编号。
这行代码的作用是告诉中断控制器,当 TIM6 定时器触发中断时,执行与该中断通道相关的中断服务程序(Interrupt Service Routine,ISR)。在程序的其他地方,你可能会编写一个中断服务程序来处理 TIM6 定时器中断时需要执行的操作。