步进电机控制库概述

1. 软件概述

步进电机控制库包含三个主要层,分别是应用层、模块层和 MSPM0 DriverLib。

步进库架构

Fig. 1 步进库架构

1.1 应用层概述

用户特定的应用程序(例如 GUI 等)位于该层中。 在这一层,可以配置和使用电机驱动器模块的各种实例。如果用户需要执行任何硬件特定的操作,建议用户使用 HAL 模块中的 API。

1.2 HAL 模块

概述

HAL(即硬件抽象层)会创建一个抽象层,它提供 用来配置不同引脚和外设的 API。使用 HAL 的目标是抽象处理所有器件特定的配置,从而通过最大程度地减少其他元件所需的更新来简化库到各种硬件的移植。HAL 旨在仅抽象处理应用所需的引脚或外设,这样做是为了使其轻量化,同时仍然具有移植灵活性。

HAL 旨在将特定数量的引脚或通道与外设关联。为便于理解,我们以 GPIO 为例。HAL 具有枚举 HAL_GPIO_OUT_PIN,其中将所有 GPIO 输出引脚包含为成员,如下所示。

/*! @enum HAL_GPIO_OUT_PIN */
typedef enum{
    /*! Index associated to output GPIO PIN 0 */
    HAL_GPIO_OUT_PIN_0 = 0,
    /*! Index associated to output GPIO PIN 1 */
    HAL_GPIO_OUT_PIN_1,
    /*! Index associated to output GPIO PIN 2 */
    HAL_GPIO_OUT_PIN_2,
    /*! Index associated to output GPIO PIN 3 */
    HAL_GPIO_OUT_PIN_3,
    /*! Index associated to output GPIO PIN 4 */
    HAL_GPIO_OUT_PIN_4,
    /*! Index associated to output GPIO PIN 5 */
    HAL_GPIO_OUT_PIN_5,
    /*! Index associated to output GPIO PIN 6 */
    HAL_GPIO_OUT_PIN_6,
    /*! Index associated to output GPIO PIN 7 */
    HAL_GPIO_OUT_PIN_7,
    /*! Index associated to output GPIO PIN 8 */
    HAL_GPIO_OUT_PIN_8,
    /*! Index associated to output GPIO PIN 9 */
    HAL_GPIO_OUT_PIN_9,
    /*! Total number of output GPIO pins */
    HAL_GPIO_OUT_PIN_MAX,
}HAL_GPIO_OUT_PIN;

为了将 HAL GPIO 引脚映射到真实的硬件引脚,我们使用一个由 HAL_GPIO_OUT_PIN 枚举成员进行索引的结构,该结构存储各种成员,如端口、引脚名称等。请参见下面的 gpioOUT 结构,该结构会保存有关端口和引脚的数据。

gpioOUT[HAL_GPIO_OUT_PIN_0].iomux   = GENERIC_GPIO_OUT_PINO_0_IOMUX;
gpioOUT[HAL_GPIO_OUT_PIN_0].port    = GENERIC_GPIO_OUT_PORT;
gpioOUT[HAL_GPIO_OUT_PIN_0].pin     = GENERIC_GPIO_OUT_PINO_0_PIN;

请注意,GENERIC_GPIO_OUT_PINO_0_PIN 在 TI Sysconfig 生成的文件中定义,具体行如下所示:

#define GENERIC_GPIO_OUT_PINO_0_PIN                              (DL_GPIO_PIN_0)

因此,HAL_GPIO_OUT_PIN_0 间接引用 DL_GPIO_PIN_0,但这种映射的优点是:由于 TI Sysconfig 控制 GENERIC_GPIO_OUT_PINO_0_PIN 的生成,因此很容易在 TI Sysconfig GUI 中更改引脚,并且 HAL 会自动遵循此更改,而无需用户更改 HAL 层中的任何代码。

如上所示,当通过 HAL 访问硬件时,我们需要传递 HAL 特定枚举,如 HAL_GPIO_OUT_PIN_0。这些枚举存储在访问 HAL 层的实例中,就电机驱动器 drv8889q1 而言,我们使用分配到 HAL 枚举的引脚来初始化实例,如下面的代码片段所示。

drv8889q1.dir               = HAL_GPIO_OUT_PIN_0;
drv8889q1.drvOff            = HAL_GPIO_OUT_PIN_1;
drv8889q1.nsleep            = HAL_GPIO_OUT_PIN_2;
drv8889q1.nfault            = HAL_GPIO_IN_PIN_0;
drv8889q1.vref              = HAL_DAC_CHANNEL_0;
drv8889q1.step              = HAL_PWM_CHANNEL_0;
drv8889q1.spi               = HAL_SPI_CHANNEL_0;
drv8889q1.spiCS             = HAL_SPI_CS_2;

现在,如果我们需要将 nSLEEP 引脚设置为高电平,可以使用 API DRV8889Q1_setNSleep() 并通过其传递此 drv8889q1 实例,代码片段如下所示:

void DRV8889Q1_setNSleep(DRV8889Q1_Instance *handle)
{
    HAL_setGPIOVal(handle->nsleep, HAL_GPIO_VALUE_HIGH);
    /* Startup delay for the DRV8889Q1 SPI to be ready */
    HAL_delayMilliSeconds(DRV8889Q1_SPI_READY_DELAY_MS);
}

当 DRV8889Q1_setNSleep() 与 HAL 层交互时,它会传递 drv8889q1 实例的成员,具体示例如上面的代码片段所示。在该代码片段中,drv8889q1 实例的 nsleep 成员被传递到 HAL 层,这与使用其他 HAL API(例如计时器、SPI、DAC 等)的概念相同。用户可随意扩展 HAL 的 API 以支持微控制器的其他外设和特性,但为确保能轻松迁移到该库的新版本,强烈建议不要修改现有 API。

