OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 2967|回复: 3

如何将两个步进电机驱动整合在一起,控制它们不冲突

[复制链接]

5

主题

18

帖子

0

精华

初级会员

Rank: 2

积分
129
金钱
129
注册时间
2019-12-30
在线时间
22 小时
发表于 2020-7-31 15:16:40 | 显示全部楼层 |阅读模式
1金钱
现在有两个电机驱动程序,一个驱动电机A旋转控制左右,一个驱动电机控制升降,是根据原子的例程改了一下,代码如下:

电机A:
  1. #include "driver.h"
  2. #include "delay.h"
  3. #include "usart.h"


  4. u8 rcr_remainder;   //重复计数余数部分
  5. u8 is_rcr_finish=1; //重复计数器是否设置完成
  6. long rcr_integer;        //重复计数整数部分
  7. long target_pos=0;  //有符号方向
  8. long current_pos=0; //有符号方向
  9. DIR_Type motor_dir=CW;//顺时针

  10. /************** 驱动器控制信号线初始化 ****************/
  11. void Driver_Init(void)
  12. {
  13.         GPIO_InitTypeDef  GPIO_InitStructure;

  14.         RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG, ENABLE);//使能GPIOG时钟

  15.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_2; //DRIVER_DIR DRIVER_OE对应引脚
  16.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
  17.         GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
  18.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100M
  19.         GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
  20.         GPIO_Init(GPIOG, &GPIO_InitStructure);//初始化GPIOG3,4
  21.        
  22.         GPIO_ResetBits(GPIOG,GPIO_Pin_0);//PG3输出低 使能输出  DRIVER_ENA
  23.         GPIO_SetBits(GPIOG,GPIO_Pin_2);//PG4输出高 顺时针方向  DRIVER_DIR
  24.        
  25. }


  26. /***********************************************
  27. //TIM8_CH2(PC7) 单脉冲输出+重复计数功能初始化
  28. //TIM8 时钟频率 84*2=168MHz
  29. //arr:自动重装值
  30. //psc:时钟预分频数
  31. ************************************************/
  32. void TIM8_OPM_RCR_Init(u16 arr,u16 psc)
  33. {                                                          
  34.         GPIO_InitTypeDef GPIO_InitStructure;
  35.         TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
  36.         TIM_OCInitTypeDef  TIM_OCInitStructure;
  37.         NVIC_InitTypeDef NVIC_InitStructure;

  38.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8,ENABLE);          //TIM8时钟使能   
  39.         RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);         //使能PORTC时钟                                                                                    

  40.         GPIO_PinAFConfig(GPIOC,GPIO_PinSource6,GPIO_AF_TIM8); //GPIOC7复用为定时器8
  41.        
  42.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;           //GPIOC7
  43.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;        //复用功能
  44.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;        //速度100MHz
  45.         GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;      //推挽复用输出
  46.         GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;      //下拉
  47.         GPIO_Init(GPIOC,&GPIO_InitStructure);               //初始化PC7
  48.        
  49.         TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
  50.        
  51.         TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值         
  52.         TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值   
  53.         TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
  54.         TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
  55.         TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
  56.         TIM_ClearITPendingBit(TIM8,TIM_IT_Update);

  57.         TIM_UpdateRequestConfig(TIM8,TIM_UpdateSource_Regular); /********* 设置只有计数溢出作为更新中断 ********/
  58.         TIM_SelectOnePulseMode(TIM8,TIM_OPMode_Single);/******* 单脉冲模式 **********/

  59.         TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式2
  60.         TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出2使能
  61.         TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable; /****** 比较输出2N失能 *******/
  62.         TIM_OCInitStructure.TIM_Pulse = arr>>1; //设置待装入捕获比较寄存器的脉冲值,右移一位
  63.         TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
  64.         TIM_OC1Init(TIM8, &TIM_OCInitStructure);  //根据TIM_OCInitStruct中指定的参数初始化外设TIMx

  65.         TIM_OC1PreloadConfig(TIM8, TIM_OCPreload_Enable);  //CH2预装载使能         
  66.         TIM_ARRPreloadConfig(TIM8, ENABLE); //使能TIMx在ARR上的预装载寄存器
  67.        
  68.         TIM_ITConfig(TIM8, TIM_IT_Update ,ENABLE);  //TIM8   使能或者失能指定的TIM中断

  69.         NVIC_InitStructure.NVIC_IRQChannel = TIM8_UP_TIM13_IRQn;  //TIM8中断
  70.         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;  //先占优先级1级
  71.         NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;  //从优先级1级
  72.         NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
  73.         NVIC_Init(&NVIC_InitStructure);  //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
  74.        
  75.         TIM_ClearITPendingBit(TIM8, TIM_IT_Update);  //清除TIMx的中断待处理位:TIM 中断源
  76.         TIM_Cmd(TIM8, ENABLE);  //使能TIM8                                                                                          
  77. }



  78. /******* TIM8更新中断服务程序 *********/
  79. void TIM8_UP_TIM13_IRQHandler(void)
  80. {
  81.         if(TIM_GetITStatus(TIM8,TIM_FLAG_Update)!=RESET)//获取当前定时器状态,判断是否完成更新,更新中断
  82.         {
  83.                 TIM_ClearITPendingBit(TIM8,TIM_FLAG_Update);//清除更新中断标志位               
  84.                 if(is_rcr_finish==0)//重复计数器未设置完成    重复计数器默认初始值为1,已完成状态
  85.                 {
  86.                         if(rcr_integer!=0) //整数部分脉冲还未发送完成
  87.                         {
  88.                                 TIM8->RCR=RCR_VAL;//设置重复计数值
  89.                                 rcr_integer--;//减少RCR_VAL+1个脉冲                               
  90.                         }else if(rcr_remainder!=0)//余数部分脉冲 不为0
  91.                         {
  92.                                 TIM8->RCR=rcr_remainder-1;//设置余数部分
  93.                                 rcr_remainder=0;//清零
  94.                                 is_rcr_finish=1;//重复计数器设置完成                               
  95.                         }else goto out;   //rcr_remainder=0,直接退出                         
  96.                         TIM_GenerateEvent(TIM8,TIM_EventSource_Update);//产生一个更新事件 重新初始化计数器
  97.                         TIM_CtrlPWMOutputs(TIM8,ENABLE);        //MOE 主输出使能       
  98.                         TIM_Cmd(TIM8, ENABLE);  //使能TIM8                       
  99.                         if(motor_dir==CW) //如果方向为顺时针   
  100.                                 current_pos+=(TIM8->RCR+1);//加上重复计数值
  101.                         else          //否则方向为逆时针
  102.                                 current_pos-=(TIM8->RCR+1);//减去重复计数值                       
  103.                 }else
  104.                 {
  105. out:                is_rcr_finish=1;//重复计数器设置完成
  106.                         TIM_CtrlPWMOutputs(TIM8,DISABLE);        //MOE 主输出关闭
  107.                         TIM_Cmd(TIM8, DISABLE);  //关闭TIM8                                V
  108.                         printf("当前位置=%ld\r\n",current_pos);//打印输出
  109.                 }       
  110.         }
  111. }
  112. /***************** 启动TIM8 *****************/
  113. void TIM8_Startup(u32 frequency)   //启动定时器8
  114. {
  115.         u16 temp_arr=1000000/frequency-1;
  116.         TIM_SetAutoreload(TIM8,temp_arr);//设定自动重装值       
  117.         TIM_SetCompare1(TIM8,temp_arr>>1); //匹配值2等于重装值一半,是以占空比为50%       
  118.         TIM_SetCounter(TIM8,0);//计数器清零
  119.         TIM_Cmd(TIM8, ENABLE);  //使能TIM8
  120. }
  121. /********************************************
  122. //相对定位函数
  123. //num 0~2147483647
  124. //frequency: 20Hz~100KHz
  125. //dir: CW(顺时针方向)  CCW(逆时针方向)
  126. *********************************************/
  127. void Locate_Rle(long num,u32 frequency,DIR_Type dir) //相对定位函数
  128. {
  129.         if(num<=0) //数值小等于0 则直接返回
  130.         {
  131.                 printf("\r\nThe num should be greater than zero!!\r\n");
  132.                 return;
  133.         }
  134.         if(TIM8->CR1&0x01)//上一次脉冲还未发送完成  直接返回
  135.         {
  136.                 printf("\r\nThe last time pulses is not send finished,wait please!\r\n");
  137.                 return;
  138.         }
  139.         if((frequency<20)||(frequency>100000))//脉冲频率不在范围内 直接返回
  140.         {
  141.                 printf("\r\nThe frequency is out of range! please reset it!!(range:20Hz~100KHz)\r\n");
  142.                 return;
  143.         }
  144.         motor_dir=dir;//得到方向       
  145.         DRIVER_DIR=motor_dir;//设置方向
  146.        
  147.         if(motor_dir==CW)//顺时针
  148.                 target_pos=current_pos+num;//目标位置
  149.         else if(motor_dir==CCW)//逆时针
  150.                 target_pos=current_pos-num;//目标位置
  151.        
  152.         rcr_integer=num/(RCR_VAL+1);//重复计数整数部分
  153.         rcr_remainder=num%(RCR_VAL+1);//重复计数余数部分
  154.         is_rcr_finish=0;//重复计数器未设置完成
  155.         TIM8_Startup(frequency);//开启TIM8
  156. }
  157. /********************************************
  158. //绝对定位函数
  159. //num   -2147483648~2147483647
  160. //frequency: 20Hz~100KHz
  161. *********************************************/
  162. void Locate_Abs(long num,u32 frequency)//绝对定位函数
  163. {
  164.         if(TIM8->CR1&0x01)//上一次脉冲还未发送完成 直接返回
  165.         {
  166.                 printf("\r\nThe last time pulses is not send finished,wait please!\r\n");
  167.                 return;
  168.         }
  169.         if((frequency<20)||(frequency>100000))//脉冲频率不在范围内 直接返回
  170.         {
  171.                 printf("\r\nThe frequency is out of range! please reset it!!(range:20Hz~100KHz)\r\n");
  172.                 return;
  173.         }
  174.         target_pos=num;//设置目标位置
  175.         if(target_pos!=current_pos)//目标和当前位置不同
  176.         {
  177.                 if(target_pos>current_pos)
  178.                         motor_dir=CW;//顺时针
  179.                 else
  180.                         motor_dir=CCW;//逆时针
  181.                 DRIVER_DIR=motor_dir;//设置方向
  182.                
  183.                 rcr_integer=abs(target_pos-current_pos)/(RCR_VAL+1);//重复计数整数部分
  184.                 rcr_remainder=abs(target_pos-current_pos)%(RCR_VAL+1);//重复计数余数部分
  185.                 is_rcr_finish=0;//重复计数器设置完成
  186.                 TIM8_Startup(frequency);//开启TIM8
  187.         }
  188. }





