eydj2008 发表于 2009-5-24 11:43:44

原创==>C-FREE 3.5 步进电机细分正弦值计算程序

/*************************************************************************
   适用于:步进电机细分驱动SIN值计算 MOTOR_SIN   7226+621939610+3771 等
   设计制作:DJ.y
   编译环境:C-FREE 3.5
*************************************************************************/

#include <stdio.h>


int count_n=0,count_ph=0;
//**************R的N次方***************************************************************
float RN(float r,long n)   //去掉R的0和1次方 需要见另一个完整功能函数
{ long i;
   float j=r;
for(i=1;i<n;i++)       j=j*r;
returnj;
}
//***********N的阶乘******************************************************************
long fact(long n)            //浮点运算见另外一个函数
{ long i,j=1;
for(i=1;i<=n;i++)
      {
         j=j*i;
      }
returnj;
}
/***********************SIN()*******************************************************/
float sin(float x)   //设x== 0-180
{float y;    //y为弧度增大为10000倍double y ;//双精度64位 单精度float 32位
float goal,PI=3.1415926;
y    = x*PI/180;
//printf("%f",y);    printf("\n");      ?test OK
//6=3的阶乘   120=5的阶乘   750=7的阶乘 ---根据SINX 幂级数公式得 取前3级
//goal =(y-y*y*y/6+y*y*y*y*y/120);//-y*y*y*y*y*y*y/720+y*y*y*y*y*y*y*y*y/5040
goal =y-RN(y,3)/fact(3)+RN(y,5)/fact(5)-RN(y,7)/fact(7)+RN(y,9)/fact(9)-RN(y,11)/fact(11);
return goal;
}
//**************步进电机A相电流取样值******************************
int data_vref1(int step,int max_value_current)
{
//char step=8;//默认为8个细分每步
int value_current;
float angle;   //每个细分步的角度
int DATA_PH1,DATA_PH2;
int DATA_VREF1,DATA_VREF2;   //最大128细分*4拍==512
int i_bat_1,i_bat_2,i_bat_3,i_bat_4,j=0;
FILE *fp;
int*ptr1,*ptr2,*ptr3,*ptr4;


ptr1 =& DATA_VREF1;         //指针地址
ptr2 =& DATA_VREF1;         //指针地址
ptr3 =& DATA_VREF1;         //指针地址
ptr4 =& DATA_VREF1;         //指针地址

angle=90.000000/step;         //每步角度计算
for (i_bat_1=0;i_bat_1<step;i_bat_1++)
   {
   //value_current=max_value_current*sin(angle*i_bat_1)+128;//适用于NJU39610max_value_current=120
   value_current=max_value_current*sin(angle*i_bat_1);          //适用于TCL7226 max_value_current=256

      DATA_PH1=1; DATA_PH1=1; DATA_PH1=0;DATA_PH1=0;
      DATA_PH2=0; DATA_PH2=1; DATA_PH2=1;DATA_PH2=0;
   
   DATA_VREF1         =value_current;
   DATA_VREF1=value_current;
   DATA_VREF1=value_current;
   DATA_VREF1=value_current;
   
   DATA_VREF2=value_current;
   DATA_VREF2    =value_current;
   DATA_VREF2=value_current;
   DATA_VREF2=value_current;
   
   *ptr1   =   value_current;
//-----------------------------------------------------
       ptr1++;
   }
//*******************TO TXT**********************************************
for (i_bat_2=0;i_bat_2<step*4;i_bat_2++)
   {
            //------------to txt------------------------------------
       // fp=fopen("C:\\data.txt","a");    //程序指针指向文件地址w表示清0或新建
      fprintf(fp,"%d,",DATA_VREF1);
      if(count_n>=20-1){ count_n=0;    fprintf(fp,"\n");} else count_n++;   //回车换行

   }
    fprintf(fp,"\n");
for (i_bat_2=0;i_bat_2<step*4;i_bat_2++)
   {
            //------------to txt------------------------------------
       // fp=fopen("C:\\data.txt","a");    //程序指针指向文件地址w表示清0或新建
      fprintf(fp,"%d,",DATA_VREF2);
      if(count_n>=20-1){ count_n=0;    fprintf(fp,"\n");} else count_n++;   //回车换行

   }
   fprintf(fp,"\n");

   
   
}

