打印

GD32F103VBT6带多路步进电机工作不正常,请高手们指点一下

[复制链接]
771|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
gdszzyq|  楼主 | 2022-4-14 15:50 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我原来用的是STM32F103VBT6这款芯片做的控制板,想用GD32F103VBT6替换,于是做了几块样板测试,我用原ST库写的程序只是修改了那几个超时参数,其它都不变直接烧进去GD的板子上测试,我的产品带5路步进电机,发现当3路以上步进电机同时运转时出现严重丢步情况,而且是在空载的情况下。
同样的程序在ST的板子上都用了几年了都没有问题。论坛上有人说要用GD的库改才行,于是我把程序全部改成GD库的,但一样出现这样情况,找了代理商的FAE找不到原因,我写了个程序同时输出7路PWM信号,用示波器观察波形正常,我怀疑是加减速过程出现问题,但没办法用示波器观察到这个过程,请问大家有没有遇到类似的问题?真的想换GD芯片,ST的太贵了,请高手帮帮我,万分感谢!

使用特权

评论回复

相关帖子

沙发
gdszzyq|  楼主 | 2022-4-14 15:55 | 只看该作者
我用了2个定时器输出5路步进电机的驱动脉冲,用的是输出比较模式产生的PWM信号,没有用默认引脚,而是用别的端口在中断里翻转产生脉冲,周期最大是100微秒。

使用特权

