找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2532|回复: 0
收起左侧

STM32步进电机驱动算法(转帖)

[复制链接]
ID:657909 发表于 2019-12-6 23:48 | 显示全部楼层 |阅读模式
部分核心代码

  1. #define ACCELERATED_SPEED_LENGTH  3000    //定义加速度的点数(其实也是3000个细分步的意思),调这个参数改变加速点
  2. #define FRE_MIN 3000     //最低的运行频率,调这个参数调节最低运行速度
  3. #define FRE_MAX 24000  //最高的运行频率,调这个参数调节匀速时的最高速度

  4. int step_to_run;  //要运行的步数
  5. float fre[ACCELERATED_SPEED_LENGTH];  //数组存储加速过程中每一步的频率
  6. unsigned short period[ACCELERATED_SPEED_LENGTH]; //数组储存加速过程中每一步定时器的自动装载值

  7. void CalculateSModelLine(float fre[],  unsigned short period[],   float  len,  float fre_max,  float fre_min, float flexible)
  8. {
  9.     int i=0;
  10.     float deno ;
  11.     float melo ;
  12.     float delt = fre_max-fre_min;
  13.     for(; i<len; i++)
  14.     {
  15.         melo = flexible * (i-len/2) / (len/2);
  16.         deno = 1.0 / (1 + expf(-melo));   //expf is a library function of exponential(e)
  17.         fre[i] = delt * deno + fre_min;
  18.         period[i] = (unsigned short)(1000000.0 / fre[i]);    // 10000000 is the timer driver frequency
  19.     }
  20.    return ;
  21. }

  22. //主函数

  23. int main(void)
  24. {

  25.     u8 t;

  26.     delay_init();
  27.     NVIC_Config();
  28.     LED_Init();    //初始化IO口
  29.       TIM1_Int_Init(10,72); //设置定时器的频率等
  30.     //PB8 9 12 13
  31.     //KEY_Init();
  32.     //SMG_io_init();
  33.     CalculateSModelLine(fre,period,ACCELERATED_SPEED_LENGTH,FRE_MAX,FRE_MIN,4);
  34.     TIM_Cmd(TIM1, ENABLE);

  35.     while(1)
  36.     {

  37.         }
  38. }

  39. 定时器初始化

  40. void TIM1_Int_Init(u16 arr,u16 psc)  
  41. {  
  42.     NVIC_InitTypeDef NVIC_InitStructure;  
  43.     TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;  
  44.     TIM_OCInitTypeDef  TIM_OCInitStructure;

  45.     TIM_DeInit(TIM1);                                           /*¸′λTIM1¶¨ê±Æ÷*/  
  46.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);        /*¿aê±Öó*/  
  47.     TIM_TimeBaseStructure.TIM_Period = arr;                     /*ê±ÖóμÎ′eμÄ′Îêy£¬1»êyÖD¶ÏÕaàïêÇ1msÖD¶Ïò»′Î*/      
  48.     TIM_TimeBaseStructure.TIM_Prescaler = psc;                /* ·ÖÆμ720*/         
  49.     TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;            
  50.     TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; /*¼Æêy·½ÏòÏòéϼÆêy*/  
  51.     TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;

  52.     TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);  

  53.        /* Channel 1, 2,3 and 4 Configuration in PWM mode */
  54.     TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
  55.     TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  56.     TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable; //2»ê1óÃNμÄêä3ö£¬ËùòÔòa1Øμô
  57.     TIM_OCInitStructure.TIM_Pulse = 0;   //μúò»′ÎûóDêä3öÂö3å
  58.     TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
  59.     TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
  60.     TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
  61.     TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;

  62.     TIM_OC4Init(TIM1, &TIM_OCInitStructure);
  63.     TIM_OC4PreloadConfig(TIM1, TIM_OCPreload_Enable);        
  64.     /* Clear TIM1 update pending flag  Çå3yTIM1òç3öÖD¶Ï±êÖ¾]  */  
  65.     TIM_ClearFlag(TIM1, TIM_FLAG_Update);                 
  66.     NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_IRQn;          /*òç3öÖD¶Ï*/  
  67.     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  
  68.     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;   
  69.     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;  
  70.     NVIC_Init(&NVIC_InitStructure);  

  71.         /* TIM1 counter enable */
  72.         TIM_Cmd(TIM1, DISABLE);
  73.         /* TIM1 Main Output Enable */
  74.         TIM_CtrlPWMOutputs(TIM1, ENABLE);

  75.         TIM_ClearFlag(TIM1, TIM_FLAG_Update);
  76.         TIM_ITConfig(TIM1,TIM_IT_Update,ENABLE);
  77. }

  78. //初始化定时器IO

  79. void LED_Init(void)
  80. {
  81.     GPIO_InitTypeDef  GPIO_InitStructure;

  82.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE);

  83.     //设置PA11为复用推挽输出
  84.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  85.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  86.     GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_6 | GPIO_Pin_8 | GPIO_Pin_11 | GPIO_Pin_12;
  87.     GPIO_Init(GPIOA, &GPIO_InitStructure);   

  88.     //Âö3å¿ú+·½Ïò
  89.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  90.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  91.     GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_5;
  92.     GPIO_Init(GPIOB, &GPIO_InitStructure);   

  93.       /* TIM1 Full remapping pins */
  94.     GPIO_PinRemapConfig(GPIO_FullRemap_TIM1, ENABLE);   //打开重映射
  95. }



  96. 定时器更新中断

  97. int i = 0;
  98. void TIM1_UP_IRQHandler(void)  
  99. {  
  100.   TIM_ClearFlag(TIM1, TIM_FLAG_Update);
  101.     if(i < ACCELERATED_SPEED_LENGTH && g_motor_dir_s == 0) //加速,直到步数达到 ACCELERATED_SPEED_LENGTH
  102.     {
  103.         TIM1->ARR= period[i];
  104.         TIM1->CCR4= period[i]/2;
  105.         i++;
  106.     step_to_run = 20000;   //这里设置要跑的步数,当然可以写在main函数中,这里没有把加减速的步数算上
  107.     }
  108.     else if(step_to_run > 0) //匀速
  109.     {
  110.         step_to_run--;
  111.      }
  112.   else if(i > 0 && g_motor_dir_s == 1)  //电机减速
  113.   {
  114.         i--;
  115.         TIM1->ARR= period[i];
  116.         TIM1->CCR4= period[i]/2;
  117.     }        

  118.     if(i == ACCELERATED_SPEED_LENGTH || i == 0)
  119.         {
  120.             g_motor_dir_s = (~g_motor_dir_s)&0x01;
  121.             }   
  122. }
复制代码

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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