步进电机的控制
先是步进电机的头文件
/*
------------------------------------------------------------------------
| 文件名 :motor.h
| 文件描述 :本文件用于步进电机相关结构体的定义和函数接口
| 作者 : pinocchio
| 创建时间 :19.4.26
------------------------------------------------------------------------
修改日期 :19.4.26
修改人 :pinocchio
------------------------------------------------------------------------
**************************************************************************
* 1. 本代码基于STM32F427IIH(2018RM开发板A型)开发,编译环境为keil
* 2. 本代码只适用于倒立摆,不建议用于其他用途
* 3.本代码最终解释权归哈尔滨工业大学(深圳)所有
* 4.请勿转载!!!!!!!!!!!
*
* Copyright (c) 2019 2019哈尔滨工业大学(深圳) 版权所有
**************************************************************************
*/
#ifndef MOTOR_H_
#define MOTOR_H_
#define rotate 1
#define contrarotate -1
#define PI 3.1416
typedef struct
{
struct
{
float KP;
float KI;
float KD;
float error;
float last_error;
float integral;
}pid;
//就pid控制的定义
float outputMAX;
//防止输出速度过大,在1ms不能够输出
float Ref_speed;
//电机的目标速度
int round_count;
//用于脉冲的计数
float rotate_times;
//由目标速度换算出的输出脉冲数目
}Motor;
//定义电机的结构体
extern int tim_i;
void size_init(void);
extern Motor motor;
void motor_init(void);
void Rotate(void);
void Rontrarotate(void);
void motor_transmit(void);
float absolute_value(float i);
void auto_rotate(void);
//函数接口
#endif
然后就是电机的控制.c文件
/*
------------------------------------------------------------------------
| 文件名 :motor.c
| 文件描述 :本文件用于步进电机控制
| 作者 : pinocchio
| 创建时间 :19.4.26
------------------------------------------------------------------------
修改日期 :19.4.26
修改人 :pinocchio
------------------------------------------------------------------------
**************************************************************************
* 1. 本代码基于STM32F427IIH(2018RM开发板A型)开发,编译环境为keil
* 2. 本代码只适用于倒立摆,不建议用于其他用途
* 3.本代码最终解释权归哈尔滨工业大学(深圳)所有
* 4.请勿转载!!!!!!!!!!!
*
* Copyright (c) 2019 2019哈尔滨工业大学(深圳) 版权所有
**************************************************************************
*/
#include "motor.h"
#include "main.h"
#include "tim.h"
#include "struct.h"
#include "encoder.h"
Motor motor;
Struct size;
//对电机结构体和尺寸的定义
void motor_init(void)
{
motor.pid.KP = 10 ;
motor.pid.KI = 0;
motor.pid.KD = 0;
motor.outputMAX = 0;
motor.Ref_speed = 0;
motor.round_count=0;
motor.rotate_times=0;
motor.pid.error = 0;
motor.pid.last_error = 0;
motor.pid.integral = 0;
}
//电机相关数据初始化函数
void size_init(void)
{
size.L = 0.1465;//编码器对应长度
size.R = 0.195;//步进电机对应长度
}
//尺寸的初始化。这里后面根据目标修改
void motor_transmit(void)
{
motor.rotate_times = (1.60 * motor.Ref_speed) / (2*PI*size.L) ;
//计算出来达到目标速度需要输出多少个脉冲
if(motor.rotate_times >= 0.5 )//判断正转
{
while (motor.round_count < motor.rotate_times)
{
Rotate();
}
motor.round_count=0;
}
else if (motor.rotate_times <= - 0.5 )//判断反转
{
while (motor.round_count > motor.rotate_times)
{
Rontrarotate();
}
motor.round_count=0;
}
else if (motor.rotate_times < 0.5&&motor.rotate_times > -0.5)
{
}
//如果脉冲数是0.6,那它会发一次脉冲,如果是0.4就不发脉冲
//如果不写这个的话会导致0.01也会发1个脉冲0.99也是发一个脉冲
//而1ms发一次脉冲,会导致有一个固定速度,导致难以控制
}
void Rotate(void)
{
HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_1);
//这里是使能一次PWM,发送一个脉冲
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_SET);
//这里是输出方向的
motor.round_count ++;
}
//电机正向旋转的函数
void Rontrarotate(void)
{
HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_1);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET);
motor.round_count --;
}
//电机反向旋转的函数
float absolute_value(float i)
{
if(i>= 0 ) return i;
else return -i;
}
//用于取绝对值的函数
void auto_rotate(void)
{
motor.pid.last_error = motor.pid.error;
//此处之所以要到0.8才控制是因为倒立摆要旋转到一定角度才可以控制
//此处之所以只控制到0.995是因为如果已经控制完毕,就不发旋转信号,这样便于控制
if( angle_position >= 0.80*PI&& angle_position <= 0.995*PI)
{
//你是正旋转的函数
motor.pid.error = -(PI - absolute_value(angle_position));
motor.Ref_speed = -(PI - absolute_value(angle_position)) * motor.pid.KP + motor.pid.KI * motor.pid.integral + motor.pid.KD*( motor.pid.error-motor.pid.last_error) ;
motor.pid.integral += motor.pid.error ;
}
if( angle_position <= -0.80*PI&& angle_position >= -0.995*PI)
{
motor.pid.error = PI - absolute_value(angle_position);
motor.Ref_speed = (PI - absolute_value(angle_position))*motor.pid.KP + motor.pid.KI * motor.pid.integral + motor.pid.KD*( motor.pid.error-motor.pid.last_error) ;
motor.pid.integral += motor.pid.error ;
}
if( (angle_position >= -0.80*PI && angle_position <= 0.80*PI)||angle_position >= 0.995*PI||angle_position <= -0.995*PI)
{
motor.Ref_speed = 0;
}
//此处是为了调试小角度时控制写的,因为摆一落下就没有力了,便于控制
}
//倒立摆控制函数
void start_rotate(void)
{
}
//用于起摆的函数,这里就不写了。留给大家写
那么现在步进电机的控制就写完了
版权声明:本文为weixin_44109556原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。