【stm32-3】对射式红外传感器计次&旋转编码器计数

5 篇文章 0 订阅

1.对射式红外传感器计次 

void EXTI_DeInit(void);        //把EXTI配置都清除,恢复到上电默认状态
void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct//指向EXTI_InitTypeDef结构体的指针,其中包含了EXTI外设的基本信息);        //初始化
void EXTI_StructInit(EXTI_InitTypeDef* EXTI_InitStruct);        //
void EXTI_GenerateSWInterrupt(uint32_t EXTI_Line);        //软件触发外部中断
EXTI_GetITStatus(EXTI_Line0)==SET)    //用于判断在该中断函数上的中断是否发生,若发生,标志位置1.
void EXTI_ClearITPendingBit(uint32_t EXTI_Line);        //清除中断标志位

void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);        //配置优先级分组:抢占优先级和响应优先级(NVIC_PriorityGroup_2);
void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct//指向NVIC_InitTypeDef结构体的指针,该设备中含有NVIC外设的信息);        //根据NVIC_InitStruct中指定的参数初始化NVIC外设

(1)main.c

#include "Device/Include/stm32f10x.h"   // Device header
#include "Delay.h"
#include "OLED.h"
#include "countsensor.h"
int main(void)
{
	OLED_Init();
	countsensor_Init();
	OLED_ShowString(1,1,"Count:");

	while(1)
	{
		OLED_ShowNum(1,7,countsensor_Get(),5);
	}
}

(2)countsensor.c

#include "Device/Include/stm32f10x.h"   // Device header
uint16_t countsensor_count;
void countsensor_Init()
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
	
	GPIO_InitTypeDef GPIO_Initstructure;
	GPIO_Initstructure.GPIO_Mode=GPIO_Mode_IPU;
	GPIO_Initstructure.GPIO_Pin=GPIO_Pin_14;
	GPIO_Initstructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_Initstructure);
	
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource14);//AFIO:选择要用做外部中断线源的GPIO端口:指定要配置的外部中断线
	EXTI_InitTypeDef EXTI_Initstructure;
	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_PriorityGroupConfig(NVIC_PriorityGroup_2);
	NVIC_InitTypeDef NVIC_Initstructure;
	NVIC_Initstructure.NVIC_IRQChannel=EXTI15_10_IRQn;
	NVIC_Initstructure.NVIC_IRQChannelCmd=ENABLE;
	NVIC_Initstructure.NVIC_IRQChannelPreemptionPriority=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)	//用于判断在该中断函数上的中断是否发生,若发生,标志位置1.
	{
		countsensor_count++;
		EXTI_ClearITPendingBit(EXTI_Line14);	//清除中断标志位,防止单片机检测到中断标志,重复进入中断
	}
}

 (3)countsensor.h

#ifndef __COUNT_SENSOR_H
#define __COUNT_SENSOR_H

void countsensor_Init(void);
uint16_t countsensor_Get(void);
//中断函数不需要调用,自动执行
#endif

 2.旋转编码器计数

(1)main.c

#include "Device/Include/stm32f10x.h"   // Device header
#include "Delay.h"
#include "OLED.h"
#include "encoder.h"
int16_t Num;
int main(void)
{
	OLED_Init();
	encode_Init();
	OLED_ShowString(1,1,"Num:");
	while(1)
	{
		Num+=encoder_Get();
		OLED_ShowSignedNum(1,5,Num,5);
	}
}

(2)encoder.c

