STM32单相编码器(龙邱512线)

文章介绍了编码器的基本概念,包括增量型和绝对值型编码器的工作原理,并详细阐述了单相编码器如何与单片机通过TIM5模块进行连接,用于测量脉冲数量、判断旋转方向和速度。在代码示例中展示了TIM5的初始化配置和中断处理函数,用于捕获编码器的脉冲信号。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

编码器(encoder)是将信号或数据进行编制、转换为可用以通讯、传输和存储的信号形式的设备。按照外形可以分为实心轴和空心轴;按照工作原理编码器可分为增量式和绝对式两类。增量式编码器是将位移转换成周期性的电信号,再把这个电信号转变成计数脉冲,用脉冲的个数表示位移的大小。绝对式编码器的每一个位置对应一个确定的数字码,因此它的示值只与测量的起始和终止位置有关,而与测量的中间过程无关。 

增量型:就是每转过单位的角度就发出一个脉冲信号(也有发正余弦信号,然后对其进行细分,斩波出频率更高的脉冲),通常为A相、B相、Z相输出,A相、B相为相互延迟1/4周期的脉冲输出,根据延迟关系可以区别正反转,而且通过取A相、B相的上升和下降沿可以进行2或4倍频;Z相为单圈脉冲,即每圈发出一个脉冲。

绝对值型:就是对应一圈,每个基准的角度发出一个唯一与该角度对应二进制的数值,通过外部记圈器件可以进行多个位置的记录和测量。

单相联接:只有A相用于测速,方向靠DIR判断

A、B两相联接,可判断正反向和测速。

A、B、Z三相联接,用于带参考位修正的位置测量。 

我这里用的是单相的龙邱512线的,每转一圈编码器输出512个脉冲 ,根据这个编码器输出脉冲就可以用单片机IO测出脉冲个数,进而判断编码器转了几圈以及速度。

编码器接线:编码器A相接单片机的TIM5_CH1,对应接口为PA0,编码器的DIR可以接PA1读取正转反转电平。

void TIM5_CH1_Input_Init(u16 arr,u16 psc)
{
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_ICInitTypeDef TIM_ICInitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	GPIO_InitTypeDef GPIO_InitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5,ENABLE);//使能TIM5时钟
	
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;//管脚设置
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPD;	 //设置下拉输入模式
	GPIO_Init(GPIOA,&GPIO_InitStructure); 	   /* 初始化GPIO */
	
	TIM_TimeBaseInitStructure.TIM_Period=arr;   //自动装载值
	TIM_TimeBaseInitStructure.TIM_Prescaler=psc; //分频系数
	TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
	TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; //设置向上计数模式
	TIM_TimeBaseInit(TIM5,&TIM_TimeBaseInitStructure);	
	
	TIM_ICInitStructure.TIM_Channel=TIM_Channel_1; //通道1
	TIM_ICInitStructure.TIM_ICFilter=0x00;  //滤波
	TIM_ICInitStructure.TIM_ICPolarity=TIM_ICPolarity_Rising;//捕获极性
	TIM_ICInitStructure.TIM_ICPrescaler=TIM_ICPSC_DIV1; //分频系数
	TIM_ICInitStructure.TIM_ICSelection=TIM_ICSelection_DirectTI;//直接映射到TI1
	TIM_ICInit(TIM5,&TIM_ICInitStructure);
	TIM_ITConfig(TIM5,TIM_IT_Update|TIM_IT_CC1,ENABLE);
	
	NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn;//中断通道
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;//抢占优先级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority =0;		//子优先级
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);
		
	TIM_Cmd(TIM5,ENABLE); //使能定时器
	
}

/*******************************************************************************
  * @brief  TIM5_CH1中断函数
  * @param  无
  * @retval 无
*******************************************************************************/
void TIM5_IRQHandler(void)
{
	if((TIM5_CH1_CAPTURE_STA&0x80)==0) //还未成功捕获
	{
		if(TIM_GetITStatus(TIM5,TIM_IT_Update)) //发生更新中断
		{
			if(TIM5_CH1_CAPTURE_STA&0X40)//捕获到了高电平
			{
				if((TIM5_CH1_CAPTURE_STA&0x3f)==0x3f) //高电平时间太长
				{
					TIM5_CH1_CAPTURE_STA|=0x80; //标志一次捕获成功
					TIM5_CH1_CAPTURE_VAL=0xffff;
				}
				else
				{
					TIM5_CH1_CAPTURE_STA++;
				}
			}
		}
		if(TIM_GetITStatus(TIM5,TIM_IT_CC1)) //发生捕获中断
		{
			if(TIM5_CH1_CAPTURE_STA&0X40)//捕获到了低电平
			{
				TIM5_CH1_CAPTURE_STA|=0x80; //成功捕获一次高电平
				TIM5_CH1_CAPTURE_VAL=TIM_GetCapture1(TIM5);
				TIM_OC1PolarityConfig(TIM5,TIM_ICPolarity_Rising); //设置上升沿捕获
			}
			else
			{
				TIM5_CH1_CAPTURE_STA=0;
				TIM5_CH1_CAPTURE_VAL=0;
				TIM5_CH1_CAPTURE_STA|=0x40; //捕获到高电平 标志
				TIM_Cmd(TIM5,DISABLE);
				TIM_SetCounter(TIM5,0); //定时器初值为0
				TIM_OC1PolarityConfig(TIM5,TIM_ICPolarity_Falling); //设置下降沿捕获
				TIM_Cmd(TIM5,ENABLE);
			}
		}
	}
	TIM_ClearITPendingBit(TIM5,TIM_IT_CC1|TIM_IT_Update);
}

main函数死循环捕获脉冲就行

while(1)
	{
		if(TIM5_CH1_CAPTURE_STA&0x80) //成功捕获
		{
			temp=temp++;
			TIM5_CH1_CAPTURE_STA=0; //开始下一次捕获
		}
		OLED_ShowSignedNum(1, 7, temp, 5);
		
	}

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值