This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] EK-TM4C123GXL:具有 CAN 和控制步进电机的 FreeRTOS

Guru**** 2456980 points
Other Parts Discussed in Thread: EK-TM4C123GXL

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/642202/ek-tm4c123gxl-freertos-with-can-and-controlling-stepper-motor

器件型号:EK-TM4C123GXL

您好!

我对这很不熟悉。 我需要一些指导、这样你就可以让我朝着正确的方向前进、因为我现在不知道。 我收到的 CAN 消息中包含一些值、这些值将对应于步进电机的脉冲。 例如、如果字节1包含5、我将需要使用50kHz PWM 向步进电机生成5个脉冲、当下一条消息到达时(字节1中包含6个脉冲)、我将需要生成6个脉冲等(脉冲可能会发生变化)。 因此、我需要一个对达到所需脉冲值的上升沿进行计数的东西、然后中断(禁用 PWM? 还是将占空比设置为0?) 直到下一条 CAN 消息到达并执行相同的操作。 在这里、CCP 计时器是否足够? 如果有任何提示、我们将不胜感激!  

(我能够发送和接收 CAN 消息)

FreeRTOS 用于使用线程。 目前、我在一个线程中有 CAN 接收、在另一个线程中有电机控制。 如果我管理上面的任务、我将为3个电机(如果可能的话)再增加3个螺纹。 很抱歉、如果我不清楚。  

使用 EK-TM4C123GXL 板。

感谢您的观看、

