中断——对射式红外传感器计次、旋转编码器计次

对射式红外传感器计次

代码:

#include "stm32f10x.h"                  // Device header

//声明一个名为CountSensor_Count的uint16_t类型的变量,用于保存计数传感器的计数值。
uint16_t CountSensor_Count; 


//定义了一个名为CountSensor_Init的函数,用于初始化计数传感器。
void CountSensor_Init(void)
{
    //使能GPIOB的时钟,使能AFIO(复用功能IO)的时钟。
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
	

    //定义一个名为GPIO_InitStructure的结构体,用于配置GPIO的初始化参数。
	GPIO_InitTypeDef GPIO_InitStructure;
    //设置GPIO引脚为输入模式,启用上拉电阻。
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    //设置GPIO引脚为引脚14
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
    //设置GPIO引脚的速度为50MHz。
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    //使用上述配置初始化GPIOB引脚。
	GPIO_Init(GPIOB, &GPIO_InitStructure);


    //配置外部中断线路。
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource14);
	
    //定义一个名为EXTI_InitStructure的结构体,用于配置外部中断的初始化参数。
	EXTI_InitTypeDef EXTI_InitStructure;
    //配置外部中断线为引脚14。
	EXTI_InitStructure.EXTI_Line = EXTI_Line14;
    //使能外部中断线。
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    //配置外部中断为中断模式。
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    //配置外部中断触发方式为下降沿触发。
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
    //使用上述配置初始化外部中断。
	EXTI_Init(&EXTI_InitStructure);
	

    //定义一个名为NVIC_InitStructure的结构体,用于配置中断向量表的初始化参数。
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	
    //
	NVIC_InitTypeDef NVIC_InitStructure;
    //配置中断通道为EXTI15_10_IRQn。
	NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;
  
    //使能中断通道。
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    //配置抢占优先级为1。
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    //配置子优先级为1。
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;

	NVIC_Init(&NVIC_InitStructure);

}


uint16_t CountSensor_Get(void)

{

	return CountSensor_Count;

}


void EXTI15_10_IRQHandler(void)

{

	if (EXTI_GetITStatus(EXTI_Line14) == SET)

	{

		/*如果出现数据乱跳的现象,可再次判断引脚电平,以避免抖动*/

		if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14) == 0)

		{

			CountSensor_Count ++;

		}

		EXTI_ClearITPendingBit(EXTI_Line14);

	}

}

STM32的中断类型:

  1. 外部中断:通过外部触发信号(如按键、传感器等)引发的中断。

  2. 定时器中断:定时器到达设定的时间或计数值时触发的中断。用于实现定时、计时等功能。

  3. UART(串口)中断:当串口接收或发送数据时触发的中断。用于实现串口通信。

  4. DMA(直接存储器访问)中断:当DMA传输完成时触发的中断。用于高速数据传输。

  5. ADC(模数转换器)中断:当模数转换器完成一次模数转换时触发的中断。用于模拟信号采集。

  6. I2C(I²C总线)中断:当I2C总线传输完成或出现错误时触发的中断。用于实现I2C设备之间的通信。

  7. SPI(串行外设接口)中断:当SPI接口传输完成或出现错误时触发的中断。用于实现SPI设备之间的通信。

  8. USB(通用串行总线)中断:与USB相关的中断,用于USB设备的连接和通信。

STM32单片机的GPIO模式配置:

对于WK_UP——配置下拉输入

KEY0,KEY1——配置上拉输入

  1. 输入浮空模式(GPIO_Mode_IN_FLOATING):

    • 特点:GPIO口为输入模式,无上拉或下拉电阻,处于浮空状态。
    • 应用场景:适用于外部传感器信号输入,如按键、开关、触摸传感器等。
  2. 输入上拉模式(GPIO_Mode_IPU,Input Pull-Up):

    • 特点:GPIO口为输入模式,内部上拉电阻启用,连接到VDD(高电平)。
    • 应用场景:适用于外部信号输入,如按键,信号线断开时保持高电平。
  3. 输入下拉模式(GPIO_Mode_IPD,Input Pull-Down):

    • 特点:GPIO口为输入模式,内部下拉电阻启用,连接到地(低电平)。
    • 应用场景:适用于外部信号输入,如按键,信号线断开时保持低电平。
  4. 模拟模式(GPIO_Mode_AIN,Analog Input):

    • 特点:GPIO口为模拟输入模式,用于ADC模数转换输入。
    • 应用场景:适用于模拟传感器信号采集,如温度传感器、光敏传感器等。
  5. 推挽输出模式(GPIO_Mode_Out_PP,Output Push-Pull):

    • 特点:GPIO口为输出模式,推挽输出,可提供高电平和低电平输出。
    • 应用场景:适用于驱动大多数外设和数字电路,如LED、继电器、电机驱动等。
  6. 开漏输出模式(GPIO_Mode_Out_OD,Output Open-Drain):

    • 特点:GPIO口为输出模式,开漏输出,只能提供低电平输出,高电平需要外部上拉电阻。
    • 应用场景:适用于需要多个输出端合并的场景,如I2C总线,多路开关控制等。
  7. 复用推挽输出模式(GPIO_Mode_AF_PP,Alternate Function Output Push-Pull):

    • 特点:GPIO口为复用功能输出模式,可用于驱动某些外设的特殊功能。
    • 应用场景:适用于复用功能模式下的外设控制,如串口、定时器等。
  8. 复用开漏输出模式(GPIO_Mode_AF_OD,Alternate Function Output Open-Drain):

    • 特点:GPIO口为复用功能输出模式,开漏输出,只能提供低电平输出,高电平需要外部上拉电阻。
    • 应用场景:适用于复用功能

