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.

[参考译文] MSP432E401Y:缩短线程的睡眠时间

Guru**** 2540720 points
Other Parts Discussed in Thread: MSP-EXP432E401Y, MSP432E401Y

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1010640/msp432e401y-reduce-sleep-time-for-thread

器件型号:MSP432E401Y
主题中讨论的其他器件:MSP-EXP432E401Y

大家好、社区

我正在使用  MSP-EXP432E401Y (TI-RTOS)。  我正在开发一个脚本来识别系统。 该系统包含一个直流电机(带 H 桥)和一个编码器。 对于系统识别、我设置 PWM 并通过编码器 API 测量当前位置和速度。

该程序由两个线程组成。 第一个线程执行驱动例程、使直流电机驱动定义的系统配置。 第二个线程读取当前测量的变量(PWM、位置和速度)并将其写入向量。 这在程序结束时通过控制台输出。

基本程序运行良好。 但是、在小于100毫秒的时间间隔内无法查询测量变量。
然而、10ms 的采样对于系统识别是必不可少的。

如果我选择小于100ms 的周期时间、则转换驱动系统配置的线程不会经常被调用、并且驱动系统配置不再与所需的系统配置相对应。

是否可以在10ms 的周期内调用第二个线程? 还是 MSP432E401Y 无法实现? 因为它的计算量太大或相似?

(此问题 e2e.ti.com/.../msp432e401y-maximum-adc-sample-frequency 表明原则上是可能的、问题是、为什么它会导致我遇到这些问题)。

在以下相关代码中:

void generateSysIdentificationVec()
{
    u[iter] = (GPIO_read(CONFIG_GPIO_L298N_IN2)-GPIO_read(CONFIG_GPIO_L298N_IN1))*duty*120;
    y1[iter] = QEIPositionGet(QEI0_BASE);
    y2[iter] = (long)(QEIDirectionGet(QEI0_BASE)*QEIVelocityGet(QEI0_BASE));
    iter = iter +1;
}

/*
 *  ======== sysIdentificationThread ========
 */
void *systemIdentificationThread(void *arg0)
{
    ...

    /* System Identification */
    do
    {
        generateSysIdentificationVec();
        // 100ms - best possible
        usleep(100000);
    }
    while (sysIdentificationRoutineRunning);
    
    ...

    return 0;
}

/*
 *  ======== stopMotor ========
 *  Stop Motor
 */
void stopMotor()
{
    /* Spinning Direction Forward
     *
     * Input1: High(1)
     * Input2: High(1)
    */

    /* Set L298N Input1 */
    GPIO_write(CONFIG_GPIO_LED_1, CONFIG_GPIO_LED_ON);
    GPIO_write(CONFIG_GPIO_L298N_IN1, 1);

    /* Set L298N Input2 */
    GPIO_write(CONFIG_GPIO_LED_2, CONFIG_GPIO_LED_ON);
    GPIO_write(CONFIG_GPIO_L298N_IN2, 1);
}

/*
 *  ======== setSpinningDirectionForward ========
 *  Set motor direction: Forward
 */
void setSpinningDirectionForward()
{
    /* Spinning Direction Forward
     *
     * Input1: Low(0)
     * Input2: High(1)
    */

    /* Set L298N Input1 */
    GPIO_write(CONFIG_GPIO_LED_1, CONFIG_GPIO_LED_OFF);
    GPIO_write(CONFIG_GPIO_L298N_IN1, 0);

    /* Set L298N Input2 */
    GPIO_write(CONFIG_GPIO_LED_2, CONFIG_GPIO_LED_ON);
    GPIO_write(CONFIG_GPIO_L298N_IN2, 1);
}

/*
 *  ======== setSpinningDirectionBackward ========
 *  Set motor direction: Backward
 */
void setSpinningDirectionBackward()
{
    /* Spinning Direction Backward
     *
     * Input1: High(1)
     * Input2: Low(0)
    */

    /* Set L298N Input1 */
    GPIO_write(CONFIG_GPIO_LED_1, CONFIG_GPIO_LED_ON);
    GPIO_write(CONFIG_GPIO_L298N_IN1, 1);

    /* Set L298N Input2 */
    GPIO_write(CONFIG_GPIO_LED_2, CONFIG_GPIO_LED_OFF);
    GPIO_write(CONFIG_GPIO_L298N_IN2, 0);
}

/*
 *  Drive Test route
 */
