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

发布于:2024-05-07 ⋅ 阅读:(23) ⋅ 点赞:(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);        //软件触发外部中断
FlagStatus EXTI_GetFlagStatus(uint32_t EXTI_Line);
void EXTI_ClearFlag(uint32_t EXTI_Line);
ITStatus EXTI_GetITStatus(uint32_t EXTI_Line);        //获取中断标志位是否被置1
void EXTI_ClearITPendingBit(uint32_t EXTI_Line);        //清除中断标志位

void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);        //配置优先级分组:抢占优先级和响应优先级
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