注意"开漏输出模式"(GPIO_Mode_Out_OD)是一种高电平无驱动能力的模式。在这种模式下,GPIO口可以提供低电平输出,但无法主动提供高电平输出。

复用推挽输出模式和推挽输出模式的区别是什么?

主要的区别在于复用推挽输出模式可以将GPIO口用于复用功能输出,而推挽输出模式仅用于普通数字信号的输出。

在STM32单片机中,每个GPIO引脚都有多个功能。除了基本的输入和输出功能外,它们还可以用于连接到其他外设(如串口、定时器、SPI等)以实现特定的功能。

复用功能输出是指将GPIO口配置为某个特定外设功能的输出接口。通过配置GPIO引脚的复用功能模式,我们可以利用同一个GPIO引脚输出不同的功能信号,而不仅仅是普通的数字信号。

例如,我们可以将一个GPIO引脚配置为串口功能的复用输出模式。这样,该GPIO引脚就可以用于向外部设备发送串口通信数据。同样地,我们可以将其他GPIO引脚配置为定时器、SPI、I2C等功能的复用输出模式,以实现与这些外设的通信或控制信号输出。

简而言之,复用功能输出允许我们在同一个GPIO引脚上实现多种不同的功能,通过配置不同的复用功能模式,可以将GPIO引脚连接到不同的外设,以实现特定功能的输出。这提供了更大的灵活性和功能扩展性,使单个GPIO引脚可以适应不同的应用需求。

旋转编码器计次

代码:

#include "stm32f10x.h"                  // 设备头文件

int16_t Encoder_Count;

void Encoder_Init(void)
{
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
    
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;        // GPIO口配置为输入上拉模式
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;    // GPIO口引脚为0和1
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;     // GPIO口速度设置为50MHz
    GPIO_Init(GPIOB, &GPIO_InitStructure);               // 初始化GPIOB
    
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource0);
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource1);
    
    EXTI_InitTypeDef EXTI_InitStructure;
    EXTI_InitStructure.EXTI_Line = EXTI_Line0 | EXTI_Line1;                   // 外部中断线选择0和1
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;                     // 使能外部中断线
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;           // 外部中断模式为中断模式
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;       // 下降沿触发中断
    EXTI_Init(&EXTI_InitStructure);                               // 初始化外部中断配置
    
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);               // 中断优先级分组配置
    
    NVIC_InitTypeDef NVIC_InitStructure;
    NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;           // 中断通道选择为EXTI0
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                // 使能中断通道
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;      // 抢占优先级设置为1
    NVIC_Init(&NVIC_InitStructure);
    
    NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;           // 中断通道选择为EXTI1
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                // 使能中断通道
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;      // 抢占优先级设置为1
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;             // 子优先级设置为2
    NVIC_Init(&NVIC_InitStructure);
}

int16_t Encoder_Get(void)
{
    int16_t Temp;
    Temp = Encoder_Count;
    Encoder_Count = 0;
    return Temp;
}

void EXTI0_IRQHandler(void)
{
    if (EXTI_GetITStatus(EXTI_Line0) == SET)
    {
        /*如果出现数据乱跳的现象,可再次判断引脚电平,以避免抖动*/
        if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) == 0)
        {
            if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0)
            {
                Encoder_Count --;
            }
        }
        EXTI_ClearITPendingBit(EXTI_Line0);
    }
}

void EXTI1_IRQHandler(void)
{
    if (EXTI_GetITStatus(EXTI_Line1) == SET)
    {
        /*如果出现数据乱跳的现象,可再次判断引脚电平,以避免抖动*/
		if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0)
		{
			if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) == 0)
			{
				Encoder_Count ++;
			}
		}
		EXTI_ClearITPendingBit(EXTI_Line1);
	}
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值