//******************************************************************************
int main()
{FILE *fp;
    //n! N的阶乘
int i,j=1;

int step,max_value_current;
//int data ;
   //ptr=&data;
    //-------------输入细分步数----------------------------------------------
   printf("INT STEP为整型数据0-65536,细分电流最大值为M,步进电机细分微步数N.");    printf("\n");
   printf("生成文件目录==>C:\\data.txt (0<M<255)(0<N<255)请输入M的值和N的值:(M,N)");   printf("\n");
   printf("注意:先输入M的值,再回车后输入N的值,不能输入带小数的值");   printf("\n");
   printf("M:N:");
   scanf("%d",&max_value_current);      //输入函数
   scanf("%d",&step);

       fp=fopen("C:\\data.txt","a");    //程序指针指向文件地址w表示清0或新建
       fprintf(fp,"步进电机微步细分最大电流值为:%d。   ",max_value_current);
       fprintf(fp,"步进电机%d微步细分电流值为:",step);
       fprintf(fp,"\n");
       data_vref1(step,max_value_current);
       fclose(fp);
   /*
    for(i=1;i<n;i++)
   {
         j=j*i;
      data=j;       //将值存入数据表中

    printf("%d",j);
    printf("\n");
      }*/
}

/*********************TEST*************************************
float x=9,y,goal;
y    = x*3.1416/180;
goal =(y-y*y*y/6+y*y*y*y*y/120);
printf("\n");
printf("%f",goal);   //ok
//**************************************************************/
/*************************************************************************
支持开源活动(有专利和商业性目的除外)
百度HI群号:1165496单片机编程技术交流
腾讯QQ群号:60893314 单片机编程技术交流
我们的口号是:三人行,必有我师。希望大家多交流,不保留。
同一个世界,同一个梦,为富民中国。
**************************************************************************/

eydj2008 发表于 2009-5-24 11:50:27

这是我连续工作 二个周末研究出来的呀! 哎 当时做的时候还真辛苦还不知道这个正弦怎么计算,而且网上也找了 也没找到,
开始我还只用EXCEL SIN()实现的步进电机正弦计算 附上 原文件
步进电机细分计算程序和EXCEL_SIN表ourdev_447460.rar(文件大小:21K) (原文件名:motor_sin.rar)

aozima 发表于 2009-5-24 11:50:35

BS C-FREE
并不FREE
而且编译器用的MINGW 曾被他骗了..
典型的:开别人的源 赚自己的钱
建议楼主用C::B去吧...

http://cache.amobbs.com/bbs_upload782111/files_15/ourdev_447461.jpg
(原文件名:a.jpg)

对楼主的程序提个建议:
1.不要使用绝对路径生成的文件应该在当前目录下的好..*UNIX下没有C:// 最好可以参数指定生成的文件名 方便调用(没有输入时生成默认的文件名)
2.输入的地方有点考人的IQ 建议搞得更简单些 两个不要一起输入 应该输入一个再提示输入下一个 而且提示不要是M N
请输入细分电流最大值:
请输入步进电机细分微步数:
数据data.txt已生成!

呵呵我不懂步进只是就楼主使用开源软件发表下自己的意见
支持楼主的两个星期...

eydj2008 发表于 2009-5-24 11:52:56

管他呢 能用的就是好东西 不能用的就扔掉

new007 发表于 2009-5-24 11:59:42

为何不用查表方式?

eydj2008 发表于 2009-5-24 12:18:30

不好意思啊!查表!我这个程序就是生成 正弦值表呀!
你看看程序可能是我说明得不够
因为我也是做单片机的 这个程序能用,对我来说就已经不错了,谁是计算机高手 帮我改一下呀吧再传上来
我还不知道 二个以上的值 分开输入 怎么编的

