三、代码实现
encoder.c
- /* 此文件为编码器电机闭环调试,包括速度环和位置环
- * 配置:TIM2(PA0、PA1):编码器模式
- * TIM1-CH1(PE9):PWM输出
- * IN1:PF1
- * IN2: PF2
- * ENABLE: PF0
- * 使用方法:1、初始化Motor_Init()
- * 2、发送电流SetCurrent()
- */
- #include "encoder.h"
- encoderMotor_t encoderMoto[ENCODER_MOTO_COUNT]; //编码器电机结构体
- pid_t Encoder_Motor_Pid_Pos[ENCODER_MOTO_COUNT]; //编码器电机位置环PID结构体
- pid_t Encoder_Motor_Pid_Spd[ENCODER_MOTO_COUNT]; //编码器电机速度环PID结构体
- void Motor_Init(void)
- {
- HAL_TIM_Encoder_Start(&htim2, TIM_CHANNEL_ALL); //开启编码器定时器
- __HAL_TIM_ENABLE_IT(&htim2,TIM_IT_UPDATE); //开启编码器定时器更新中断,防溢出处理
- __HAL_TIM_SET_COUNTER(&htim2, 10000); //编码器定时器初始值设定为10000
-
- encoderMoto[0].IOControl.htim_pwm = htim1;
- encoderMoto[0].IOControl.IN1_Port = GPIOF;
- encoderMoto[0].IOControl.IN2_Port = GPIOF;
- encoderMoto[0].IOControl.IN1_Pin = GPIO_PIN_1;
- encoderMoto[0].IOControl.IN2_Pin = GPIO_PIN_2;
- }
- //
- /* 编码器电机发送电流函数
- * motor:编码器电机参数结构体
- * val:转动的速度或角度,SPEED最大为110,POSITION一圈为3960
- * mode:模式选择:速度环:SPEED
- * 位置环:POSITION
- */
- void SetCurrent(encoderMotor_t *motor, int32_t val, uint32_t mode)
- {
- float pos_output,spd_output;
- if(mode == 1)
- spd_output = pid_calc(&Encoder_Motor_Pid_Spd[0], motor->speed, val);
- else
- {
- pos_output = pid_calc(&Encoder_Motor_Pid_Pos[0], motor->totalAngle, val);
- spd_output = pid_calc(&Encoder_Motor_Pid_Spd[0], motor->speed, pos_output);
- }
- if(spd_output > 0)
- {
- HAL_GPIO_WritePin(motor->IOControl.IN1_Port, motor->IOControl.IN1_Pin, GPIO_PIN_SET); //控制正反转
- HAL_GPIO_WritePin(motor->IOControl.IN2_Port, motor->IOControl.IN2_Pin, GPIO_PIN_RESET);
- __HAL_TIM_SET_COMPARE(&motor->IOControl.htim_pwm, TIM_CHANNEL_1, (uint32_t)(spd_output));
- }
- else
- {
- HAL_GPIO_WritePin(motor->IOControl.IN1_Port, motor->IOControl.IN1_Pin, GPIO_PIN_RESET);
- HAL_GPIO_WritePin(motor->IOControl.IN2_Port, motor->IOControl.IN2_Pin, GPIO_PIN_SET);
- __HAL_TIM_SET_COMPARE(&motor->IOControl.htim_pwm, TIM_CHANNEL_1, (uint32_t)(-spd_output));
- }
-
- }
- void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
- {
- static int16_t count = 0;
- if(htim->Instance==htim6.Instance) //1ms中断
- {
- count++;
- if(count >= 10)
- {
- count = 0;
- int16_t pluse = COUNTERNUM - RELOADVALUE/2;
- encoderMoto[0].totalAngle = pluse + encoderMoto[0].loopNum * RELOADVALUE/2;
- encoderMoto[0].speed = (float)(encoderMoto[0].totalAngle - encoderMoto[0].lastAngle)/(4*PLUSE_OF_CIRCLE*RR)*6000; //进行速度计算,根据前文所说的,4倍频,编码器13位,减速比30,再乘以6000即为每分钟输出轴多少转
- encoderMoto[0].lastAngle = encoderMoto[0].totalAngle; //更新转过的圈数
- }
- }
- else if(htim->Instance == htim2.Instance) //如果是编码器更新中断,即10ms内,脉冲数超过了计数范围,需要进行处理
- {
- if(COUNTERNUM < 10000) encoderMoto[0].loopNum++;
- else if(COUNTERNUM > 10000) encoderMoto[0].loopNum--;
- __HAL_TIM_SetCounter(&htim2, 10000); //重新设定初始值
- }
- }
|