金牌会员
 
- 积分
- 1635
- 金钱
- 1635
- 注册时间
- 2012-8-28
- 在线时间
- 71 小时
|
发表于 2020-4-25 15:39:32
|
显示全部楼层
#ifndef _motor_h
#define _motor_h//两相四线步进电机
///////////
#include "stm32f10x.h"
#include "delay.h"
#include "sys.h"//io引用
////////////////////////////////////////
//作者QQ750273008 祁成 2018.5.29
////////////////////////////////////////
//电机类型:只能选一种
#define phase_two//两相四线步进电机
// #define phase_four//四相五线步进电机
////////////////////////////////////////
//双拍
#define use_motor_4code 1 //0:8拍模式, 1:4拍模式
typedef struct
{
u8 num; //电机轴的编号0~0xFF
const u8 *drive_code; //步进电机节拍:停止+8种节拍
u8 rotate_val; //电机旋转值
int add; //当前绝对位置
int go; //预计移动
//加减速参数
u32 dead_us; //最小死区时间(最快速度)//迷你滑台1ms
u32 delay_ms; //电机转一拍停留时间(可以为0)
u16 VF; //加减速曲线,(值越大,加减速越快)
}motors;
////////////////////////////////////////
//电机默认参数表
extern motors zhou;
//当前可用轴
//extern motors zhou1;//x->dead_us =950 ;
//extern motors zhou2;//x->dead_us =950 ;
extern motors X;//x->dead_us =950 ;
extern motors Y;
extern motors Z;//电机Z轴
extern motors A;
extern motors B;
extern motors C;
extern motors D;
//////////////////////////////////////////
void motor_init(void);//轴初始化
u8 motorGoto(motors *x,int Goto);//轴定位
u8 motorGo(motors *x,long int go);//轴移动
void io_out(motors *x,u8 code);//输出驱动编码
void motor_cmd(motors *x,FunctionalState NewState);//电机失效(自由运动)
//////////////
//////////////
//io
//#define motor1_1 PAout(12) //PB12 左轮 A相 IN1
//#define motor1_2 PAout(13) //PB13 左轮 A'相 IN2
//#define motor1_3 PAout(14) //PB14 左轮 B相 IN3
//#define motor1_4 PAout(15) //PB15 左轮 B'相 IN4
//#define motor2_1 PBout(11) //PB11 右轮 A相 IN1
//#define motor2_2 PBout(10) //PB10 右轮 A'相 IN2
//#define motor2_3 PBout(1) //PB1 右轮 B相 IN3
//#define motor2_4 PBout(0) //PB0 右轮 B'相 IN4
#endif
////////////////////////// 下面是c文件
#include "stm32f10x.h"
#include "motor.h"//两相四线步进电机
#include "delay.h"//延时
//两相四线步进电机 56A9
#ifdef phase_two//两相四线步进电机(D0:A) ,(D1:A非), (D2:B), (D3:B非)
//8拍 A AB B A'B A' A'B' B' AB'
static const u8 motor_code[9]={0X00,0x01,0x05,0X04,0X06,0X02,0X0A,0X08,0X09};//步进电机,停止+8种节拍
// static const u8 motor_code[9]={0X00,0x08,0x0A,0X02,0X06,0X04,0X05,0X01,0X09};//步进电机,停止+8种节拍
#endif
//4拍 AB A'B A'B' AB'
//static const u8 motor_4code[9]={0X00,0x0A,0X06,0X05,0X09};//停止+4种节拍
//四相五线步进电机
#ifdef phase_four//四相五线步进电机
//8拍 A AB B BC C CD D DA
static const u8 motor_code[9]={0X00,0x01,0x03,0X02,0X06,0X04,0X0C,0X08,0X09};//步进电机,停止+8种节拍
#endif
//电机默认参数表
static motors zhou={
0,//电机轴的编号0~0xFF
motor_code, //步进电机节拍:停止+8种节拍
0,//电机当前节拍位置
0,//当前绝对位置
0,//预计移动
950,//最小死区时间(最快速度)//迷你滑台1000us
0,//电机转一拍停留时间(可以为0)
25//加减速曲线,(值越大,加减速变化越大)
};
//当前可用轴
motors X={0x01,motor_code,0,0,0,1000,0,50};//x->dead_us =950 ;
motors Y={0x02,motor_code,0,0,0,1000,0,50};//x->dead_us =950 ;
motors Z={0x03,motor_code,0,0,0,1000,0,50};//x->dead_us =950 ;
motors A={0x04,motor_code,0,0,0,1000,0,50};//x->dead_us =950 ;
motors B={0x05,motor_code,0,0,0,1000,0,50};//x->dead_us =950 ;
motors C={0x06,motor_code,0,0,0,1000,0,50};//x->dead_us =950 ;
//extern motors zhou1;//x->dead_us =950 ;
//extern motors zhou2;
///////////////////////////
///////////////////////////
/*初始化*/
void motor_init(void)//初始化
{
//添加并初始化需要用的轴
//X=zhou;
// X.num=0x01;
// Y.num =0x02;
// Y.delay_ms=0;
motorGoto(&X,0);
motorGoto(&Y,0);
motorGoto(&Z,0);
delay_s(5);
motorGoto(&X,1);
motorGoto(&Y,1);
motorGoto(&Z,1);
}
/*轴定位*/
u8 motorGoto(motors *x,int Goto)//轴定位
{
int i;
i=Goto - x->add;//偏移量;
motorGo(x,i);//轴移动(定位值 减 当前位置)
return 0;
}
/*轴移动*/
u8 motorGo(motors *x,long int go)//轴移动
{
u8 rotate,drive_val;//节拍,线圈驱动值
long int i;//脉冲数
if(go>0)//正转
{
x->go=go;//距离脉冲
for(i=0;i < x->go;i++)//正转循环
{
//得到下一个节拍,齿轮
rotate=(x->rotate_val + (1+use_motor_4code))%9;//当前节拍 + 偏移节拍
//一拍是否小于一拍
if(rotate < (1+use_motor_4code))//一节拍值
{
rotate = 1 + use_motor_4code;//绕过电机停止的编码值0x00,齿轮
}
drive_val=x->drive_code[rotate];//得到电机8拍驱动编码
//////////////////////////////
//输出:
io_out(x,drive_val);//输出驱动编码
x->rotate_val=rotate; //记录电机最后一次节拍编号
}
//记录当前地址
x->add += go;
return 0;
}
else//反转
{
x->go=go;//距离脉冲
for(i=0;i > x->go;i--)//负数
{
//补一圈回到原点,减1步节拍。
rotate = (x->rotate_val + 9-1-use_motor_4code)%9;
///////////////
//旋转纠错
if(use_motor_4code) rotate += rotate%2 ;//回到双4拍的节拍上
if(rotate==0)
{
rotate=8;//绕过电机停止的编码值0x00
}
drive_val=x->drive_code[rotate];//得到电机8拍驱动编码
//////////////////////////////
//输出:
io_out(x,drive_val);//输出驱动编码
x->rotate_val=rotate; //记录电机最后一次节拍编号
}
//记录当前地址
x->add += go;
return 0;
}
}
void motor_cmd(motors *x,FunctionalState NewState)//电机失效(自由运动)
{
if(NewState==ENABLE)
{
io_out(x,0x08);//轴控制
}
else
{
io_out(x,0x00);//取消轴控制
}
// io_out(&zhou2,0x00);//取消轴控制
/////////////////////////////////
// u32 i,j,code=0x0f;
// //////////////////////////////
// //输出:
// GPIOB->ODR&=0XFFFF0FFF,//轴1
// GPIOB->BSRR = code<<12;
//
// GPIOB->ODR&=0XFFFFF3FC,//轴2
// i=code & 0x0C;//d3,d2
// i=i << 8;//d10
// j=code & 0x03;
// i |= j;
// GPIOB->BSRR = i;
}
void io_out(motors *x,u8 drive_code)//输出驱动编码
{
u32 i=0,j;
switch(x->num)
{
//////////////////////////////
//输出:
case 0x01:GPIOB->ODR&=0XFFFF0FFF; //轴1
GPIOB->BSRR = drive_code<<12; //PB15,14,13,12
break;
case 0x02:GPIOB->ODR&=0XFFFFF3FC; //轴2
i=drive_code & 0xC; //1100
i=i << 8; //PB11,PB10
j=drive_code & 0x3;
i |= j; //PB1,B0
GPIOB->BSRR = i; //PB11,10,1,0
break;
// case 0x03:GPIOB->ODR&=0XFFFF0FFF,
// GPIOB->BSRR |=code<<12;break;
}
//////////////////////////////
//停留时间:
//电机转一拍停留时间
if(x->dead_us > 0)delay_us(x->dead_us);//最小死区时间(最快速度)
if(x->delay_ms > 0)delay_ms(x->delay_ms);
}
|
|