机械社区

 找回密码
 注册会员

QQ登录

只需一步,快速开始

搜索
查看: 2808|回复: 4

步进电机这个c程序怎么改电机频率阿?是改哪个参数频率能降低

[复制链接]
发表于 2014-7-19 17:42:26 | 显示全部楼层 |阅读模式
#include<reg51.H>
#include <intrins.h>         //内部包含延时函数 _nop_();
typedef  unsigned char   u8;
typedef  unsigned int    u16;
sbit key =P1^0;   //正反转
sbit key1=P1^1;          //启动停止
sbit key2=P1^2;   //加速
sbit key3=P1^3;   //减速
sbit LCD_RS=P2^4;
sbit LCD_WR=P2^3;
sbit LCD_EN=P2^2;
sbit BEEP=P3^5;
sbit Ir_Pin = P3^2;
u8 Ir_Buf[4]; //用于保存解码结果
u8 code table[]="Zhang and wh 0011 ";
u8 code table0[]="---- STOP 00R/M";   //初始 停止
u8 code table3[]="FOR SPEED 12R/M";   //启动 3档正转
u8 code table2[]="FOR SPEED 05R/M";   //2档正转
u8 code table1[]="FOR SPEED 03R/M";   //1档正转
u8 code table4[]="FOR SPEED 20R/M";   //4档正转
u8 code table5[]="FOR SPEED 30R/M";   //5档正转
u8 code table10[]="---- STOP 00R/M";   // 停止
u8 code table13[]="BACK SPEED 12R/M";   //3档反转
u8 code table12[]="BACK SPEED 05R/M";   //2档反转
u8 code table11[]="BACK SPEED 03R/M";   //1档反转
u8 code table14[]="BACK SPEED 20R/M";   //4档反转
u8 code table15[]="BACK SPEED 30R/M";   //5档反转
u8 code FFW[8]={0x7F,0x3F,0xBF,0x9F,0xDF,0xCF,0xEF,0x6F};
u8 code REV[8]={0x6F,0xEF,0xCF,0xDF,0x9F,0xBF,0x3F,0x7F};
u8 code SPD[6]={0x18,0x16,0x12,0x08,0x06,0x04};                //五个档
bit flag=1;
bit flag1=0;
u8 j=0x01;                         
u8 s=0x00;
u8 d=0x00;
void int1_init(void)
{
        IT0 = 1; //下降沿有效
        EX0 = 1;
        EA = 1;
}

/*********************************************
* UART初始化
* 波特率:9600
*********************************************/
void uart_init(void)
{
    TMOD = 0x21;
    SCON = 0x50;
    TH1 = 0xFD;
    TL1 = 0xFD;
    TR1 = 1;
}
/*********************************************
* UART发送一字节
*********************************************/
void UART_Send_Byte(u8 dat)
{
        SBUF = dat;
        while (TI == 0);
        TI = 0;
}
/*********************************************
* 获取低电平时间
*********************************************/
u16 Ir_Get_Low()
{
        TL0 = 0;
        TH0 = 0;
        TR0 = 1;
        while (!Ir_Pin && (TH0&0x80)==0);  
        TR0 = 0;           
        return (TH0 * 256 + TL0);
}
/*********************************************
* 获取高电平时间
*********************************************/
u16 Ir_Get_High()
{
        TL0 = 0;
        TH0 = 0;
        TR0 = 1;
        while (Ir_Pin && (TH0&0x80)==0);

        TR0 = 0;
        return (TH0 * 256 + TL0);
}