sunsky 发表于 2009-5-24 17:44:59

/*************************************************************************
   适用于:步进电机细分驱动SIN值计算 MOTOR_SIN   7226+621939610+3771 等
   设计制作:DJ.y
   编译环境:C-FREE 3.5
*************************************************************************/

#include <stdio.h>


int count_n=0,count_ph=0;
//**************R的N次方***************************************************************
float RN(float r,long n)   //去掉R的0和1次方 需要见另一个完整功能函数
{
    long i;
    float j=r;
    for (i=1;i<n;i++)       j=j*r;
    returnj;
}
//***********N的阶乘******************************************************************
long fact(long n)            //浮点运算见另外一个函数
{
    long i,j=1;
    for (i=1;i<=n;i++)
    {
      j=j*i;
    }
    returnj;
}
/***********************SIN()*******************************************************/
float sin(float x)   //设x== 0-180
{
    float y;    //y为弧度增大为10000倍double y ;//双精度64位 单精度float 32位
    float goal,PI=3.1415926;
    y    = x*PI/180;
//printf("%f",y);    printf("\n");      ?test OK
//6=3的阶乘   120=5的阶乘   750=7的阶乘 ---根据SINX 幂级数公式得 取前3级
//goal =(y-y*y*y/6+y*y*y*y*y/120);//-y*y*y*y*y*y*y/720+y*y*y*y*y*y*y*y*y/5040
    goal =y-RN(y,3)/fact(3)+RN(y,5)/fact(5)-RN(y,7)/fact(7)+RN(y,9)/fact(9)-RN(y,11)/fact(11);
    return goal;
}
//**************步进电机A相电流取样值******************************
int data_vref1(int step,int max_value_current)
{
//char step=8;//默认为8个细分每步
    int value_current;
    float angle;   //每个细分步的角度
    int DATA_PH1,DATA_PH2;
    int DATA_VREF1,DATA_VREF2;   //最大128细分*4拍==512
    int i_bat_1,i_bat_2,i_bat_3,i_bat_4,j=0;
    FILE *fp;
    int*ptr1,*ptr2,*ptr3,*ptr4;


    ptr1 =& DATA_VREF1;         //指针地址
    ptr2 =& DATA_VREF1;         //指针地址
    ptr3 =& DATA_VREF1;         //指针地址
    ptr4 =& DATA_VREF1;         //指针地址

    angle=90.000000/step;         //每步角度计算
    for (i_bat_1=0;i_bat_1<step;i_bat_1++)
    {
      //value_current=max_value_current*sin(angle*i_bat_1)+128;//适用于NJU39610max_value_current=120
      value_current=max_value_current*sin(angle*i_bat_1);          //适用于TCL7226 max_value_current=256

      DATA_PH1=1;
      DATA_PH1=1;
      DATA_PH1=0;
      DATA_PH1=0;
      DATA_PH2=0;
      DATA_PH2=1;
      DATA_PH2=1;
      DATA_PH2=0;

      DATA_VREF1         =value_current;
      DATA_VREF1=value_current;
      DATA_VREF1=value_current;
      DATA_VREF1=value_current;

      DATA_VREF2=value_current;
      DATA_VREF2    =value_current;
      DATA_VREF2=value_current;
      DATA_VREF2=value_current;

      *ptr1   =   value_current;
//-----------------------------------------------------
      ptr1++;
    }
//*******************TO TXT**********************************************
    for (i_bat_2=0;i_bat_2<step*4;i_bat_2++)
    {
      //------------to txt------------------------------------
      // fp=fopen("C:\\data.txt","a");    //程序指针指向文件地址w表示清0或新建
      fprintf(fp,"%d,",DATA_VREF1);
      if (count_n>=20-1)
      {
            count_n=0;
            fprintf(fp,"\n");
      }
      else count_n++;   //回车换行

    }
    fprintf(fp,"\n");
    for (i_bat_2=0;i_bat_2<step*4;i_bat_2++)
    {
      //------------to txt------------------------------------
      // fp=fopen("C:\\data.txt","a");    //程序指针指向文件地址w表示清0或新建
      fprintf(fp,"%d,",DATA_VREF2);
      if (count_n>=20-1)
      {
            count_n=0;
            fprintf(fp,"\n");
      }
      else count_n++;   //回车换行

    }
    fprintf(fp,"\n");



}