#include "Device/Include/stm32f10x.h"   // Device header
int16_t encodercount;
void encode_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_Initstructure.GPIO_Pin=GPIO_Pin_0 | GPIO_Pin_1;
	GPIO_Initstructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_Initstructure);
	
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource0);	//函数不能|,|后是两个数操作之后的值
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource1);
	//AFIO:选择要用做外部中断线源的GPIO端口:指定要配置的外部中断线
	
	EXTI_InitTypeDef EXTI_Initstructure;
	EXTI_Initstructure.EXTI_Line=EXTI_Line0|EXTI_Line1;
	EXTI_Initstructure.EXTI_LineCmd=ENABLE;
	EXTI_Initstructure.EXTI_Mode=EXTI_Mode_Interrupt;
	EXTI_Initstructure.EXTI_Trigger=EXTI_Trigger_Falling;	//下降沿触发
	EXTI_Init(&EXTI_Initstructure);
	//指向EXTI_InitTypeDef结构体的指针,其中包含了EXTI外设的基本信息   初始化
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	NVIC_InitTypeDef NVIC_Initstructure;
	NVIC_Initstructure.NVIC_IRQChannel=EXTI0_IRQn;
	NVIC_Initstructure.NVIC_IRQChannelCmd=ENABLE;
	NVIC_Initstructure.NVIC_IRQChannelPreemptionPriority=1;
	NVIC_Initstructure.NVIC_IRQChannelSubPriority=1;
	NVIC_Init(&NVIC_Initstructure);
	//指向NVIC_InitTypeDef结构体的指针,该设备中含有NVIC外设的信息
	//根据NVIC_InitStruct中指定的参数初始化NVIC外设
	NVIC_Initstructure.NVIC_IRQChannel=EXTI1_IRQn;
	NVIC_Initstructure.NVIC_IRQChannelCmd=ENABLE;
	NVIC_Initstructure.NVIC_IRQChannelPreemptionPriority=2;
	NVIC_Initstructure.NVIC_IRQChannelSubPriority=2;
	NVIC_Init(&NVIC_Initstructure);
	
}
int16_t encoder_Get(void)
{
	int16_t temp;
	temp=encodercount;
	encodercount=0;
	return temp;
}
void EXTI0_IRQHandler(void)		//????????????
{
	if(EXTI_GetITStatus(EXTI_Line0)==SET)	//用于判断在该中断函数上的中断是否发生,若发生,标志位置1.
	{
		if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1)==0)
		{
			encodercount--;
		}
		EXTI_ClearITPendingBit(EXTI_Line0);	//清除中断标志位
	}
}
void EXTI1_IRQHandler(void)
{
	if(EXTI_GetITStatus(EXTI_Line1)==SET)	//中断标志位置1(SET),程序会跳到中断函数
	{
		if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_0)==0)
		{
			encodercount++;
		}
		EXTI_ClearITPendingBit(EXTI_Line1);	//清除中断标志位
	}
}

(3)encoder.h

#ifndef __ENCODER_H
#define __ENCODER_H

void encode_Init(void);
int16_t encoder_Get(void);

#endif

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
STM32单片机配合红外传感器进行计次原理通常涉及以下几个步骤: 1. **选择传感器**:首先,你需要一个红外(IR)传感器,比如常见的IR-recv模块,它能检测到红外信号的变化。 2. **连接硬件**:将IR传感器的中断引脚连接到STM32的输入引脚,以便在接收到红外脉冲时产生中断。例如,你可以连接到PA0或PB6这样的GPIO口。 3. **初始化中断**:在STM32的初始化阶段,配置中断控制器和GPIO为中断模,并设置适当的中断服务函数(ISR)来处理接收到的红外脉冲。 4. **中断服务函数(ISR)**:当红外信号变化时,ISR会被调用。在这个函数中,你需要检查传感器的状态(如接收到信号或未接收到),然后增加计数器或者设置标志位。 5. **计数或逻辑判断**:在中断服务函数中,根据红外脉冲的频率,你可以简单地计数,每接收到一个脉冲就递增计数器,或者根据特定的红外编码执行特定的操作,比如控制LED闪烁或发送数据。 6. **数据处理或显示**:在非中断上下文中,周期性地检查计数器或标志位的结果,可能的话,将计数值存储到存储器或通过串口发送出去。 7. **可能的错误处理**:确保有适当的错误处理机制,比如红外接收不连续或长时间没有接收到信号,防止误触发和计数溢出。 8. **电源管理**:考虑到电池寿命或功耗,确保在空闲时关闭不必要的功能,并使用低功耗模降低待机时的电流消耗。 **相关问题**: 1. STM32如何配置中断以响应红外传感器? 2. 如何在STM32中正确处理中断服务函数以计数红外脉冲? 3. 红外传感器计次时如何避免误触发和数据丢失?

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值