复制代码


电机B:
  1. #include "driver.h"
  2. #include "delay.h"
  3. #include "usart.h"


  4. u8 rcr_remainder;   //重复计数余数部分
  5. u8 is_rcr_finish=1; //重复计数器是否设置完成
  6. long rcr_integer;        //重复计数整数部分
  7. long target_pos=0;  //有符号方向
  8. long current_pos=0; //有符号方向
  9. DIR_Type motor_dir=CCW;//顺时针

  10. /************** 驱动器控制信号线初始化 ****************/
  11. void Driver_Init(void)
  12. {
  13.         GPIO_InitTypeDef  GPIO_InitStructure;

  14.         RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG, ENABLE);//使能GPIOG时钟

  15.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3|GPIO_Pin_4; //DRIVER_DIR DRIVER_OE对应引脚
  16.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
  17.         GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
  18.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100M
  19.         GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
  20.         GPIO_Init(GPIOG, &GPIO_InitStructure);//初始化GPIOG3,4
  21.        
  22.         GPIO_ResetBits(GPIOG,GPIO_Pin_3);//PG3输出低 使能输出  DRIVER_ENA
  23.         GPIO_SetBits(GPIOG,GPIO_Pin_4);//PG4输出高 顺时针方向  DRIVER_DIR
  24.        
  25. }


  26. /***********************************************
  27. //TIM8_CH2(PC7) 单脉冲输出+重复计数功能初始化
  28. //TIM8 时钟频率 84*2=168MHz
  29. //arr:自动重装值
  30. //psc:时钟预分频数
  31. ************************************************/
  32. void TIM8_OPM_RCR_Init(u16 arr,u16 psc)
  33. {                                                          
  34.         GPIO_InitTypeDef GPIO_InitStructure;
  35.         TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
  36.         TIM_OCInitTypeDef  TIM_OCInitStructure;
  37.         NVIC_InitTypeDef NVIC_InitStructure;

  38.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8,ENABLE);          //TIM8时钟使能   
  39.         RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);         //使能PORTC时钟                                                                                    

  40.         GPIO_PinAFConfig(GPIOC,GPIO_PinSource7,GPIO_AF_TIM8); //GPIOC7复用为定时器8
  41.        
  42.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;           //GPIOC7
  43.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;        //复用功能
  44.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;        //速度100MHz
  45.         GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;      //推挽复用输出
  46.         GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;      //下拉
  47.         GPIO_Init(GPIOC,&GPIO_InitStructure);               //初始化PC7
  48.        
  49.         TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
  50.        
  51.         TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值         
  52.         TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值   
  53.         TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
  54.         TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
  55.         TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
  56.         TIM_ClearITPendingBit(TIM8,TIM_IT_Update);

  57.         TIM_UpdateRequestConfig(TIM8,TIM_UpdateSource_Regular); /********* 设置只有计数溢出作为更新中断 ********/
  58.         TIM_SelectOnePulseMode(TIM8,TIM_OPMode_Single);/******* 单脉冲模式 **********/

  59.         TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2
  60.         TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出2使能
  61.         TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable; /****** 比较输出2N失能 *******/
  62.         TIM_OCInitStructure.TIM_Pulse = arr>>1; //设置待装入捕获比较寄存器的脉冲值,右移一位
  63.         TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
  64.         TIM_OC2Init(TIM8, &TIM_OCInitStructure);  //根据TIM_OCInitStruct中指定的参数初始化外设TIMx

  65.         TIM_OC2PreloadConfig(TIM8, TIM_OCPreload_Enable);  //CH2预装载使能         
  66.         TIM_ARRPreloadConfig(TIM8, ENABLE); //使能TIMx在ARR上的预装载寄存器
  67.        
  68.         TIM_ITConfig(TIM8, TIM_IT_Update ,ENABLE);  //TIM8   使能或者失能指定的TIM中断

  69.         NVIC_InitStructure.NVIC_IRQChannel = TIM8_UP_TIM13_IRQn;  //TIM8中断
  70.         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;  //先占优先级1级
  71.         NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;  //从优先级1级
  72.         NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
  73.         NVIC_Init(&NVIC_InitStructure);  //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
  74.        
  75.         TIM_ClearITPendingBit(TIM8, TIM_IT_Update);  //清除TIMx的中断待处理位:TIM 中断源
  76.         TIM_Cmd(TIM8, ENABLE);  //使能TIM8                                                                                          
  77. }
  78. /******* TIM8更新中断服务程序 *********/
  79. void TIM8_UP_TIM13_IRQHandler(void)
  80. {
  81.         if(TIM_GetITStatus(TIM8,TIM_FLAG_Update)!=RESET)//获取当前定时器状态,判断是否完成更新,更新中断
  82.         {
  83.                 TIM_ClearITPendingBit(TIM8,TIM_FLAG_Update);//清除更新中断标志位               
  84.                 if(is_rcr_finish==0)//重复计数器未设置完成    重复计数器默认初始值为1,已完成状态
  85.                 {
  86.                         if(rcr_integer!=0) //整数部分脉冲还未发送完成
  87.                         {
  88.                                 TIM8->RCR=RCR_VAL;//设置重复计数值
  89.                                 rcr_integer--;//减少RCR_VAL+1个脉冲                               
  90.                         }else if(rcr_remainder!=0)//余数部分脉冲 不为0
  91.                         {
  92.                                 TIM8->RCR=rcr_remainder-1;//设置余数部分
  93.                                 rcr_remainder=0;//清零
  94.                                 is_rcr_finish=1;//重复计数器设置完成                               
  95.                         }else goto out;   //rcr_remainder=0,直接退出                         
  96.                         TIM_GenerateEvent(TIM8,TIM_EventSource_Update);//产生一个更新事件 重新初始化计数器
  97.                         TIM_CtrlPWMOutputs(TIM8,ENABLE);        //MOE 主输出使能       
  98.                         TIM_Cmd(TIM8, ENABLE);  //使能TIM8                       
  99.                         if(motor_dir==CW) //如果方向为顺时针   
  100.                                 current_pos+=(TIM8->RCR+1);//加上重复计数值
  101.                         else          //否则方向为逆时针
  102.                                 current_pos-=(TIM8->RCR+1);//减去重复计数值                       
  103.                 }else
  104.                 {
  105. out:                is_rcr_finish=1;//重复计数器设置完成
  106.                         TIM_CtrlPWMOutputs(TIM8,DISABLE);        //MOE 主输出关闭
  107.                         TIM_Cmd(TIM8, DISABLE);  //关闭TIM8                                V
  108.                         printf("当前位置=%ld\r\n",current_pos);//打印输出
  109.                 }       
  110.         }
  111. }
  112. /***************** 启动TIM8 *****************/
  113. void TIM8_Startup(u32 frequency)   //启动定时器8
  114. {
  115.         u16 temp_arr=1000000/frequency-1;
  116.         TIM_SetAutoreload(TIM8,temp_arr);//设定自动重装值       
  117.         TIM_SetCompare2(TIM8,temp_arr>>1); //匹配值2等于重装值一半,是以占空比为50%       
  118.         TIM_SetCounter(TIM8,0);//计数器清零
  119.         TIM_Cmd(TIM8, ENABLE);  //使能TIM8
  120. }
  121. /********************************************
  122. //相对定位函数
  123. //num 0~2147483647
  124. //frequency: 20Hz~100KHz
  125. //dir: CW(顺时针方向)  CCW(逆时针方向)
  126. *********************************************/
  127. void Locate_Rle(long num,u32 frequency,DIR_Type dir) //相对定位函数
  128. {
  129.         if(num<=0) //数值小等于0 则直接返回
  130.         {
  131.                 printf("\r\nThe num should be greater than zero!!\r\n");
  132.                 return;
  133.         }
  134.         if(TIM8->CR1&0x01)//上一次脉冲还未发送完成  直接返回
  135.         {
  136.                 printf("\r\nThe last time pulses is not send finished,wait please!\r\n");
  137.                 return;
  138.         }
  139.         if((frequency<20)||(frequency>100000))//脉冲频率不在范围内 直接返回
  140.         {
  141.                 printf("\r\nThe frequency is out of range! please reset it!!(range:20Hz~100KHz)\r\n");
  142.                 return;
  143.         }
  144.         motor_dir=dir;//得到方向       
  145.         DRIVER_DIR=motor_dir;//设置方向
  146.        
  147.         if(motor_dir==CW)//顺时针
  148.                 target_pos=current_pos+num;//目标位置
  149.         else if(motor_dir==CCW)//逆时针
  150.                 target_pos=current_pos-num;//目标位置
  151.        
  152.         rcr_integer=num/(RCR_VAL+1);//重复计数整数部分
  153.         rcr_remainder=num%(RCR_VAL+1);//重复计数余数部分
  154.         is_rcr_finish=0;//重复计数器未设置完成
  155.         TIM8_Startup(frequency);//开启TIM8
  156. }
  157. /********************************************
  158. //绝对定位函数
  159. //num   -2147483648~2147483647
  160. //frequency: 20Hz~100KHz
  161. *********************************************/
  162. void Locate_Abs(long num,u32 frequency)//绝对定位函数
  163. {
  164.         if(TIM8->CR1&0x01)//上一次脉冲还未发送完成 直接返回
  165.         {
  166.                 printf("\r\nThe last time pulses is not send finished,wait please!\r\n");
  167.                 return;
  168.         }
  169.         if((frequency<20)||(frequency>100000))//脉冲频率不在范围内 直接返回
  170.         {
  171.                 printf("\r\nThe frequency is out of range! please reset it!!(range:20Hz~100KHz)\r\n");
  172.                 return;
  173.         }
  174.         target_pos=num;//设置目标位置
  175.         if(target_pos!=current_pos)//目标和当前位置不同
  176.         {
  177.                 if(target_pos>current_pos)
  178.                         motor_dir=CW;//顺时针
  179.                 else
  180.                         motor_dir=CCW;//逆时针
  181.                 DRIVER_DIR=motor_dir;//设置方向
  182.                
  183.                 rcr_integer=abs(target_pos-current_pos)/(RCR_VAL+1);//重复计数整数部分
  184.                 rcr_remainder=abs(target_pos-current_pos)%(RCR_VAL+1);//重复计数余数部分
  185.                 is_rcr_finish=0;//重复计数器设置完成
  186.                 TIM8_Startup(frequency);//开启TIM8
  187.         }
  188. }