void delay(u16 x)
{
        u16 a,b;
        for(a=x;a>0;a--)
                for(b=10;b>0;b--);
}
  void beep(void)
{
  u8 i;
  for (i=0;i<180;i++)
   {
     delay(6);
     BEEP=!BEEP;                 //BEEP取反
   }
  BEEP=1;                      //关闭蜂鸣器
}
void sdelay(u8 n)                //延时程序
{
        u8 i,k;
        for(i=2*n;i>0;i--)
for(k=125;k>0;k--);
}
u8 READ_COM(void)                        //读状态(命令)函数
{
        u8 a;
        LCD_RS=0;                        //命令(状态)字操作
        LCD_WR=1;                        //读操作
        LCD_EN=1;                        //操作允许
        delay(1);                        //延时
        a=P0;                                //读取状态赋值到a
        LCD_EN=0;                        //操作禁止
        return a;                         //将读取的命令(状态)字返回
}
void WRITE_COM(u8 com)                        //写状态(命令)函数,入口参数为命令(状态)字
{
        LCD_RS=0;                        //命令(状态)字操作
        LCD_WR=0;                        //写操作       
        P0=com;                                // 命令(状态)字准备好
        LCD_EN=0;                        //操作使能位高脉冲
        delay(10);
        LCD_EN=1;
        delay(10);
        LCD_EN=0;
        LCD_WR=1;                        //写禁止
}
u8 READ_DAT()                        //读数据函数
{
        u8 a;
        P0=0xFF;
        LCD_RS=1;                        //数据操作
        LCD_WR=1;                        //读操作
        LCD_EN=1;                        //操作允许
        delay(1);                        //延时
        a=P0;                                //数据读取到a
        LCD_EN=0;                        //操作禁止
        return a;                         //将读取数据返回
}
void WRITE_DAT(u8 date)                //写数据函数 ,入口参数为写入数据
{
        LCD_RS=1;
        LCD_WR=0;        
        P0=date;
        LCD_EN=0;
        delay(10);
        LCD_EN=1;
        delay(10);
        LCD_EN=0;
        LCD_WR=1;
}
bit LCD_BUSY()                        //1602液晶读忙操作,忙则返回1,空闲则返回0
{
    return (bit)(READ_COM()&0x80);
}
void init()                                        //1602液晶初始化函数
{
        delay(15);
        WRITE_COM(0x38);
        delay(5);
        WRITE_COM(0x38);
        delay(5);
        WRITE_COM(0x38);                 //设置显示模式
        while(LCD_BUSY());                 //读忙
        WRITE_COM(0x08);                //关闭显示        
        while(LCD_BUSY());                //读忙
        WRITE_COM(0x06);                //指针加1模式
        while(LCD_BUSY());                //读忙
        WRITE_COM(0x01);                //显示清屏
        while(LCD_BUSY());                 //读忙
        WRITE_COM(0x0f);                //开显示,显示光标,光标闪烁
}
void DISPLAY(u8 m)                            //显示主程序
{
        u8 a;
    init();
        while(LCD_BUSY());                //读忙
        WRITE_COM(0x80);                //设置初始操作地址
        for(a=0;a<16;a++)                //写入table1内容
        {
                while(LCD_BUSY());
                WRITE_DAT(table[a]);
        }

        while(LCD_BUSY());                //读忙
        WRITE_COM(0xc0);                 //设置初始操作地址
        for(a=0;a<16;a++)                //写入table2内容
        {
                while(LCD_BUSY());
                switch(m)
                 {
                   case 0: WRITE_DAT(table0[a]);break;
                   case 1: WRITE_DAT(table1[a]);break;
                   case 2: WRITE_DAT(table2[a]);break;
                   case 3: WRITE_DAT(table3[a]);break;
                   case 4: WRITE_DAT(table4[a]);break;
                   case 5: WRITE_DAT(table5[a]);break;
                   case 10: WRITE_DAT(table10[a]);break;
                   case 11: WRITE_DAT(table11[a]);break;
                   case 12: WRITE_DAT(table12[a]);break;
                   case 13: WRITE_DAT(table13[a]);break;
                   case 14: WRITE_DAT(table14[a]);break;
                   case 15: WRITE_DAT(table15[a]);break;
             }                          
        }
}   