1.3 电机驱动器模块

电机驱动器模块将所有电机驱动任务抽象为简单的 API,如启动电机、停止电机、设置速度等。该层的理念是独立于硬件并使用 HAL API 来执行硬件任务。

电机驱动器引脚关联

在使用电机驱动器模块之前,用户需要指定映射到电机驱动器实例的 HAL 枚举,请参阅下面的代码片段。

/* Assign the pins specific for the DRV */
drv8411a.ain1               = HAL_GPIO_OUT_PIN_0;
drv8411a.ain2               = HAL_GPIO_OUT_PIN_1;
drv8411a.bin1               = HAL_GPIO_OUT_PIN_2;
drv8411a.bin2               = HAL_GPIO_OUT_PIN_3;
drv8411a.nfault             = HAL_GPIO_IN_PIN_0;
drv8411a.aipropi            = HAL_ADC_CHANNEL_0;
drv8411a.bipropi            = HAL_ADC_CHANNEL_1;
drv8411a.vref               = HAL_DAC_CHANNEL_0;
drv8411a.indexerTimer       = HAL_TIM_CHANNEL_0;
drv8411a.ADCTriggerTimer    = HAL_TIM_CHANNEL_1;

电机驱动器 API

电机驱动器模块提供简单的 API,用户可以将其与电机驱动器模块的实例一同使用。

电机驱动器层 API 还处理电机驱动器特定逻辑,同时保持 API 通用,因此用户可以使用不同的电机驱动器,而不必担心内部逻辑有任何差异。例如,下面是处理 H 桥驱动状态的 DRV8411A_setPWMDrive API 的一部分。

__STATIC_INLINE void DRV8411A_setPWMDrive(
                                HAL_GPIO_OUT_PIN in1, HAL_GPIO_OUT_PIN in2,
                                STEPPER_DRIVE drive, DRV8411A_DECAY decayMode)
{
    HAL_GPIO_VALUE in1GpioVal  = HAL_GPIO_VALUE_LOW;
    HAL_GPIO_VALUE in2GpioVal  = HAL_GPIO_VALUE_LOW;
    switch (drive)
    {
        case STEPPER_DRIVE_DISABLE:
            in1GpioVal = HAL_GPIO_VALUE_LOW;
            in2GpioVal = HAL_GPIO_VALUE_LOW;
            break;
        case STEPPER_DRIVE_DECAY:
            if(decayMode == DRV8411A_DECAY_SLOW)
            {
                in1GpioVal = HAL_GPIO_VALUE_HIGH;
                in2GpioVal = HAL_GPIO_VALUE_HIGH;
            }
            else
            {
                in1GpioVal = HAL_GPIO_VALUE_LOW;
                in2GpioVal = HAL_GPIO_VALUE_LOW;
            }

请注意,在上面的代码片段中,在 GPIO 中设置控制输出以设置驱动状态的任务对于每个驱动器模块来说可能有所不同,但是,由于我们使用由电机驱动器模块处理的通用驱动状态来基于其内部逻辑设置正确的输出状态,因此步进库能够用于多个电机驱动器模块。

1.4 步进库模块

概述

步进库包含用于步进电机控制的通用算法。当使用多个电机驱动器模块时,该层有助于减小代码大小。

该层由电机驱动器模块使用,用户不应直接使用该层的 API。可通过电机驱动器层与相应实例一同访问步进库,该层会配置通用算法并使用步进库 API。

void DRV8411A_setStepMode(DRV8411A_Instance *handle, DRV8411A_STEP stepMode)
{
    if(stepMode == DRV8411A_STEP_FULL_STEP)
    {
        handle->stepMode = stepMode;
        STEPPER_setIndexerIncVal(&handle->indexer, STEPPER_STEP_INC_DEC_FULL_STEP);
        DRV8411A_setSpeed(handle, handle->setFreq);
    }
    if(stepMode == DRV8411A_STEP_HALF_STEP_NC)
    {
        handle->stepMode = stepMode;
        STEPPER_setIndexerIncVal(&handle->indexer, STEPPER_STEP_INC_DEC_HALF_STEP);
        DRV8411A_setSpeed(handle, handle->setFreq);
        STEPPER_setStepType(&handle->indexer, STEPPER_STEP_TYPE_NONCIR);
    }
    else
    {
        STEPPER_setStepType(&handle->indexer, STEPPER_STEP_TYPE_CIR);
    }
}

在上面的代码中,DRV8411A 仅会将分度器递增或递减值设置为 STEPPER_STEP_INC_DEC_FULL_STEP 或 STEPPER_STEP_INC_DEC_HALF_STEP。但是,还有更多值需要设置,但由于 DRV8411A 不支持这些模式,因此不会使用它们。

此外,步进库并不了解使用其 API 的电机驱动器模块的驱动器接口,即是 PWM 还是相位使能接口。步进库会生成通用驱动状态,电机驱动器模块根据 PWM 或相位使能逻辑将其转换为控制输出,这一点也在“电机驱动器 API”部分中进行了讨论。

1.5 MSPM0 DriverLib 概述

MSPM0 DriverLib 是一组功能齐全的 API,用于配置、控制和操作 MSPM0 平台的硬件外设。更多相关信息,请参阅 DriverLib 文档。

2. API 指南

3. 已知问题

1.在离线应用程序中,GUI 图有时不起作用。 2.离线应用程序中会出现程序加载失败的问题。 3.目前仅支持 CCS IDE。

4. 支持的器件

DRV8411A

支持的 MSPM0 LaunchPad

链接

DRV8889-Q1

支持的 MSPM0 LaunchPad

链接