复制代码



两个驱动大部分都是一样的,不同的就是用到的引脚,通道不同,如何做可以使主函数里面可以驱动这两个电机,我现在放在一个项目里面,只有一个电机动,另外一个不动,有大佬给我说用RTOS多线程去做,是怎么个方法思路呢,我也是刚接触STM32不到两周的时间,比较迷茫,清各位给我指导一下。

最佳答案

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

5

主题

18

帖子

0

精华

初级会员

Rank: 2

积分
129
金钱
129
注册时间
2019-12-30
在线时间
22 小时
 楼主| 发表于 2020-7-31 15:16:41 | 显示全部楼层
回复

使用道具 举报

117

主题

598

帖子

1

精华

资深版主

Rank: 8Rank: 8

积分
1702
金钱
1702
注册时间
2012-5-10
在线时间
439 小时
发表于 2020-7-31 16:38:47 | 显示全部楼层
看看我的,希望给你思路,一个定时器控制十几个电机
  1. static Motor GB_Motors[Motor_Total_Num] =
  2. {
  3.     //Motor_1
  4.     {   
  5.         .name = Motor_1,
  6.         
  7.         .step_gpio_group = Motor1_CLK_Group,                                                //电机clk gpio group
  8.         .step_gpio_pin = Motor1_CLK_Pin,                                                    //电机clk gpio pin

  9.         .dir_gpio_group = Motor1_DIR_Group,                                                 //电机方向 gpio group
  10.         .dir_gpio_pin = Motor1_DIR_Pin,                                                     //电机方向 gpio pin
  11.         .forward_value = GPIO_PIN_RESET,                                                    //电机正向运动电平

  12.         .en_gpio_group = NULL,                                                              //电机使能 gpio group

  13.         .sensor_gpio_group = {Motor1_Origin_Group, BloodHolder_On_Start_Group},             //电机 传感器 gpio group
  14.         .sensor_gpio_pin = {Motor1_Origin_Pin, BloodHolder_On_Start_Pin},                   //电机 传感器 gpio pin
  15.         .sensor_triggered_value = {GPIO_PIN_RESET, GPIO_PIN_RESET},                         //电机 传感器 触发电平
  16.         .sensor_enable = {true, true},                                                      //电机传感器 使能,默认打开,可动态调整
  17.         .sensor_triggered_cnt = {0, 0},                                                     //传感器连续触发次数
  18.         .sensor_triggered_pass_cnt = {50, 50},                                                //传感器确认触发次数

  19.         .normalTotalPwmCnt = 4,

  20.         .motorLocation = 0,
  21.         .targetLocation = 0,
  22.         .isSLine = false,
  23.         //测量最大行程为18000,设置超限位置为20000
  24.         //.max_location = 20000,
  25.         //精确测量 全程运行4.5秒
  26.         //.out_time = 6000,

  27.         .minPwmCnt = 20,
  28.         .maxPwmCnt = 4,
  29.         .seriesParm = 4,
  30.         .changeParm = 100,
  31.     },

  32.     //Motor_2
  33.     {   
  34.         .name = Motor_2,
  35.         
  36.         .step_gpio_group = Motor2_CLK_Group,                                                //电机clk gpio group
  37.         .step_gpio_pin = Motor2_CLK_Pin,                                                    //电机clk gpio pin

  38.         .dir_gpio_group = Motor2_DIR_Group,                                                 //电机方向 gpio group
  39.         .dir_gpio_pin = Motor2_DIR_Pin,                                                     //电机方向 gpio pin
  40.         .forward_value = GPIO_PIN_RESET,                                                    //电机正向运动电平

  41.         .en_gpio_group = NULL,                                                              //电机使能 gpio group

  42.         .sensor_gpio_group = {Blood_Check_Group, NULL},             //电机 传感器 gpio group
  43.         .sensor_gpio_pin = {Blood_Check_Pin, NULL},                   //电机 传感器 gpio pin
  44.         .sensor_triggered_value = {GPIO_PIN_SET, GPIO_PIN_RESET},                         //电机 传感器 触发电平
  45.         .sensor_enable = {true, true},                                                      //电机传感器 使能,默认打开,可动态调整
  46.         .sensor_triggered_cnt = {0, 0},                                                     //传感器连续触发次数
  47.         .sensor_triggered_pass_cnt = {250, 1},                                                //传感器确认触发次数

  48.         .normalTotalPwmCnt = 3,

  49.         .motorLocation = 0,
  50.         .targetLocation = 0,
  51.         .isSLine = true,
  52.         //.max_location = 5000,
  53.         //.out_time = 50000,

  54.         .minPwmCnt = 40,
  55.         .maxPwmCnt = 5,
  56.         .seriesParm = 4,
  57.         .changeParm = 35
  58.     },

  59.     //Motor_3
  60.     {   
  61.         .name = Motor_3,
  62.         
  63.         .step_gpio_group = Motor3_CLK_Group,                                                //电机clk gpio group
  64.         .step_gpio_pin = Motor3_CLK_Pin,                                                    //电机clk gpio pin

  65.         .dir_gpio_group = Motor3_DIR_Group,                                                 //电机方向 gpio group
  66.         .dir_gpio_pin = Motor3_DIR_Pin,                                                     //电机方向 gpio pin
  67.         .forward_value = GPIO_PIN_SET,                                                    //电机正向运动电平

  68.         .en_gpio_group = NULL,                                                              //电机使能 gpio group

  69.         .sensor_gpio_group = {Motor_3_Origin_Group, NULL},             //电机 传感器 gpio group
  70.         .sensor_gpio_pin = {Motor_3_Origin_Pin, NULL},                   //电机 传感器 gpio pin
  71.         .sensor_triggered_value = {GPIO_PIN_RESET, GPIO_PIN_RESET},                         //电机 传感器 触发电平
  72.         .sensor_enable = {true, true},                                                      //电机传感器 使能,默认打开,可动态调整
  73.         .sensor_triggered_cnt = {0, 0},                                                     //传感器连续触发次数
  74.         .sensor_triggered_pass_cnt = {50, 1},                                                //传感器确认触发次数

  75.         .normalTotalPwmCnt = 4,

  76.         .motorLocation = 0,
  77.         .targetLocation = 0,
  78.         .isSLine = false,

  79.         .minPwmCnt = 20,
  80.         .maxPwmCnt = 4,
  81.         .seriesParm = 4,
  82.         .changeParm = 500
  83.     },
  84.     //Motor_4
  85.     {   
  86.         .name = Motor_4,
  87.         
  88.         .step_gpio_group = Motor4_CLK_Group,                                                //电机clk gpio group
  89.         .step_gpio_pin = Motor4_CLK_Pin,                                                    //电机clk gpio pin

  90.         .dir_gpio_group = Motor4_DIR_Group,                                                 //电机方向 gpio group
  91.         .dir_gpio_pin = Motor4_DIR_Pin,                                                     //电机方向 gpio pin
  92.         .forward_value = GPIO_PIN_SET,                                                      //电机正向运动电平

  93.         .en_gpio_group = NULL,                                                              //电机使能 gpio group

  94.         .sensor_gpio_group = {Motor_4_Origin_Group, NULL},                                  //电机 传感器 gpio group
  95.         .sensor_gpio_pin = {Motor_4_Origin_Pin, NULL},                                      //电机 传感器 gpio pin
  96.         .sensor_triggered_value = {GPIO_PIN_SET, GPIO_PIN_RESET},                           //电机 传感器 触发电平
  97.         .sensor_enable = {true, true},                                                      //电机传感器 使能,默认打开,可动态调整
  98.         .sensor_triggered_cnt = {0, 0},                                                     //传感器连续触发次数
  99.         .sensor_triggered_pass_cnt = {250, 1},                                              //传感器确认触发次数

  100.         .normalTotalPwmCnt = 4,
  101.         .motorLocation = 0,
  102.         .targetLocation = 0,
  103.         .isSLine = true,
  104.         //.max_location = 27000,
  105.         //.out_time = 10000,

  106.         .minPwmCnt = 15,
  107.         .maxPwmCnt = 4,
  108.         .seriesParm = 6,
  109.         .changeParm = 1500
  110.     },
  111.     //Motor_5
  112.     {   
  113.         .name = Motor_5,
  114.         
  115.         .step_gpio_group = Motor5_CLK_Group,                                                //电机clk gpio group
  116.         .step_gpio_pin = Motor5_CLK_Pin,                                                    //电机clk gpio pin

  117.         .dir_gpio_group = Motor5_DIR_Group,                                                 //电机方向 gpio group
  118.         .dir_gpio_pin = Motor5_DIR_Pin,                                                     //电机方向 gpio pin
  119.         .forward_value = GPIO_PIN_RESET,                                                    //电机正向运动电平

  120.         .en_gpio_group = NULL,                                                              //电机使能 gpio group

  121.         .sensor_gpio_group = {Motor_5_Origin_Group, NULL},             //电机 传感器 gpio group
  122.         .sensor_gpio_pin = {Motor_5_Origin_Pin, NULL},                   //电机 传感器 gpio pin
  123.         .sensor_triggered_value = {GPIO_PIN_RESET, GPIO_PIN_RESET},                         //电机 传感器 触发电平
  124.         .sensor_enable = {true, true},                                                      //电机传感器 使能,默认打开,可动态调整
  125.         .sensor_triggered_cnt = {0, 0},                                                     //传感器连续触发次数
  126.         .sensor_triggered_pass_cnt = {50, 1},                                                //传感器确认触发次数

  127.         .normalTotalPwmCnt = 4,
  128.         .motorLocation = 0,
  129.         .targetLocation = 0,
  130.         .isSLine = false,
  131.         //.max_location = 28000,
  132.         //.out_time = 7500,

  133.         .minPwmCnt = 20,
  134.         .maxPwmCnt = 3,
  135.         .seriesParm = 6,
  136.         .changeParm = 500
  137.     },
  138.     //Motor_6
  139.     {   
  140.         .name = Motor_6,
  141.         
  142.         .step_gpio_group = Motor6_CLK_Group,                                                //电机clk gpio group
  143.         .step_gpio_pin = Motor6_CLK_Pin,                                                    //电机clk gpio pin

  144.         .dir_gpio_group = Motor6_DIR_Group,                                                 //电机方向 gpio group
  145.         .dir_gpio_pin = Motor6_DIR_Pin,                                                     //电机方向 gpio pin
  146.         .forward_value = GPIO_PIN_RESET,                                                    //电机正向运动电平

  147.         .en_gpio_group = NULL,                                                              //电机使能 gpio group

  148.         .sensor_gpio_group = {Motor_6_Origin_Group, NULL},             //电机 传感器 gpio group
  149.         .sensor_gpio_pin = {Motor_6_Origin_Pin, NULL},                   //电机 传感器 gpio pin
  150.         .sensor_triggered_value = {GPIO_PIN_RESET, GPIO_PIN_RESET},                         //电机 传感器 触发电平
  151.         .sensor_enable = {true, true},                                                      //电机传感器 使能,默认打开,可动态调整
  152.         .sensor_triggered_cnt = {0, 0},                                                     //传感器连续触发次数
  153.         .sensor_triggered_pass_cnt = {50, 1},                                                //传感器确认触发次数

  154.         .normalTotalPwmCnt = 15,
  155.         .motorLocation = 0,
  156.         .targetLocation = 0,
  157.         .isSLine = false,
  158.         //.max_location = 5500,
  159.         //.out_time = 2300,

  160.         .minPwmCnt = 20,
  161.         .maxPwmCnt = 3,
  162.         .seriesParm = 6,
  163.         .changeParm = 500
  164.     },
  165.     //Motor_7
  166.     {   
  167.         .name = Motor_7,
  168.         
  169.         .step_gpio_group = Motor7_CLK_Group,                                                //电机clk gpio group
  170.         .step_gpio_pin = Motor7_CLK_Pin,                                                    //电机clk gpio pin

  171.         .dir_gpio_group = Motor7_DIR_Group,                                                 //电机方向 gpio group
  172.         .dir_gpio_pin = Motor7_DIR_Pin,                                                     //电机方向 gpio pin
  173.         .forward_value = GPIO_PIN_RESET,                                                    //电机正向运动电平

  174.         .en_gpio_group = NULL,                                                              //电机使能 gpio group

  175.         .sensor_gpio_group = {Motor_7_Origin_Group, NULL},             //电机 传感器 gpio group
  176.         .sensor_gpio_pin = {Motor_7_Origin_Pin, NULL},                   //电机 传感器 gpio pin
  177.         .sensor_triggered_value = {GPIO_PIN_RESET, GPIO_PIN_RESET},                         //电机 传感器 触发电平
  178.         .sensor_enable = {true, true},                                                      //电机传感器 使能,默认打开,可动态调整
  179.         .sensor_triggered_cnt = {0, 0},                                                     //传感器连续触发次数
  180.         .sensor_triggered_pass_cnt = {250, 1},                                                //传感器确认触发次数

  181.         .normalTotalPwmCnt = 4,
  182.         .motorLocation = 0,
  183.         .targetLocation = 0,
  184.         .isSLine = true,
  185.         //.max_location = 20000,
  186.         //.out_time = 8000,

  187.         .minPwmCnt = 15,
  188.         .maxPwmCnt = 4,
  189.         .seriesParm = 6,
  190.         .changeParm = 1000
  191.     },
  192.     //Motor_8   排液针电机,即三轴平台Z2
  193.     {   
  194.         .name = Motor_8,
  195.         
  196.         .step_gpio_group = Motor8_CLK_Group,                                                //电机clk gpio group
  197.         .step_gpio_pin = Motor8_CLK_Pin,                                                    //电机clk gpio pin

  198.         .dir_gpio_group = Motor8_DIR_Group,                                                 //电机方向 gpio group
  199.         .dir_gpio_pin = Motor8_DIR_Pin,                                                     //电机方向 gpio pin
  200.         .forward_value = GPIO_PIN_SET,                                                    //电机正向运动电平

  201.         .en_gpio_group = NULL,                                                              //电机使能 gpio group

  202.         .sensor_gpio_group = {Motor_8_Origin_Group, NULL},             //电机 传感器 gpio group
  203.         .sensor_gpio_pin = {Motor_8_Origin_Pin, NULL},                   //电机 传感器 gpio pin
  204.         .sensor_triggered_value = {GPIO_PIN_RESET, GPIO_PIN_RESET},                         //电机 传感器 触发电平
  205.         .sensor_enable = {true, true},                                                      //电机传感器 使能,默认打开,可动态调整
  206.         .sensor_triggered_cnt = {0, 0},                                                     //传感器连续触发次数
  207.         .sensor_triggered_pass_cnt = {50, 1},                                                //传感器确认触发次数

  208.         .normalTotalPwmCnt = 8,
  209.         .motorLocation = 0,
  210.         .targetLocation = 0,
  211.         .isSLine = false,
  212.         //.max_location = 2000,
  213.         //.out_time = 2000,

  214.         .minPwmCnt = 20,
  215.         .maxPwmCnt = 4,
  216.         .seriesParm = 4,
  217.         .changeParm = 100
  218.     },
  219.     //Motor_10
  220.     {   
  221.         .name = Motor_10,
  222.         
  223.         .step_gpio_group = Motor10_CLK_Group,                                                //电机clk gpio group
  224.         .step_gpio_pin = Motor10_CLK_Pin,                                                    //电机clk gpio pin

  225.         .dir_gpio_group = Motor10_DIR_Group,                                                 //电机方向 gpio group
  226.         .dir_gpio_pin = Motor10_DIR_Pin,                                                     //电机方向 gpio pin
  227.         .forward_value = GPIO_PIN_RESET,                                                    //电机正向运动电平

  228.         .en_gpio_group = NULL,                                                              //电机使能 gpio group

  229.         .sensor_gpio_group = {Motor_10_Origin_Group, Water_Deep_Check_Group},                                 //电机 传感器 gpio group
  230.         .sensor_gpio_pin = {Motor_10_Origin_Pin, Water_Deep_Check_Pin},                                     //电机 传感器 gpio pin
  231.         .sensor_triggered_value = {GPIO_PIN_RESET, GPIO_PIN_SET},                         //电机 传感器 触发电平
  232.         .sensor_enable = {true, true},                                                      //电机传感器 使能,默认打开,可动态调整
  233.         .sensor_triggered_cnt = {0, 0},                                                     //传感器连续触发次数
  234.         .sensor_triggered_pass_cnt = {50, 50},                                                //传感器确认触发次数

  235.         .normalTotalPwmCnt = 3,
  236.         .motorLocation = 0,
  237.         .targetLocation = 0,
  238.         .isSLine = false,
  239.         //.max_location = 13500,
  240.         //.out_time = 3000,

  241.         .minPwmCnt = 20,
  242.         .maxPwmCnt = 4,
  243.         .seriesParm = 4,
  244.         .changeParm = 100
  245.     },

  246.     //Motor_12
  247.     {   
  248.         .name = Motor_12,
  249.         
  250.         .step_gpio_group = Motor12_CLK_Group,                                                //电机clk gpio group
  251.         .step_gpio_pin = Motor12_CLK_Pin,                                                    //电机clk gpio pin

  252.         .dir_gpio_group = Motor12_DIR_Group,                                                 //电机方向 gpio group
  253.         .dir_gpio_pin = Motor12_DIR_Pin,                                                     //电机方向 gpio pin
  254.         .forward_value = GPIO_PIN_RESET,                                                    //电机正向运动电平

  255.         .en_gpio_group = NULL,                                                              //电机使能 gpio group

  256.         .sensor_gpio_group = {Motor_12_Origin_Group, NULL},             //电机 传感器 gpio group
  257.         .sensor_gpio_pin = {Motor_12_Origin_Pin, NULL},                   //电机 传感器 gpio pin
  258.         .sensor_triggered_value = {GPIO_PIN_RESET, GPIO_PIN_RESET},                         //电机 传感器 触发电平
  259.         .sensor_enable = {true, true},                                                      //电机传感器 使能,默认打开,可动态调整
  260.         .sensor_triggered_cnt = {0, 0},                                                     //传感器连续触发次数
  261.         .sensor_triggered_pass_cnt = {50, 1},                                                //传感器确认触发次数

  262.         .normalTotalPwmCnt = 3,
  263.         .motorLocation = 0,
  264.         .targetLocation = 0,
  265.         .isSLine = false,

  266.         .minPwmCnt = 20,
  267.         .maxPwmCnt = 4,
  268.         .seriesParm = 4,
  269.         .changeParm = 100
  270.     },

  271.     //Motor_14
  272.     {   
  273.         .name = Motor_14,
  274.         
  275.         .step_gpio_group = Motor14_CLK_Group,                                                //电机clk gpio group
  276.         .step_gpio_pin = Motor14_CLK_Pin,                                                    //电机clk gpio pin

  277.         .dir_gpio_group = Motor14_DIR_Group,                                                 //电机方向 gpio group
  278.         .dir_gpio_pin = Motor14_DIR_Pin,                                                     //电机方向 gpio pin
  279.         .forward_value = GPIO_PIN_RESET,                                                    //电机正向运动电平

  280.         .en_gpio_group = NULL,                                                              //电机使能 gpio group

  281.         .sensor_gpio_group = {Motor_14_Origin_Group, NULL},             //电机 传感器 gpio group
  282.         .sensor_gpio_pin = {Motor_14_Origin_Pin, NULL},                   //电机 传感器 gpio pin
  283.         .sensor_triggered_value = {GPIO_PIN_RESET, GPIO_PIN_RESET},                         //电机 传感器 触发电平
  284.         .sensor_enable = {true, true},                                                      //电机传感器 使能,默认打开,可动态调整
  285.         .sensor_triggered_cnt = {0, 0},                                                     //传感器连续触发次数
  286.         .sensor_triggered_pass_cnt = {50, 1},                                                //传感器确认触发次数

  287.         .normalTotalPwmCnt = 4,
  288.         .motorLocation = 0,
  289.         .targetLocation = 0,
  290.         .isSLine = false,
  291.         //.max_location = 28000,
  292.         //.out_time = 7500,

  293.         .minPwmCnt = 20,
  294.         .maxPwmCnt = 3,
  295.         .seriesParm = 6,
  296.         .changeParm = 500
  297.     },
  298.     //Motor_15
  299.     {
  300.         .name = Motor_15,
  301.         
  302.         .step_gpio_group = Motor15_CLK_Group,                                                //电机clk gpio group
  303.         .step_gpio_pin = Motor15_CLK_Pin,                                                    //电机clk gpio pin

  304.         .dir_gpio_group = Motor15_DIR_Group,                                                 //电机方向 gpio group
  305.         .dir_gpio_pin = Motor15_DIR_Pin,                                                     //电机方向 gpio pin
  306.         .forward_value = GPIO_PIN_RESET,                                                    //电机正向运动电平

  307.         .en_gpio_group = NULL,                                                              //电机使能 gpio group

  308.         .sensor_gpio_group = {Motor_15_Origin_Group, NULL},             //电机 传感器 gpio group
  309.         .sensor_gpio_pin = {Motor_15_Origin_Pin, NULL},                   //电机 传感器 gpio pin
  310.         .sensor_triggered_value = {GPIO_PIN_RESET, GPIO_PIN_RESET},                         //电机 传感器 触发电平
  311.         .sensor_enable = {true, true},                                                      //电机传感器 使能,默认打开,可动态调整
  312.         .sensor_triggered_cnt = {0, 0},                                                     //传感器连续触发次数
  313.         .sensor_triggered_pass_cnt = {50, 1},                                                //传感器确认触发次数

  314.         .normalTotalPwmCnt = 15,
  315.         .motorLocation = 0,
  316.         .targetLocation = 0,
  317.         .isSLine = false,
  318.         //.max_location = 5500,
  319.         //.out_time = 2300,

  320.         .minPwmCnt = 20,
  321.         .maxPwmCnt = 3,
  322.         .seriesParm = 6,
  323.         .changeParm = 500
  324.     },
  325. };
复制代码
如有技术问题,微信扫头像交流,STM32,JAVA,服务器
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165475
金钱
165475
注册时间
2010-12-1
在线时间
2115 小时
发表于 2020-8-2 23:33:09 | 显示全部楼层
帮顶
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-4-30 15:49

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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