Giancarlo

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用 USER="Giancarlo Kuosmanen">我对此非常陌生。 我需要一些指导、[/引述]

    好的、考虑到您的主题行、这听起来像是您为自己设置了一个挑战

    [引用 user="Giancarlo Kuosmanen"]。 我将收到 CAN 消息、其中包含一些对应于步进电机脉冲的值。[/quot]

    哦。

    [引用 USER="Giancarlo Kuosmanen"]例如、如果字节1包含5、我将需要使用50kHz PWM 向步进电机生成5个脉冲、当下一条消息到达时(字节1中包含6个脉冲)、我将需要生成6个脉冲、以此类推(脉冲可能会有所不同)。 [/报价]

    好的、如果消息重复出现或丢失(CAN 协议中的这两种情况都很自然)、您该怎么办?

    [引用 USER="Giancarlo Kuosmanen">我需要一个对达到所需脉冲值的上升沿进行计数、然后中断的东西(禁用 PWM? 还是将占空比设置为0?) 直到下一条 CAN 消息到达并执行相同的操作。 在这里、CCP 计时器是否足够?[/quot]

    您正在生成脉冲、为什么要从外部对它们进行计数?

    Robert

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您的"标签"注释:"不依赖于完美。"

    然而、您的回答及其总结"标签"(两者)非常符合"依赖性!"    优秀的员工(这次假期2次)和我自己——都很赞……

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用用户="Robert Adsett"]

    您正在生成脉冲、为什么要从外部对它们进行计数?

    Robert

    [/报价]

    发送 CAN 消息中定义的脉冲数量的问题通过使用计时器和 ccp 拆分来计算 PWM 信号的上升沿并使用 TimerDisable 禁用计时器来解决。

    第一条消息工作正常、但不会每次都禁用和启用计时器。  

    代码如下:

    void ringing_interrupt (void)
    {
    TimerIntClear (TIMER0_BASE、TIMER_CAPB_EVENT);
    PULSE_CONTRAIN[1]。tick++;
    if (pulpulate_control[1].tick >(pulpulate_control[1].num_pulses)*32-1)
    {
    TimerDisable (TIMER0_BASE、TIMER_B);
    }
    UARTprintf (" tick interrupt1:%u\t\n"、pulate_control[1].tick);
    }
    
    void initMotors (void)
    {
    
    uint32_t 周期= SysCtlClockGet ()/25000;// 50kHz PWM
    //uint32_t dutyCycle =周期/ 2;// 50%占空比
    /*此部分启用定时器 CCP 电机1. *
    SysCtlPeripheralEnable (SYSCTL_Periph_GPIOF);//启用 F 端口
    //启用和配置 Timer0外设。
    GPIOPinConfigure (GPIO_PF1_T0CCP1); //为 TimerB 启用 PF1引脚 | Timer0 PWM0
    //GPIOPinConfigure (GPIO_PF0_T0CCP0); //为 TimerA 启用 PF0引脚 |定时器0
    GPIOPinTypeTimer (GPIO_PORTF_BASE、GPIO_PIN_1);
    //GPIOPinTypeTimer (GPIO_PORTF_BASE、GPIO_PIN_0);
    SysCtlPeripheralEnable (SYSCTL_Periph_TIMER0);//even:T0CCP0引脚:PF0或 PB6 || ODD:T0CCP1引脚:Pb7或 PF1
    /*使用 timer0进行 PWM 和上升沿计数*/
    TimerConfigure (TIMER0_BASE、TIMER_CFG_SPLIT_PAGE|TIMER_CFG_B_PWM|TIMER_CFG_B_CAP_COUNT_UP);
    TimerLoadSet (TIMER0_BASE、TIMER_B、周期-1);//周期-1、因为0计数。
    //TimerMatchSet (TIMER0_BASE、TIMER_B、dutyCycle);
    /* 上升沿 *
    TimerControlEvent (TIMER0_BASE、TIMER_B、TIMER_EVENT_POS_EDGE);//测量上升沿
    //TimerLoadSet (TIMER0_BASE、TIMER_A、周期- 1);
    TimerEnable (TIMER0_BASE、TIMER_B);
    //TimerEnable (TIMER0_BASE、TIMER_A);
    //中断
    //注册一个中断函数,当计时器 b 遇到位置边沿事件时调用该函数
    内部寄存器(INT_TIMER0B、上升中断);
    //确保清除中断
    TimerIntClear (TIMER0_BASE、TIMER_CAPB_EVENT);
    //启用指示的定时器中断源。
    TimerIntEnable (TIMER0_BASE、TIMER_CAPB_EVENT);
    //在中断控制器中启用指定的中断。
    IntEnable (INT_TIMER0B);
    }
    
    void MotorControl_one (void * pvParameters)
    {
    
    struct canMsgs canrec;
    uint32_t 周期= SysCtlClockGet ()/25000;// 25kHz PWM
    uint32_t dutyCycle =(周期/ 2);// 50%占空比
    initMotors();
    xQueueReceive(Queh,&canREC,0);
    
    while (1)
    {
    
    if (canREC.CANmsgRX.ui32MsgID = 1)
    {
    TimerEnable (TIMER0_BASE、TIMER_B);
    TimerMatchSet (TIMER0_BASE、TIMER_B、dutyCycle);//PWM
    PULSE_CONTRAIN[1].TICK = 0;
    PULSE_CONTRAIN[1].num_puls= canREC.CANmsgRX.pui8MsgData[1];
    
    
    }
    vTaskSuspend (MotorOne);
    }
    } 

    现在、我的问题是、是否有其他方法可以启用和禁用 PWM 信号?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用 user="Giancarlo Kuosmanen"]发送 CAN 消息中定义的脉冲数量的问题

    但是、它不能解决 CAN 消息本身的脆弱性问题。

    [引用 user="Giancarlo Kuosmanen"]现在我的问题是是否有其他方法可以启用和禁用 PWM 信号?

    为什么使用 PWM?

    Robert

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您可以整体忽略 CAN。 我们将 PWM 发送到步进电机的微步进驱动器、并尝试使用由上升沿触发的中断对脉冲进行计数。 但是、中断似乎也会在边沿之间触发、因为我们需要特定的延迟才能使其正常工作。 我们知道驱动器需要3200个脉冲/转速、因此我们非常赞赏有关如何计数脉冲/上升沿的提示。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用 user="Giancarlo Kuosmanen">您可以整体忽略 CAN。 [/报价]

    不、很抱歉、我不能。 基于 Δ 的协议要求解决问题。

    [引用 USER="Giancarlo Kuosmanen"]我们将 PWM 发送到步进电机的微步进驱动器[/引用]

    我知道你在用它做什么。 我想问为什么它必须是 PWM、而不是其他形式的脉冲发生器。

    [引用 user="Giancarlo Kuosmanen"]我们知道驱动器需要3200个脉冲/转速、因此非常感谢您提供有关如何计算脉冲/上升沿的提示。[/引用]

    我不明白为什么您需要对脉冲进行计数。 只需生成正确数量的脉冲。 添加计数步骤只会使您的任务变得更困难。

    Robert

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用 user="Robert Adsett">我知道您在使用它执行什么操作。 我想问为什么它必须是 PWM、而不是其他形式的脉冲发生器。

    对于任何其他形式的脉冲发生器、您的意思是什么?

    [引用 user="Robert Adsett">我不明白为什么需要对脉冲进行计数。 只需生成正确数量的脉冲。 添加计数步骤只会使您的任务变得更困难。

    您是否建议使用延迟输出高电平和低电平信号? 或其他哪种方法?  

    Giancarlo

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用用户="Giancarlo Kuosmanen"]

    Robert Adsett
    我知道你在用它做什么。 我想问为什么它必须是 PWM、而不是其他形式的脉冲发生器。

    [/报价]

    不、您有一个高度复杂的微控制器、其中包含少量计时器、有多种方法可以生成脉冲。 PWM 适用于提供粗略 D/A 或驱动功率器件、但使用它异步生成特定数量的脉冲是选择最难使用的方法之一。

    [引用用户="Giancarlo Kuosmanen"]

    Robert Adsett
    我不明白为什么您需要对脉冲进行计数。 只需生成正确数量的脉冲。 添加计数步骤只会使您的任务变得更困难。

    [/报价]

    让我们尝试最简单的伪代码

    void GeneratePulses (unsigned int n)
    {
    while (n>0){
    GeneratePulse ();
    N-;
    }
    } 

    它真的可以这么简单。 在您使其正常工作后、您可以进行优化。

    Robert

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用用户="Robert Adsett"]

    让我们尝试最简单的伪代码

    void GeneratePulses (unsigned int n)
    {
    while (n>0){
    GeneratePulse ();
    N-;
    }
    } 

    它真的可以这么简单。 在您使其正常工作后、您可以进行优化。

    [/报价]

    您是否可以提及可从 cortex 使用的功能? OPM (单脉冲模式)?   

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用 user="Giancarlo Kuosmanen">您是否可以提及可从 cortex 使用的功能? OPM (单脉冲模式)?   [/报价]

    GPIO

    计时器

    有两个。 您可以输出的脉冲链的速度可能会受到接收器件能力的限制、这种能力超过了微型器件的生成能力。 一旦您使其正常工作并且事实证明有必要、您就可以转到合并中断。

    Robert

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用用户="Robert Adsett"]

    GPIO

    计时器

    [/报价]

    我们使用计时器和 GPIO 来控制电机的角度。 但无论如何都要感谢、如果解释不是很好、会发生一些误解、很抱歉。