#1楼主:来帮忙啊!51单片机控制步进电机L297 L298
文章发表于:2007-11-19 01:37
我只学过一点51 的汇编,现在比较着急搞这个,希望你们能给予我帮助。相近的程序,或比较详细思路。谢谢!
结构:5 个按钮和1个开关输入给单片机,输出5个指示灯,控制L297和L298来驱动步进电机
5个按钮1个开关 右行,左行,停止,试用,复位,右行到位。
指示灯是指示各个按钮的状态,即右行过程就是右行灯亮。
开始在左边,按下 试用 步进电机以低速右行,到位压下右行到位开关停止,此期间用意是测量行程,以后要按照新的速度走(50s走完全程),按下 左行 后就要以这样的速度左行到头,以后的都是做右行都是。停止就是无论什么状态都让步进电机停止!复位是给单片机复位。
#3
文章发表于:2007-11-20 09:43
L297和L298来驱动步进电机
我曾经写过,好像是四步八拍什么的,其实很简单,无非“定时读表”——使用定时器,读ABCD三像的表比如四相八拍的,可以列写一个表如step_z[8]={0x01,0x03,0x02,0x06,0x04,0x0c,0x08,0x09};
反转时倒着读表。慢转时将定时器时间加长,慢转将定时器时间放慢,很简单。
#4
文章发表于:2007-12-11 20:28
参考程序框架:
引脚定义:
#define 按钮1 Px_x ;
#define 按钮2 Px_x ;
.......
变量定义:
......
设置定时器工作方式;
开定时器中断;
开定时器;
//定时器中断处理程序
{
停定时器;
步进脚电平翻转;
清空标志位;
重新装入定时值;//与速度有关;
if(停止开关未闭合)
{启动定时器;}
}
//主程序:
『
while(1)
{
while(试用开关未闭合); //等待
//试用程序:
『
步数清零;
//向右走:
设为慢速度(设置定时器);
方向=右;
while(到位开关未闭合)
『
方向=右;
』
//如果到达;
停定时器;
总步数=当前步数;
速度=50秒/总步数;
以速度值设置定时器;
』
试用开关=闭合;
//至此完成试用;
// 查询左行或右行
if(左行开关闭合){
while(当前步数不为0) //未走到最左;
{
方向=左;
if(右行开关闭合){break;}
}
}
if(右行开关闭合){
while(当前步数不为总步数) //未走到最左;
{
方向=左;
if(左行开关闭合){break;}
}
}
}
』
主程序至此over。
#6
文章发表于:2007-12-11 20:49
偶忘吃饭了,频频出错 汗!
if(右行开关闭合){
while(当前步数不为总步数) //未走到最右;
{
方向=右;
if(左行开关闭合){break;}
}
}
#8
文章发表于:2007-11-20 09:50
左行右行什么的那要看你硬件了,反正无非正反快慢…
这是我写的用MSP430的步进电机驱动希望对你有所帮助
#include<msp430x14x.h>
#define uchar unsigned char
uchar step[8];
//uchar step_z[8]={0x01,0x03,0x02,0x06,0x04,0x0c,0x08,0x09};
uchar step_z2[8]={0x0e,0x0c,0x0d,0x09,0x0b,0x03,0x07,0x06};
uchar kk;
int step1;
uchar ttt;
unsigned int count;
unsigned int test;
unsigned int speed[10];
void init_TA(void){
TACTL="TASSEL"_1+MC_0+TACLR;
CCTL0|=CCIE;
CCR1=32768;
CCTL1|=CCIE;
CCR0=69;
TACTL|=MC_2;
}
void init_IO(void){
P4DIR=0X0F;
P4SEL=0;
P2SEL=0;
P2DIR=0;
P2IES|=BIT0;
P2IE|=BIT0;
P1SEL=0;
P1DIR=0;
P1IES=BIT0+BIT1+BIT2+BIT3;
P1IE=BIT0+BIT1+BIT2+BIT3;
}
void init_step(void){
uchar i;
kk="0";
step1=69;
test="0";
ttt="0";
init_IO();
init_TA();
for(i=0;i<8;i++)
{
step[i]=step_z2[i];
}
}
void main(void)
{
WDTCTL="WDTHOLD"+WDTPW;
init_step();
_EINT();
while(1){
LPM0;
}
}
#pragma vector="PORT2"_VECTOR
__interrupt void countup(void)
{
switch(P2IFG&BIT0)
{
case BIT0:
{
count++;
P2IFG=0;
}
default:P2IFG=0; break;
}
}
#pragma vector="TIMERA1"_VECTOR
__interrupt void one_s(void)
{
switch(TAIV){
case 2:
{
CCR1=CCR1+32767;
speed[ttt]=count;
count="0";
ttt++;
if(ttt==10)ttt=0;
break;
}
case 4:break;
case 10:break;
default :break;
}
}
#pragma vector="TIMERA0"_VECTOR
__interrupt void one_step(void)
{
P4OUT=step[kk];
CCR0+=step1;
kk++;
//test++;
// if(test==4000){
// uchar i;
// for(i=0;i<8;i++)
// {
// step[i]=0x0f;
// }
// }
if(kk==8)kk=0;
}
#pragma vector =PORT1_VECTOR
__interrupt void change(void)
{
switch(P1IFG&0x0f)
{
case BIT0:
{
uchar i;
for(i=0;i<8;i++)
{
step[i]=step_z2[7-i];
}
P1IFG=0;
break;
}
case BIT1:
{
uchar i;
for(i=0;i<8;i++)
{
step[i]=0x0f;
}
P1IFG=0;
break;
}
case BIT2:
{
step1=step1+1;
// TBCCR0+=2;
P1IFG=0;
break;
}
case BIT3:
{
step1=step1-1;
P1IFG=0;
break;
}
default:P1IFG=0;break;
}
}
#9
文章发表于:2007-12-11 19:19
L297+L298芯片的控制比较简单,一般用步进和方向两个引脚就行了。相序由L297处理,写程序时不用考虑。步进(Step)引脚加的是脉冲信号,若L297设置为整步工作的,则一个脉冲走一步,若设置2细分的,则一个脉冲走半步。方向脚(dir)用高低电平表示两个不同的方向。写程序时只须考虑“在哪个方向走多少步”就OK了。