欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

STM32编码器模式

程序员文章站 2022-06-11 15:53:50
...

STM32编码器模式

定时器初始化

A,B相输入捕获

        /* TIM5 configuration for Ecoder gather*/
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);  // TIM5为编码采集
        TIM_TimeBaseStructure.TIM_Period = 0xFFFF;
        TIM_TimeBaseStructure.TIM_Prescaler = 0;
        TIM_TimeBaseStructure.TIM_ClockDivision = 0;
        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
        TIM_TimeBaseInit(TIM5,&TIM_TimeBaseStructure);	        
        //TIM_ICInitStructure.TIM_Channel = TIM_Channel_1 |TIM_Channel_2;//输入捕获设置
        //TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_BothEdge; 
        //TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
        //TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
        TIM_ICInitStructure.TIM_ICFilter = 0x0F;
        TIM_ICStructInit(&TIM_ICInitStructure);
        TIM_ICInit(TIM5, &TIM_ICInitStructure);	
        //即编码器的一个脉冲量,进行了4次计数。
        TIM_EncoderInterfaceConfig(TIM5, TIM_EncoderMode_TI12,TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);
//        TIM_ClearFlag(TIM5, TIM_FLAG_Update); 
//        TIM_ITConfig(TIM5,TIM_IT_Update,ENABLE);
        TIM_SetCounter(TIM5,0);//计数清零
        TIM_Cmd(TIM5, ENABLE); 

Z相零位,外部中断

void EXTI_Configuration(void)
{
	EXTI_InitTypeDef EXTI_InitStructure;
	//Emergency stop1 interrupt
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);		//注意要打开SYSCFG时钟
	EXTI_DeInit();
	//零位   
   SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOF,EXTI_PinSource3);
	EXTI_InitStructure.EXTI_Line = EXTI_Line3;
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;
	EXTI_Init(&EXTI_InitStructure);
	EXTI_ClearFlag(EXTI_Line3) ;
	
	NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority =1;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure); 
}

编码器数据处理

void Deal_ENC(void){
  
       uint32_t angle; 
       enc_para_t.cur_plus  = TIM_GetCounter(TIM5)/4;//计数值,一个脉冲记4次
       //测试
//       if((enc_para_t.sent_sign == 1)&&(enc_para_t.per_plus != enc_para_t.cur_plus)){
//         
//         enc_para_t.cur_angle = 360*enc_para_t.cur_plus/1000;
//         Sendplus(enc_para_t.cur_angle,enc_para_t.cur_plus);
//         
//       }
  	//判断编码器的方向 逆时针转
	if(Workpara_t.enc_dir==1)
	{
		if(Workpara_t.enc_total_pluse==0)
		{
			enc_para_t.cur_angle = 0;
		}
		else
		{
			enc_para_t.cur_angle = 360-360*enc_para_t.cur_plus/Workpara_t.enc_total_pluse;
		}
	}
	else//判断编码器的方向顺时针转
	{
		if(Workpara_t.enc_total_pluse==0)
		{
			enc_para_t.cur_angle = 0;
		}
		else
		{
			enc_para_t.cur_angle = 360*enc_para_t.cur_plus/Workpara_t.enc_total_pluse;
		}
	}
        //这里判断正反正转
	if(enc_para_t.search_zero == 1)//开机找到零位了
	{
		if((enc_para_t.cur_angle>300)&&(enc_para_t.cur_angle<330))//经过了这个区域 机器为正转
		{
			enc_para_t.foreward_flag = 1;//正转标志位
			enc_para_t.backward_flag = 0;//反转标志位
		}
		if(enc_para_t.cur_angle<50)//经过这个区域 机器为反转
		{
			enc_para_t.foreward_flag = 0;//正转标志位
			enc_para_t.backward_flag = 1;//反转标志位
		}
	}
        //判断是不是在校准界面上
	if(enc_para_t.adj_status == adj_open)
	{
		//到达一定时间 并且脉冲数有变化的时候 向上传递数据
		if((enc_para_t.sent_sign == 1)&&(enc_para_t.per_plus != enc_para_t.cur_plus))
		{
                 //发送给上位机
                 Sendplus(enc_para_t.cur_angle,enc_para_t.cur_plus);
		}
	}
        angle = enc_para_t.cur_angle;
        //可以检测零位
	if(user_para_t.mac_speed_one_circle >=1)
	{
		if(angle<=10)//说明过了一次零位
		{
			user_para_t.mac_speed_one_circle = 0;
			user_para_t.mac_speed_circle++;
		}
	}
	else
	{
		//准备过零
		if(angle>350)
		{
			user_para_t.mac_speed_one_circle = 1;//下一次可以计圈
		}
	}
         //开始计算速度
	if(user_para_t.mac_speed_sign)
	{

		user_para_t.mac_speed = 60*user_para_t.mac_speed_circle+(angle-user_para_t.mac_speed_angle)/6;
		if(user_para_t.mac_speed>1500)
		{
			user_para_t.mac_speed = user_para_t.mac_per_speed;
		}
		else
		{
			user_para_t.mac_per_speed = user_para_t.mac_speed;
		}
		user_para_t.mac_speed_sign = 0;
		user_para_t.mac_speed_circle = 0;
		user_para_t.mac_speed_angle = angle;
	}
      //Workpara_t.MachineSpeed   = enc_para_t.cur_plus/Workpara_t.enc_total_pluse;//速度1秒算一次
      enc_para_t.per_plus = enc_para_t.cur_plus;//脉冲赋值 用于编码器校准界面

}

零位数据处理,外部中断

void EXTI3_IRQHandler(void)//一圈进一次 
{                
    if (EXTI_GetITStatus(EXTI_Line3) != RESET)
    {
       EXTI_ClearITPendingBit(EXTI_Line3);
	//角度和脉冲直接清零 防止误入
	enc_para_t.cur_angle = 0;
	enc_para_t.cur_plus = 0;
	enc_para_t.search_zero = 1;//开机找到零位
        TIM_SetCounter(TIM5,0);//脉冲计数清零
	//机器为正转了
	if(enc_para_t.foreward_flag == 1)
	{
		//机器进入反转区域
		enc_para_t.foreward_flag = 0;//正转标志位变为0
		enc_para_t.backward_flag = 1;//反转标志位1
	}
	else if(enc_para_t.backward_flag == 1)//机器为反转
	{
		//机器进入正转区域
		enc_para_t.foreward_flag = 1;
		enc_para_t.backward_flag = 0;

	}

	//在编码脉冲校准的时候
	if(enc_para_t.adj_status == adj_open)
	{
		//将当前脉冲赋值给总脉冲
		enc_para_t.adj_zero = 1;//已经过零了
	}
    }            
}

STM32编码器模式
STM32编码器模式
STM32编码器模式

相关标签: 单片机 stm32