评论回复
板凳
gdszzyq|  楼主 | 2022-4-14 15:56 | 只看该作者
void PWM_Init(void)
{  
   TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;//
   TIM_OCInitTypeDef  TIM_OCInitStructure;    //
   NVIC_InitTypeDef NVIC_InitStructure;
   RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2|RCC_APB1Periph_TIM4, ENABLE); //TIM2\TIM4时钟使能   
   TIM_TimeBaseStructure.TIM_Period = 65535; //自动重装载寄存器周期的值
   TIM_TimeBaseStructure.TIM_Prescaler = 0;  //先不装入分频值
   TIM_TimeBaseStructure.TIM_ClockDivision = 0; //
   TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//
   TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);    //  TIM2
   TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);    //TIM4         
   TIM_PrescalerConfig(TIM2, PrescalerValue, TIM_PSCReloadMode_Immediate);   //预分频值即时装入TIM2   
   TIM_PrescalerConfig(TIM4, PrescalerValue, TIM_PSCReloadMode_Immediate);   //预分频值即时装入TIM4
    //定时器2的CC1配置输出比较模式   
   TIM_OCInitStructure.TIM_OCMode =TIM_OCMode_Timing;   //输出比较触发模式
   TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;   
   TIM_OCInitStructure.TIM_Pulse = First_Motor_Time_Step;   //比较寄存器值
   TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;  //输出极性
   TIM_OC1Init(TIM2, &TIM_OCInitStructure);
   TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Disable);//禁止TIM_CCR1寄存器预装
        //TIM_ITConfig(TIM2, TIM_IT_CC1, ENABLE);//使能比较功能1中断
   
    //定时器2的CC2配置输出比较模式   
   TIM_OCInitStructure.TIM_OCMode =TIM_OCMode_Timing;   //输出比较触发模式
   TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;   
   TIM_OCInitStructure.TIM_Pulse = Second_Motor_Time_Step;   //比较寄存器值
   TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;  //输出极性
   TIM_OC2Init(TIM2, &TIM_OCInitStructure);
   TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Disable);//禁止TIM_CCR2寄存器预装
   //TIM_ITConfig(TIM2, TIM_IT_CC2, ENABLE);//使能比较功能2中断   
       
    //定时器2的CC3配置输出比较模式   
   TIM_OCInitStructure.TIM_OCMode =TIM_OCMode_Timing;   //输出比较触发模式
   TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;   
   TIM_OCInitStructure.TIM_Pulse = Third_Motor_Time_Step;   //比较寄存器值
   TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;  //输出极性
   TIM_OC3Init(TIM2, &TIM_OCInitStructure);
   TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Disable);//禁止TIM_CCR3寄存器预装
   //TIM_ITConfig(TIM2, TIM_IT_CC3, ENABLE);//使能比较功能3中断        
       
    //定时器2的CC4配置输出比较模式   
   /*TIM_OCInitStructure.TIM_OCMode =TIM_OCMode_Timing;   //输出比较触发模式
   TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;   
   TIM_OCInitStructure.TIM_Pulse = Fourth_Motor_Time_Step;   //比较寄存器值
   TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;  //输出极性
   TIM_OC4Init(TIM2, &TIM_OCInitStructure);
   TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Disable);//禁止TIM_CCR4寄存器预装
   //TIM_ITConfig(TIM2, TIM_IT_CC4, ENABLE);//使能比较功能4中断         */       

    //配置TIM2中断
        NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;  //TIM2中断
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;  //抢占优先级1级
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;  //从优先级1级
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
        NVIC_Init(&NVIC_InitStructure);  //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
   
   TIM_Cmd(TIM2, ENABLE); //开启定时器2
       
    //定时器4的CC1配置输出比较模式   
   TIM_OCInitStructure.TIM_OCMode =TIM_OCMode_Timing;   //输出比较触发模式
   TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;   
   TIM_OCInitStructure.TIM_Pulse = Fourth_Motor_Time_Step;   //比较寄存器值
   TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;  //输出极性
   TIM_OC1Init(TIM4, &TIM_OCInitStructure);
   TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Disable);//禁止TIM_CCR1寄存器预装
        //TIM_ITConfig(TIM4, TIM_IT_CC1, ENABLE);//使能比较功能1中断

    //定时器4的CC2配置输出比较模式   
   TIM_OCInitStructure.TIM_OCMode =TIM_OCMode_Timing;   //输出比较触发模式
   TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;   
   TIM_OCInitStructure.TIM_Pulse = Fifth_Motor_Time_Step;   //比较寄存器值
   TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;  //输出极性
   TIM_OC2Init(TIM4, &TIM_OCInitStructure);
   TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Disable);//禁止TIM_CCR2寄存器预装
        //TIM_ITConfig(TIM4, TIM_IT_CC2, ENABLE);//使能比较功能2中断
    //配置TIM4中断
        NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;  //TIM2中断
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;  //抢占优先级1级
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;  //从优先级2级
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
        NVIC_Init(&NVIC_InitStructure);  //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
   
   TIM_Cmd(TIM4, ENABLE); //开启定时器4       
}
void TIM2_IRQHandler(void)   //TIM2中断
{
        if (TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET) //检查指定的TIM中断发生与否:TIM 中断源
        {
                First_Motor_Step=!First_Motor_Step;
                if(First_Motor_Step==1)First_Motor_Step_Count++;
      TIM2->CCR1+=First_Motor_Time_Step;
      TIM_ClearITPendingBit(TIM2, TIM_IT_CC1);
        }
        if (TIM_GetITStatus(TIM2, TIM_IT_CC2) != RESET) //检查指定的TIM中断发生与否:TIM 中断源
        {
      Second_Motor_Step=!Second_Motor_Step;
      if(Second_Motor_Step==1)Second_Motor_Step_Count++;
      TIM2->CCR2+=Second_Motor_Time_Step;
      TIM_ClearITPendingBit(TIM2, TIM_IT_CC2);
        }
        if (TIM_GetITStatus(TIM2, TIM_IT_CC3) != RESET) //检查指定的TIM中断发生与否:TIM 中断源
        {
      Third_Motor_Step=!Third_Motor_Step;               
      if(Third_Motor_Step==1)Third_Motor_Step_Count++;
      TIM2->CCR3+=Third_Motor_Time_Step;
      TIM_ClearITPendingBit(TIM2, TIM_IT_CC3);
        }
}
void TIM4_IRQHandler(void)   //TIM4中断
{
        if (TIM_GetITStatus(TIM4, TIM_IT_CC1) != RESET) //检查指定的TIM中断发生与否:TIM 中断源
        {
                Fourth_Motor_Step=!Fourth_Motor_Step;
      if(Fourth_Motor_Step==1)Fourth_Motor_Step_Count++;
      TIM4->CCR1+=Fourth_Motor_Time_Step;
      TIM_ClearITPendingBit(TIM4, TIM_IT_CC1);
        }          
        if (TIM_GetITStatus(TIM4, TIM_IT_CC2) != RESET) //检查指定的TIM中断发生与否:TIM 中断源
        {
                Fifth_Motor_Step=!Fifth_Motor_Step;
                if(Fifth_Motor_Step==1)Fifth_Motor_Step_Count++;
      TIM4->CCR2+=Fifth_Motor_Time_Step;
      TIM_ClearITPendingBit(TIM4, TIM_IT_CC2);
        }       
}