void driveRoutine()
{
    sysIdentificationRoutineRunning = true;
    usleep(100000);

    Display_printf(display, 1, 0, "Backward");
    duty = 70;
    PWM_setDuty(pwm, ((uint32_t) (((uint64_t) PWM_DUTY_FRACTION_MAX * 70) / 100)));
    setSpinningDirectionBackward();
    //usleep(400000);
    ThreadAPI_Sleep(400);
    stopMotor();

    Display_printf(display, 1, 0, "Forward");
    duty = 100;
    PWM_setDuty(pwm, ((uint32_t) (((uint64_t) PWM_DUTY_FRACTION_MAX * 100) / 100)));
    setSpinningDirectionForward();
    //usleep(600000);
    ThreadAPI_Sleep(600);
    stopMotor();

    Display_printf(display, 1, 0, "Backward");
    duty = 90;
    PWM_setDuty(pwm, ((uint32_t) (((uint64_t) PWM_DUTY_FRACTION_MAX * 90) / 100)));
    setSpinningDirectionBackward();
    //usleep(300000);
    ThreadAPI_Sleep(300);
    stopMotor();

    Display_printf(display, 1, 0, "Forward");
    duty = 75;
    PWM_setDuty(pwm, ((uint32_t) (((uint64_t) PWM_DUTY_FRACTION_MAX * 75) / 100)));
    setSpinningDirectionForward();
    //usleep(500000);
    ThreadAPI_Sleep(500);
    stopMotor();

    Display_printf(display, 1, 0, "Backward");
    duty = 40;
    PWM_setDuty(pwm, ((uint32_t) (((uint64_t) PWM_DUTY_FRACTION_MAX * 40) / 100)));
    setSpinningDirectionBackward();
    //usleep(700000);
    ThreadAPI_Sleep(700);
    stopMotor();

    Display_printf(display, 1, 0, "Forward");
    duty = 40;
    PWM_setDuty(pwm, ((uint32_t) (((uint64_t) PWM_DUTY_FRACTION_MAX * 40) / 100)));
    setSpinningDirectionForward();
    //usleep(700000);
    ThreadAPI_Sleep(700);
    stopMotor();

    Display_printf(display, 1, 0, "Stop");
    //usleep(500000);
    ThreadAPI_Sleep(500);

    Display_printf(display, 1, 0, "Backward");
    duty = 100;
    PWM_setDuty(pwm, ((uint32_t) (((uint64_t) PWM_DUTY_FRACTION_MAX * 100) / 100)));
    setSpinningDirectionBackward();
    //usleep(800000);
    ThreadAPI_Sleep(800);
    stopMotor();

    Display_printf(display, 1, 0, "Forward");
    duty = 20;
    PWM_setDuty(pwm, ((uint32_t) (((uint64_t) PWM_DUTY_FRACTION_MAX * 20) / 100)));
    setSpinningDirectionForward();
    //usleep(300000);
    ThreadAPI_Sleep(300);
    duty = 30;
    PWM_setDuty(pwm, ((uint32_t) (((uint64_t) PWM_DUTY_FRACTION_MAX * 30) / 100)));
    //usleep(300000);
    ThreadAPI_Sleep(300);
    duty = 40;
    PWM_setDuty(pwm, ((uint32_t) (((uint64_t) PWM_DUTY_FRACTION_MAX * 40) / 100)));
    //usleep(300000);
    ThreadAPI_Sleep(300);
    duty = 50;
    PWM_setDuty(pwm, ((uint32_t) (((uint64_t) PWM_DUTY_FRACTION_MAX * 50) / 100)));
    //usleep(300000);
    ThreadAPI_Sleep(300);
    duty = 60;
    PWM_setDuty(pwm, ((uint32_t) (((uint64_t) PWM_DUTY_FRACTION_MAX * 60) / 100)));
    //usleep(300000);
    ThreadAPI_Sleep(300);
    duty = 70;
    PWM_setDuty(pwm, ((uint32_t) (((uint64_t) PWM_DUTY_FRACTION_MAX * 70) / 100)));
    //usleep(300000);
    ThreadAPI_Sleep(300);
    stopMotor();

    Display_printf(display, 1, 0, "Backward");
    duty = 40;
    PWM_setDuty(pwm, ((uint32_t) (((uint64_t) PWM_DUTY_FRACTION_MAX * 40) / 100)));
    setSpinningDirectionBackward();
    //sleep(2);
    ThreadAPI_Sleep(2000);
    stopMotor();

    sysIdentificationRoutineRunning = false;
}

/*
 *  ======== sysIdentificationThread ========
 */
void *driveProfileThread(void *arg0)
{
    ...
    
    /* Drive Profile */
    driveRoutine();
    
    ...

    return 0;
}

我希望社会可以帮助我。

此致
Patrick

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

    尊敬的 Patrick:

    您似乎在尝试使用轮询而不是中断来同步代码中的线程。 借助 TI-RTOS、调度程序应能够对各种线程进行优先级排序、无论这些线程是任务还是中断。 您可以在 CCS 中使用系统分析器来查看各种线程的执行时间和空闲时间。

    此外、我不确定您上面链接的 ADC 线程与您在这里尝试执行的操作之间的关系。 该线程主要讨论交错两个独立的 ADC 模块、以使有效 ADC 采样率加倍。 每个 ADC 模块的实际最大采样率不变。

    无论如何,我希望社会上的其他人也能为你提供帮助。