//******************************************************************************
int main()
{
    FILE *fp;
    //n! N的阶乘
    int i,j=1;

    int step,max_value_current;
    //int data ;
    //ptr=&data;
    //-------------输入细分步数----------------------------------------------
    printf("INT STEP为整型数据0-65536,细分电流最大值为M,步进电机细分微步数N.");
    printf("\n");
    printf("生成文件目录==>C:\\data.txt (0<M<255)(0<N<255)请输入M的值和N的值:(M,N)");
    printf("\n");
    printf("注意:先输入M的值,再回车后输入N的值,不能输入带小数的值");
    printf("\n");
    printf("M:N:");
    scanf("%d",&max_value_current);      //输入函数
    scanf("%d",&step);

    fp=fopen("C:\\data.txt","a");    //程序指针指向文件地址w表示清0或新建
    fprintf(fp,"步进电机微步细分最大电流值为:%d。   ",max_value_current);
    fprintf(fp,"步进电机%d微步细分电流值为:",step);
    fprintf(fp,"\n");
    data_vref1(step,max_value_current);
    fclose(fp);
    /*
   for(i=1;i<n;i++)
      {
          j=j*i;
       data=j;       //将值存入数据表中

   printf("%d",j);
   printf("\n");
       }*/
}

/*********************TEST*************************************
float x=9,y,goal;
y    = x*3.1416/180;
goal =(y-y*y*y/6+y*y*y*y*y/120);
printf("\n");
printf("%f",goal);   //ok
//**************************************************************/
/*************************************************************
支持开源活动(有专利和商业性目的除外)
百度HI群号:1165496单片机编程技术交流
腾讯QQ群号:60893314 单片机编程技术交流
我们的口号是:三人行,必有我师。希望大家多交流,不保留。
同一个世界,同一个梦,为富民中国。
**************************************************************/

sunsky 发表于 2009-5-24 17:48:00

整理一下。

taoyuanwangwei 发表于 2009-9-3 19:32:00

步进电机正转很平滑,但反转效果较差,有种卡卡的感觉?
细分表的问题?

eydj2008 发表于 2009-9-4 22:03:20

你用的我的细分表吗? 我的没问题呀我的程序 正转反转一个程序如果正转OK 反转肯定OK

ggyyll8683 发表于 2009-9-5 00:00:31

学习,准备搞搞步进电机

taoyuanwangwei 发表于 2009-9-8 21:48:39

是的,7226+6219的电路,最大细分数为128
定时器实现每一小步输出
我想可能细分表没问题,可能问题出现在加减速
正在研究中。。。。
加减速真的好难,现在想到最好的调速方法是改变细分数,但还是不理想
郁闷中。。。。。

mruio 发表于 2009-9-10 14:37:36

MARK

bingshuihuo888 发表于 2012-1-1 12:55:23

电路可以贡献一下吗?

our2008 发表于 2012-1-1 19:19:00

mark

hyc07209 发表于 2012-5-30 17:59:33

在Excel表里随便一个格里输入=SIN(Angle/180*3.14159),要到的正弦值就出来了。用得了这么麻烦吗

Asch 发表于 2012-8-11 13:10:50

顶顶,最近正在研究 PWM 控制 步进电机

yeksw206 发表于 2013-9-8 05:11:27

学习学习!

3.3v 发表于 2013-9-8 07:43:33

SIN计算快吗?

luckseason 发表于 2016-4-23 20:56:13

步进电机细分正弦值计算程序
页: [1]
查看完整版本: 原创==&gt;C-FREE 3.5 步进电机细分正弦值计算程序