使用特权

评论回复
地板
gdszzyq|  楼主 | 2022-4-14 15:58 | 只看该作者
以下是GD库写的
void PWM_Init(void)
{  
        timer_parameter_struct timer_initpara;
        timer_oc_parameter_struct timer_ocintpara ;
        rcu_periph_clock_enable(RCU_TIMER2); //TIM2时钟使能
        rcu_periph_clock_enable(RCU_TIMER1); //TIM1时钟使能
        timer_initpara.period            = 65535; //自动重装载寄存器周期的值
        timer_initpara.prescaler         = 0;  //先不装入分频值
        timer_initpara.clockdivision     = 0;
        timer_initpara.alignedmode       = TIMER_COUNTER_UP;
        timer_init(TIMER2,&timer_initpara);    //  TIM2
        timer_init(TIMER1,&timer_initpara);    //  TIM1       
        timer_prescaler_config(TIMER2,PrescalerValue,TIMER_PSC_RELOAD_NOW);   //预分频值即时装入TIM2
        timer_prescaler_config(TIMER1,PrescalerValue,TIMER_PSC_RELOAD_NOW);   //预分频值即时装入TIM1
         //定时器2的CC1配置输出比较模式   
        timer_ocintpara.outputstate  = TIMER_CCX_ENABLE;
        timer_ocintpara.ocnpolarity  = TIMER_OCN_POLARITY_HIGH;  //输出极性
        timer_channel_output_config(TIMER2,TIMER_CH_0,&timer_ocintpara);
        timer_channel_output_pulse_value_config(TIMER2,TIMER_CH_0,First_Motor_Time_Step);   //比较寄存器值
        timer_channel_output_mode_config(TIMER2,TIMER_CH_0,TIMER_OC_MODE_TIMING);   //输出比较触发模式
        timer_channel_output_shadow_config(TIMER2,TIMER_CH_0,TIMER_OC_SHADOW_DISABLE);//禁止TIM_CCR1寄存器预装

//定时器2的CC2配置输出比较模式   
        timer_ocintpara.outputstate  = TIMER_CCX_ENABLE;
        timer_ocintpara.ocnpolarity  = TIMER_OCN_POLARITY_HIGH;  //输出极性
        timer_channel_output_config(TIMER2,TIMER_CH_1,&timer_ocintpara);
        timer_channel_output_pulse_value_config(TIMER2,TIMER_CH_1,First_Motor_Time_Step);   //比较寄存器值
        timer_channel_output_mode_config(TIMER2,TIMER_CH_1,TIMER_OC_MODE_TIMING);   //输出比较触发模式
        timer_channel_output_shadow_config(TIMER2,TIMER_CH_1,TIMER_OC_SHADOW_DISABLE);//禁止TIM_CCR1寄存器预装

   
    //定时器2的CC3配置输出比较模式   
        timer_ocintpara.outputstate  = TIMER_CCX_ENABLE;
        timer_ocintpara.ocnpolarity  = TIMER_OCN_POLARITY_HIGH;  //输出极性
        timer_channel_output_config(TIMER2,TIMER_CH_2,&timer_ocintpara);
        timer_channel_output_pulse_value_config(TIMER2,TIMER_CH_2,First_Motor_Time_Step);   //比较寄存器值
        timer_channel_output_mode_config(TIMER2,TIMER_CH_2,TIMER_OC_MODE_TIMING);   //输出比较触发模式
        timer_channel_output_shadow_config(TIMER2,TIMER_CH_2,TIMER_OC_SHADOW_DISABLE);//禁止TIM_CCR2寄存器预装
       
    //定时器2的CC4配置输出比较模式   
        timer_ocintpara.outputstate  = TIMER_CCX_ENABLE;
        timer_ocintpara.ocnpolarity  = TIMER_OCN_POLARITY_HIGH;  //输出极性
        timer_channel_output_config(TIMER2,TIMER_CH_3,&timer_ocintpara);
        timer_channel_output_pulse_value_config(TIMER2,TIMER_CH_3,First_Motor_Time_Step);   //比较寄存器值
        timer_channel_output_mode_config(TIMER2,TIMER_CH_3,TIMER_OC_MODE_TIMING);   //输出比较触发模式
        timer_channel_output_shadow_config(TIMER2,TIMER_CH_3,TIMER_OC_SHADOW_DISABLE);//禁止TIM_CCR1寄存器预装

    //配置TIM2中断
        nvic_irq_enable(TIMER2_IRQn,0,1);
   
        timer_enable(TIMER2);//开启定时器2
       
    //定时器1的CC1配置输出比较模式   
        timer_ocintpara.outputstate  = TIMER_CCX_ENABLE;
        timer_ocintpara.ocnpolarity  = TIMER_OCN_POLARITY_HIGH;  //输出极性
        timer_channel_output_config(TIMER1,TIMER_CH_0,&timer_ocintpara);
        timer_channel_output_pulse_value_config(TIMER1,TIMER_CH_0,First_Motor_Time_Step);   //比较寄存器值
        timer_channel_output_mode_config(TIMER1,TIMER_CH_0,TIMER_OC_MODE_TIMING);   //输出比较触发模式
        timer_channel_output_shadow_config(TIMER1,TIMER_CH_0,TIMER_OC_SHADOW_DISABLE);//禁止TIM_CCR1寄存器预装
       
    //定时器1的CC2配置输出比较模式   
        timer_ocintpara.outputstate  = TIMER_CCX_ENABLE;
        timer_ocintpara.ocnpolarity  = TIMER_OCN_POLARITY_HIGH;  //输出极性
        timer_channel_output_config(TIMER1,TIMER_CH_1,&timer_ocintpara);
        timer_channel_output_pulse_value_config(TIMER1,TIMER_CH_1,First_Motor_Time_Step);   //比较寄存器值
        timer_channel_output_mode_config(TIMER1,TIMER_CH_1,TIMER_OC_MODE_TIMING);   //输出比较触发模式
        timer_channel_output_shadow_config(TIMER1,TIMER_CH_1,TIMER_OC_SHADOW_DISABLE);//禁止TIM_CCR1寄存器预装

    //定时器1的CC3配置输出比较模式   
        timer_ocintpara.outputstate  = TIMER_CCX_ENABLE;
        timer_ocintpara.ocnpolarity  = TIMER_OCN_POLARITY_HIGH;  //输出极性
        timer_channel_output_config(TIMER1,TIMER_CH_2,&timer_ocintpara);
        timer_channel_output_pulse_value_config(TIMER1,TIMER_CH_2,First_Motor_Time_Step);   //比较寄存器值
        timer_channel_output_mode_config(TIMER1,TIMER_CH_2,TIMER_OC_MODE_TIMING);   //输出比较触发模式
        timer_channel_output_shadow_config(TIMER1,TIMER_CH_2,TIMER_OC_SHADOW_DISABLE);//禁止TIM_CCR1寄存器预装
    //配置TIM1中断
        nvic_irq_enable(TIMER1_IRQn,0,2);

        timer_enable(TIMER1);//开启定时器1
}
void TIMER2_IRQHandler(void)   //TIM2中断
{
        if (timer_interrupt_flag_get(TIMER2, TIMER_INT_FLAG_CH0) != RESET) //检查指定的TIM中断发生与否:TIM 中断源
        {
                First_Motor_Step=!First_Motor_Step;
                if(First_Motor_Step==1)First_Motor_Step_Count++;
                TIMER_CH0CV(TIMER2)+=First_Motor_Time_Step;
                timer_interrupt_flag_clear(TIMER2,TIMER_INT_FLAG_CH0);
        }
        if (timer_interrupt_flag_get(TIMER2, TIMER_INT_FLAG_CH1) != RESET) //检查指定的TIM中断发生与否:TIM 中断源
        {
                Second_Motor_Step=!Second_Motor_Step;
                if(Second_Motor_Step==1)Second_Motor_Step_Count++;
                TIMER_CH1CV(TIMER2)+=Second_Motor_Time_Step;
                timer_interrupt_flag_clear(TIMER2,TIMER_INT_FLAG_CH1);
        }
        if (timer_interrupt_flag_get(TIMER2, TIMER_INT_FLAG_CH2) != RESET) //检查指定的TIM中断发生与否:TIM 中断源
        {
                Third_Motor_Step=!Third_Motor_Step;               
                if(Third_Motor_Step==1)Third_Motor_Step_Count++;
                TIMER_CH2CV(TIMER2)+=Third_Motor_Time_Step;
                timer_interrupt_flag_clear(TIMER2,TIMER_INT_FLAG_CH2);
        }
        if (timer_interrupt_flag_get(TIMER2, TIMER_INT_FLAG_CH3) != RESET) //检查指定的TIM中断发生与否:TIM 中断源
        {
                Seventh_Motor_Step=!Seventh_Motor_Step;
                if(Seventh_Motor_Step==1)Seventh_Motor_Step_Count++;
                TIMER_CH3CV(TIMER2)+=Seventh_Motor_Time_Step;
                timer_interrupt_flag_clear(TIMER2,TIMER_INT_FLAG_CH3);
        }
}
void TIMER1_IRQHandler(void)   //TIM1中断
{
        if (timer_interrupt_flag_get(TIMER1, TIMER_INT_FLAG_CH0) != RESET) //检查指定的TIM中断发生与否:TIM 中断源
        {
                Fourth_Motor_Step=!Fourth_Motor_Step;
                if(Fourth_Motor_Step==1)Fourth_Motor_Step_Count++;
                TIMER_CH0CV(TIMER1)+=Fourth_Motor_Time_Step;
                timer_interrupt_flag_clear(TIMER1,TIMER_INT_FLAG_CH0);
        }
        if (timer_interrupt_flag_get(TIMER1, TIMER_INT_FLAG_CH1) != RESET) //检查指定的TIM中断发生与否:TIM 中断源
        {
                Fifth_Motor_Step=!Fifth_Motor_Step;
                if(Fifth_Motor_Step==1)Fifth_Motor_Step_Count++;
                TIMER_CH1CV(TIMER1)+=Fifth_Motor_Time_Step;
                timer_interrupt_flag_clear(TIMER1,TIMER_INT_FLAG_CH1);
        }
        if (timer_interrupt_flag_get(TIMER1, TIMER_INT_FLAG_CH2) != RESET) //检查指定的TIM中断发生与否:TIM 中断源
        {
                Sixth_Motor_Step=!Sixth_Motor_Step;
                if(Sixth_Motor_Step==1)Sixth_Motor_Step_Count++;
                TIMER_CH2CV(TIMER1)+=Sixth_Motor_Time_Step;
                timer_interrupt_flag_clear(TIMER1,TIMER_INT_FLAG_CH2);
        }
}

使用特权

评论回复
5
单模先声| | 2022-4-14 16:46 | 只看该作者
看功能你这产品售价应该不低,成本差这一两百吗?

使用特权

评论回复
6
HJD001| | 2022-8-2 11:59 | 只看该作者
用我们的F103VBT6, ST的程序根本就不要修改

使用特权

评论回复
7
dyx8899| | 2022-8-4 12:51 | 只看该作者
啥单片机价格相差那么多

使用特权

评论回复
8
单片机搬运工| | 2022-8-12 11:29 | 只看该作者
可以试试九科芯的NS32F103VBT6   性能参数跟ST一样全兼容,需要样品可加V:15818643313

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

46

主题

320

帖子

3

粉丝