Bootstrap

STM32 旋转编码器

 旋转编码器简介

        旋转编码器:用来测量位置、速度或旋转方向的装置,当其旋转轴旋转时,其输出端可以输出与旋转速度和方向对应的方波信号,读取方波信号的频率和相位信息即可得知旋转轴的速度和方向

        类型:机械触点式/霍尔传感器式/光栅式

硬件电路

接线图:

代码配置

这里的中断配置与上一章的对射式红外传感器配置一样,只需要改一下引脚,以及通道配置,这里配置了两个引脚,所以需要配置两个中断通道(NVIC),写两个中断函数。

void Encoder_init(void)
{
		//------------------------定义结构体变量-----------------------------------
	
	GPIO_InitTypeDef GPIO_InitStructure;								//定义GPIO结构体变量
	EXTI_InitTypeDef EXTI_InitStructure;								//定义EXTI结构体变量
	NVIC_InitTypeDef NVIC_InitStructure;								//定义NVIC结构体变量
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//开启GPIO的时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);	//开启AFIO的时钟
	
	//---------------------GPIO配置--------------------------------------
	
	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初始化
	
	//---------------------GPIO配置--------------------------------------
	
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource0);//将中断线与GPIO引脚连接
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource1);//将中断线与GPIO引脚连接
	//---------------------EXTI配置--------------------------------------
	
	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配置--------------------------------------
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//中断分组,这里放到模块函数里了,一般情况放在主函数第一行(如上一章按键中断)
	
	//---------------------NVIC配置--------------------------------------
	
	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_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;				//选择中断通道
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;							//使能中断通道
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;		//抢占优先级配置
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;					//响应优先级配置
	
	NVIC_Init(&NVIC_InitStructure);
	
	//---------------------NVIC配置--------------------------------------
	
	
}

中断函数:

        中断函数编程:在中断函数里,不要执行耗时过长的代码,中断函数要简短快速最好不要用delay函数,因为中断时处理突发事情的,如果为了突发的事情在中断函数呆着出不来了,主程序就会收到严重的阻塞

int16_t Encoder_Count;
//返回数据
int16_t Encoder_Get(void)
{
 return Encoder_Count;
 
}


//中断函数
void EXTI0_IRQHandler(void)
{
	//判断中断是否触发
	if(EXTI_GetITStatus(EXTI_Line0) == SET)
	{
		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_0) == 0)
		{
			Encoder_Count++;
		}
		//清除标志位
		EXTI_ClearITPendingBit(EXTI_Line1);
	}
	
}

主函数:

#include "Encoder.h"
int main(void)
{
	LED_Init();
	OLED_Init();
	Encoder_init();
	OLED_ShowString(1, 3, "Num:");
	while(1)
    {
	
	
	    OLED_ShowSignedNum(1, 6, Encoder_Get(), 5);
	

    }	
	
}

悦读

道可道,非常道;名可名,非常名。 无名,天地之始,有名,万物之母。 故常无欲,以观其妙,常有欲,以观其徼。 此两者,同出而异名,同谓之玄,玄之又玄,众妙之门。

;