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;//已经过零了
}
}
}