|
57BYG251A的电机,3A,1.2mh,0.95欧。
细分电路采用:
MCU:STC54C12AD(频率22.13M,1T单片机;由单片机产生相序信号,并控制DA输出正弦VREF)
DAC:8BIT 双通道 DAC8229
电流控制:双L297(原设计用L6506,发现控制不了电流,因手头上L297比较多,所以临时用2块L297做成PWM限流电路)
桥电路:双L6203(快速衰减方式,L297的INH接在L6203的EN端上)
细分数:64
这个电路做了很多的测试,终于把相电流控制成正弦余弦波了,但是效果令人很不满意:在转速相同的情况下(2转/S),电机噪音的大小:64细分的效果与半步模式的驱动效果,几乎相同,只是振动和噪音稍微小了一些。实在是令人太费解了,难道细分的效果就是这样?
我把相电流的波形图截下来,大家帮我参考一下:
(12.8K的脉冲,转速1转/S。)
![](http://cache.amobbs.com/bbs_upload782111/files_9/ourdev_248223.jpg)
DAC的输出波形 (原文件名:DA输出.jpg)
![](http://cache.amobbs.com/bbs_upload782111/files_9/ourdev_248224.jpg)
L6203的采样电阻上的波形 (原文件名:采样电流.jpg)
![](http://cache.amobbs.com/bbs_upload782111/files_9/ourdev_248225.jpg)
串接在其中一相上的电阻上的波形 (原文件名:相电流.jpg)
因为最近在做试验,电路图都不是新的,没上传上来。
电机的相序采用半步驱动的相序。原来用整步时发现在换向的过程中,因为相电流不能为理想的0值,所以加入了一步,成了半步驱动的方式。所以实际走一步需要的脉冲数:64+1。
以下是源代码:
#include <absacc.h>
#include <stdio.h>
#include <intrins.h>
#include <math.h>
#include <string.h>
#include "STC12C5410AD.H"
//da端口定义
#define DA_PORT P1
#define DA_CS P3_5
#define DA_WR P3_4
#define DA_AB P3_7
//#define DA_EN P3_3
//L6506接口定义
#define PA1 P2_0
#define PA2 P2_1
#define PB1 P2_2
#define PB2 P2_3
#define PH_PORT P2
//对外接口引脚定义
#define ST_CLK P3_2
#define ST_STOP P3_3
#define ST_DIR P2_7
//逻辑定义
#define DF_XF 64 //细分数
//全局变量定义
unsigned char data mv_step; //工作时序
unsigned char data xf_step; //细分时序
unsigned char data mt_stop; //停止
unsigned char data mt_dir; //方向
unsigned char xdata arry_xf_sin[DF_XF];
unsigned char xdata arry_xf_cos[DF_XF];
unsigned char data arry_step[8];
bit sta;
bit wait;
//unsigned char data ph_sta;
unsigned char data ph_chopper;
unsigned char data reload_tl0;
unsigned char data reload_th0;
unsigned char data sys_sta;
#define SYS_STOP 0
#define SYS_WORKING 1
StopMt()
{
EX0=0;sta=0;sys_sta=SYS_STOP;wait=1;
PH_PORT=0xff;mt_stop=0;mv_step=0;xf_step=0;mt_dir=0;
DA_PORT=0;
DA_AB=0;DA_WR=0;_nop_();_nop_();
DA_WR=1;
DA_AB=1;DA_WR=0;_nop_();_nop_();
DA_WR=1;
}
void delays(unsigned char dl)
{
unsigned char i;
for(;dl>0;dl--)
{
for(i=0;i<35;i++);
}
}
//IO定义
void InitTimer()
{
// float data t;
unsigned int data maxc=0;
maxc=65485;//50 个脉冲周期
reload_tl0=(unsigned char)(maxc&0x00ff);
reload_th0=(unsigned char)((maxc&0xff00)>>8);
T1x12=1;//不进行12分频
TH1=reload_th0;
TL1=reload_tl0;
TMOD=TMOD|0x10;//T1方式1
ET1=1;//开T1中断
TR1=1;
EA=1;
}
void main(void)
{
unsigned char data i=0;
mv_step=0;xf_step=0;mt_dir=0;
WDT_CONTR=0X3D;//看门狗启动,2S超时
//初始化各个IO寄存器状态
DA_PORT=0;sta=0;
ph_chopper=0xff;//不截波
DA_CS=0;//开启DAC芯片
sys_sta=SYS_STOP;
StopMt();//停止步进电机
//整步细分+半步修正 方式
arry_step[0]=4;
arry_step[1]=5;
arry_step[2]=1;
arry_step[3]=9;
arry_step[4]=8;
arry_step[5]=10;
arry_step[6]=2;
arry_step[7]=6;
for(i=0;i<DF_XF-1;i++) //生成细分时序(sin90 内细分)
{
arry_xf_sin=(unsigned char)(255.0*sin((float)i*3.1415927/2.0/(DF_XF-1)));
arry_xf_cos=(unsigned char)(255.0*cos((float)i*3.1415927/2.0/(DF_XF-1)));
}
arry_xf_sin=0xff;
arry_xf_cos=0;
//初始化中断
EX0=1; //开INT0中断
PX0=1; //INT0高优先级
IT0=1; //边沿方式触发
EA=1; //开放系统中断
while(1)
{
WDT_CONTR=0X3D;//喂狗
ST_STOP=1;
switch(sys_sta)
{
case SYS_STOP:
if(ST_STOP==0)
{
StopMt();
sys_sta=SYS_WORKING;
PX0=1; //INT0高优先级
IT0=1; //边沿方式触发
EX0=1;EA=1;
}
break;
case SYS_WORKING:
if(ST_STOP==1)
{
EX0=0;EA=0;StopMt();
sys_sta=SYS_STOP;
}
break;
}
}
}//
void Int0Interupt(void) interrupt 0
{//CLK输入中断
DA_CS=0;
if(wait)
{//插入半步等待状态
DA_PORT=0xff;
DA_AB=0;DA_WR=0;_nop_();
DA_WR=1;//输出DA最大值
sta=~sta;
wait=0;//已完成换向修正
xf_step=DF_XF-1;//进入换向
PH_PORT=(arry_step[mv_step]|0xf0);
}
else
{//正常细分状态
if(sta)
{
DA_PORT=arry_xf_sin[xf_step];
DA_AB=0;DA_WR=0;_nop_();
DA_WR=1;
DA_PORT=arry_xf_cos[xf_step];
DA_AB=1;DA_WR=0;_nop_();
DA_WR=1;
}
else
{
DA_PORT=arry_xf_cos[xf_step];
DA_AB=0;DA_WR=0;_nop_();
DA_WR=1;
DA_PORT=arry_xf_sin[xf_step];
DA_AB=1;DA_WR=0;_nop_();
DA_WR=1;
}
xf_step++;
if(xf_step>=DF_XF)
{
xf_step=0;
mv_step++;
if(mv_step==8)
mv_step=0;
if(mv_step%2==0)
{
wait=1;//需要进行换向修正
}
sta=~sta;
PH_PORT=(arry_step[mv_step]|0xf0);
}
}
} |
阿莫论坛20周年了!感谢大家的支持与爱护!!
知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)
|