int zfan(s,j,d)
{
                  flag=~flag;        //按键后标志取反
              if(flag) d=0;
              else     d=10;
              s=j+d;
              DISPLAY(s);
                  return(j);
}
int qting(s,j,d)
{         
            flag1=~flag1;        //按键后标志取反
                if(flag1)   s=j;
                else        s=0;
                s=s+d;
                DISPLAY(s);
                        return j;
}
int jia(s,j,d)                                     //通用加速主程序
{
        if(j<5)  j++;
        else  j=5;
        s=j+d;       
        DISPLAY(s);
        return j;
}
int jian(s,j,d)
{
        if(j>1) j--;
        else j=1;
        s=j+d;       
    DISPLAY(s);
        return j;
}
void int1_isr() interrupt 0          //中断处理程序
{
        u16 temp;
        u8 i,k;

        temp = Ir_Get_Low();
        if ((temp < 7833) || (temp > 8755))  //引导脉冲低电平8500~9500us
                return;
        temp = Ir_Get_High();
        if ((temp < 3686) || (temp > 4608))  //引导脉冲高电平4000~5000us
                return;

        for (i=0; i<4; i++) //4个字节
        {
                for (k=0; k<8; k++) //每个字节8位
                {
                        temp = Ir_Get_Low();
                        if ((temp < 184) || (temp > 737)) //200~800us
                                return;

                        temp = Ir_Get_High();
                        if ((temp < 184) || (temp > 1843)) //200~2000us
                                return;
                        Ir_Buf[i] >>= 1;
                        if (temp > 1032) //1120us
                                Ir_Buf[i] |= 0x80;
                }
        }
        beep();
        UART_Send_Byte(Ir_Buf[0]);
        UART_Send_Byte(Ir_Buf[1]);
        UART_Send_Byte(Ir_Buf[2]);
        UART_Send_Byte(Ir_Buf[3]);
              s=Ir_Buf[2]  ;
                        switch(s)
                 {
                   case 15: zfan(s,j,d);flag=~flag;j=zfan(s,j,d);break;
                   case 01: qting(s,j,d);flag1=~flag1;j=qting(s,j,d);break;
                   case 17: j=jia(s,j,d);break;
                   case 12: j=jian(s,j,d);break;
             }
}
void main(void)
{
        u8 i,k,s,d;
        s=0;
        d=0;
           DISPLAY(s);
        while(1)
  {   uart_init();          //波特率初始化
          int1_init();          //中断初始化        
         if( flag1 )   
          {        for (i=0; i<8; i++)       //一个周期--八拍
                {
                        if(flag)        P1 = FFW[i];          //取数据       
                        else                P1 = REV[i];
                        k=SPD[j];
                        sdelay(k);            //节拍延时,用于调节转速
                }
                if(!key)
                {                                                         //正反转 //正反显示控制
                        sdelay(10);
                    beep();
                        if(!key)   flag=~flag;        //按键后标志取反
                        if(flag) d=0;
                        else     d=10;
                        s=j+d;
                        DISPLAY(s);
                        while(!key)        ;           //按键灵敏
                }
           }
          else   P2=0x00;
      sdelay(10);       
          if(!key1)
                {                                                         //启停转
                        sdelay(10);
                                beep();
                        if(!key1)   flag1=~flag1;        //按键后标志取反
                        if(flag1)   s=j;
                        else        s=0;
                        s=s+d;
                        DISPLAY(s);
                        while(!key1)        ;           //按键灵敏
                }
                 if(!key2)                                         //加速按键
                {
                        sdelay(10);
                                  beep();
                        if(!key2)  
                         {
                            if(j<5)  j++;
                                else  j=5;
                         }
                         s=j+d;       
                         DISPLAY(s);
                        while(!key2)        ;          
                }
                if(!key3)                                 //减速按键         
                {
                        sdelay(10);
                                  beep();
                        if(!key3)
                         {
                            if(j>1) j--;
                                else j=1;
                         }
                         s=j+d;       
                         DISPLAY(s);
                        while(!key3)        ;           //按键灵敏
                }
        }
}


回复

使用道具 举报

发表于 2014-7-19 22:22:52 | 显示全部楼层
u8 code SPD[6]={0x18,0x16,0x12,0x08,0x06,0x04};                //五个档   
这里调速度的五个挡的时间数,也就是电机运行的八拍里的每一拍的间格时间,比如你可调快一倍SPD[6]={0x0c,0x0b,0x09,0x04,0x03,0x02};  注意太快容易丢步。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-7-21 09:51:12 | 显示全部楼层
Industrial 发表于 2014-7-19 22:22
u8 code SPD[6]={0x18,0x16,0x12,0x08,0x06,0x04};                //五个档   
这里调速度的五个挡的时间 ...

我是要调慢阿。。。
回复 支持 反对

使用道具 举报

发表于 2014-7-22 18:21:53 | 显示全部楼层
能不能变通下,调慢你就把时间都加大就是了。比如调慢一倍把所有参数乘以2,改为
u8 code SPD[6]={0x30,0x2c,0x24,0x10,0x0c,0x08};                   //五个档  
回复 支持 反对

使用道具 举报

发表于 2014-7-23 09:08:17 | 显示全部楼层
爱德利才知道要调步进电机的参数这么难啊!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

小黑屋|手机版|Archiver|机械社区 ( 京ICP备10217105号-1,京ICP证050210号,浙公网安备33038202004372号 )

GMT+8, 2024-12-19 17:41 , Processed in 0.056997 second(s), 22 queries , Gzip On.

Powered by Discuz! X3.4 Licensed

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表