STM32编码器模式

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编码器模式_第1张图片
STM32编码器模式_第2张图片
STM32编码器模式_第3张图片

你可能感兴趣的:(单片机,stm32)