ZHCUBZ5A September   2021  – April 2024

 

  1.   1
  2.   摘要
  3.   商标
  4. 1引言
  5. 2电机控制理论
    1. 2.1 PMSM 的数学模型和 FOC 结构
    2. 2.2 PM 同步电机的磁场定向控制
    3. 2.3 PM 同步电机的无传感器控制
      1. 2.3.1 具有锁相环的增强型滑模观测器
        1. 2.3.1.1 PMSM 的 ESMO 设计
        2. 2.3.1.2 使用 PLL 的转子位置和转速估算
    4. 2.4 电机驱动器的硬件必要条件
      1. 2.4.1 电机相电压反馈
    5. 2.5 额外的控制特性
      1. 2.5.1 弱磁 (FW) 和每安培最大扭矩 (MTPA) 控制
      2. 2.5.2 快速启动
  6. 3在 TI 硬件套件上运行通用实验
    1. 3.1 受支持的 TI 电机评估套件
    2. 3.2 硬件电路板设置
      1. 3.2.1  LAUNCHXL-F280025C 设置
      2. 3.2.2  LAUNCHXL-F280039C 设置
      3. 3.2.3  LAUNCHXL-F2800137 设置
      4. 3.2.4  TMDSCNCD280025C 设置
      5. 3.2.5  TMDSCNCD280039C 设置
      6. 3.2.6  TMDSCNCD2800137 设置
      7. 3.2.7  TMDSADAP180TO100 设置
      8. 3.2.8  DRV8329AEVM 设置
      9. 3.2.9  BOOSTXL-DRV8323RH 设置
      10. 3.2.10 BOOSTXL-DRV8323RS 设置
      11. 3.2.11 DRV8353RS-EVM 设置
      12. 3.2.12 BOOSTXL-3PHGANINV 设置
      13. 3.2.13 DRV8316REVM 设置
      14. 3.2.14 TMDSHVMTRINSPIN 设置
      15.      34
      16.      35
    3. 3.3 实验软件实现
      1. 3.3.1 导入和配置工程
      2.      38
      3.      39
      4. 3.3.2 实验工程结构
      5. 3.3.3 实验软件概述
    4. 3.4 监控反馈或控制变量
      1. 3.4.1 使用 DATALOG 函数
      2. 3.4.2 使用 PWMDAC 函数
      3. 3.4.3 使用外部 DAC 板
    5. 3.5 使用不同的构建级别循序渐进地运行工程
      1. 3.5.1 级别 1 增量构建
        1. 3.5.1.1 构建和加载工程
        2. 3.5.1.2 设置调试环境窗口
        3. 3.5.1.3 运行代码
      2. 3.5.2 级别 2 增量构建
        1. 3.5.2.1 构建和加载工程
        2. 3.5.2.2 设置调试环境窗口
        3. 3.5.2.3 运行代码
      3. 3.5.3 级别 3 增量构建
        1. 3.5.3.1 构建和加载工程
        2. 3.5.3.2 设置调试环境窗口
        3. 3.5.3.3 运行代码
      4. 3.5.4 级别 4 增量构建
        1. 3.5.4.1 构建和加载工程
        2. 3.5.4.2 设置调试环境窗口
        3. 3.5.4.3 运行代码
  7. 4构建定制板
    1. 4.1 构建新的定制板
      1. 4.1.1 硬件设置
      2. 4.1.2 将参考代码迁移到定制电路板
        1. 4.1.2.1 设置硬件板参数
        2. 4.1.2.2 修改电机控制参数
        3. 4.1.2.3 更改引脚分配
        4. 4.1.2.4 配置 PWM 模块
        5. 4.1.2.5 配置 ADC 模块
        6. 4.1.2.6 配置 CMPSS 模块
        7. 4.1.2.7 配置故障保护函数
      3. 4.1.3 向电机控制工程中添加附加功能
        1. 4.1.3.1 添加按钮功能
        2. 4.1.3.2 添加电位器读取功能
        3. 4.1.3.3 添加 CAN 功能
    2. 4.2 支持新的 BLDC 电机驱动器板
    3. 4.3 将参考代码移植到新的 C2000 MCU
  8.   A 附录 A. 电机控制参数
  9.   参考资料
  10.   修订历史记录

添加 CAN 功能

可以将 CAN 功能添加到实验工程中,为用户提供用于发送启动/停止命令并获取运行状态反馈的通信总线。要利用此功能,请在工程构建属性中启用预定义符号 CMD_CAN_EN,如图 3-19 中所示。详细步骤如下所示。

  1. 将 CAN 源文件添加到工程中。右键点击 Project Explorer 窗口内的工程名称,并选择“Add Files”。接下来,导航到以下文件夹并选择“Link to Files”。

    <install_location>\c2000ware\driverlib\f28002x\driverlib\can.c

  2. 编辑 HAL_Obj 以在 hal_obj.h 头文件中添加 canHandle。
    typedef struct _HAL_Obj_ { uint32_t adcHandle[2]; //!< the ADC handles ... ... uint32_t canHandle; //!< the CAN handle ... ... } HAL_Obj;
  3. hal.c 文件中的 HAL_init() 函数中初始化 CAN 句柄。
    HAL_Handle HAL_init(void *pMemory,const size_t numBytes)
    {
    ... ...
        // initialize CAN handle
        obj->canHandle = CANA_BASE;             //!< the CAN handle
    ... ... 
        return(handle);
    } // end of HAL_init() function
  4. communication.h 文件中的 CAN 设置函数进行原型设计,如下代码所示。
    //! \brief     Sets up the CANA
    //! \param[in] handle  The hardware abstraction layer (HAL) handle
    extern void HAL_setupCANA(HAL_Handle handle);
  5. communication.c 文件中将 CAN 设置函数定义为以下代码。
    void HAL_setupCANA(HAL_Handle halHandle)
    {
        HAL_Obj *obj = (HAL_Obj *)halHandle;
    
        // Initialize the CAN controller
        CAN_initModule(obj->canHandle);
    
        // Set up the CAN bus bit rate to 200kHz
        // Refer to the Driver Library User Guide for information on how to set
        // tighter timing control. Additionally, consult the device data sheet
        // for more information about the CAN module clocking.
        CAN_setBitRate(obj->canHandle, DEVICE_SYSCLK_FREQ, 500000, 16);
    
        // Initialize the transmit message object used for sending CAN messages.
        // Message Object Parameters:
        //      Message Object ID Number: 1
        //      Message Identifier: 0x1
        //      Message Frame: Standard
        //      Message Type: Transmit
        //      Message ID Mask: 0x0
        //      Message Object Flags: Transmit Interrupt
        //      Message Data Length: 8 Bytes
        CAN_setupMessageObject(CANA_BASE, TX_MSG_OBJ_ID, 0x1, CAN_MSG_FRAME_STD,
                               CAN_MSG_OBJ_TYPE_TX, 0, CAN_MSG_OBJ_TX_INT_ENABLE,
                               MSG_DATA_LENGTH);
    
        // Initialize the receive message object used for receiving CAN messages.
        // Message Object Parameters:
        //      Message Object ID Number: 2
        //      Message Identifier: 0x1
        //      Message Frame: Standard
        //      Message Type: Receive
        //      Message ID Mask: 0x0
        //      Message Object Flags: Receive Interrupt
        //      Message Data Length: 8 Bytes
        CAN_setupMessageObject(obj->canHandle, RX_MSG_OBJ_ID, 0x1, CAN_MSG_FRAME_STD,
                               CAN_MSG_OBJ_TYPE_RX, 0, CAN_MSG_OBJ_RX_INT_ENABLE,
                               MSG_DATA_LENGTH);
    
        // Start CAN module operations
        CAN_startModule(obj->canHandle);
    
        return;
    }  // end of HAL_setupCANA() function
    注: 要根据系统需求初始化各种 CAN 模块参数,以上内容仅为简单参考。
  6. hal.c 文件的 HAL 设置时钟函数 HAL_setupPeripheralClks() 中启用相应的 CAN 外设时钟。
       SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_CANA);
  7. 将相关的 GPIO 配置为 hal.c 文件的 HAL_setupGpios() 函数中的 CAN 函数。
        // GPIO33->CAN_TX
        GPIO_setPinConfig(GPIO_32_CANA_TX);
        GPIO_setDirectionMode(32, GPIO_DIR_MODE_OUT);
        GPIO_setPadConfig(32, GPIO_PIN_TYPE_STD);
        GPIO_setQualificationMode(32, GPIO_QUAL_ASYNC);
    
        // GPIO33->CAN_RX
        GPIO_setPinConfig(GPIO_33_CANA_RX);
        GPIO_setDirectionMode(33, GPIO_DIR_MODE_IN);
        GPIO_setPadConfig(33, GPIO_PIN_TYPE_STD);
        GPIO_setQualificationMode(33, GPIO_QUAL_ASYNC);
  8. communication.h 文件中的 CAN 中断设置函数进行原型设计。
    extern void HAL_enableCANInts(HAL_Handle handle);
  9. 定义 CAN 中断设置函数。
    void HAL_enableCANInts(HAL_Handle handle)
    {
        HAL_Obj *obj = (HAL_Obj *)handle;
    
        // Enable CAN test mode with external loopback
    //     CAN_enableTestMode(CANA_BASE, CAN_TEST_EXL);    // Only for debug
    
        // Enable interrupts on the CAN peripheral.
        CAN_enableInterrupt(obj->canHandle, CAN_INT_IE0 | CAN_INT_ERROR |
                            CAN_INT_STATUS);
    
    
        // enable the PIE interrupts associated with the CAN interrupts
        Interrupt_enable(INT_CANA0);
    
    
        CAN_enableGlobalInterrupt(obj->canHandle, CAN_GLOBAL_INT_CANINT0);
    
        // enable the cpu interrupt for CAN interrupts
        Interrupt_enableInCPU(INTERRUPT_CPU_INT9);
    
        return;
    } // end of HAL_enableCANInts() function
  10. 调用 sys_main.c 文件中的 CAN 设置函数和 CAN 中断设置函数。
        // setup the CAN
        HAL_setupCANA(halHandle);
        // setup the CAN interrupt
        HAL_enableCANInts(halHandle);
  11. communication.h 文件中的 CAN 中断服务 (ISR) 例程进行原型设计。
    extern __interrupt void canaISR(void);
  12. 将 CAN 中断服务 (ISR) 例程矢量添加到 communication.c 文件中 initCANCOM() 内的 PIE 表中。
        Interrupt_register(INT_CANA0, &canaISR);
  13. 为了通过在 communication.c 文件中添加以下代码来加快执行速度,将 CAN ISR 代码放置在闪存中并从 RAM 运行。
    #pragma CODE_SECTION(canaISR, ".TI.ramfunc");
  14. communication.c 文件中定义 CAN 中断例程 canaISR()。定义经过原型设计并传递到 PIE 向量表的 canaIS() 函数。下面的示例代码提供了一个使用 CAN 接收/发送消息数据的函数,并清除 PIE 中的中断,从而允许再次触发 CAN 中断。
    __interrupt void canaISR(void) { ... ... // Check if the cause is the transmit message object 1 // Check if the cause is the transmit message object 1 else if(status == TX_MSG_OBJ_ID) { // // Getting to this point means that the TX interrupt occurred on // message object 1, and the message TX is complete. Clear the // message object interrupt. // CAN_clearInterruptStatus(CANA_BASE, TX_MSG_OBJ_ID); // Increment a counter to keep track of how many messages have been // sent. In a real application this could be used to set flags to // indicate when a message is sent. canComVars.txMsgCount++; // Since the message was sent, clear any error flags. canComVars.errorFlag = 0; } // Check if the cause is the receive message object 2 else if(status == RX_MSG_OBJ_ID) { // // Get the received message // CAN_readMessage(halHandle->canHandle, RX_MSG_OBJ_ID, (uint16_t *)(&canComVars.rxMsgData[0])); // Getting to this point means that the RX interrupt occurred on // message object 2, and the message RX is complete. Clear the // message object interrupt. CAN_clearInterruptStatus(halHandle->canHandle, RX_MSG_OBJ_ID); canComVars.rxMsgCount++; canComVars.flagRxDone = true; // Since the message was received, clear any error flags. canComVars. errorFlag = 0; } ... ... // Clear the global interrupt flag for the CAN interrupt line CAN_clearGlobalInterruptStatus(halHandle->canHandle, CAN_GLOBAL_INT_CANINT0); // Acknowledge this interrupt located in group 9 Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9); return; }
  15. communication.h 文件和 communication.c 文件中分别定义 updateCANCmdFreq(),并对其进行原型设计。对 CAN 总线接收和发送的数据进行处理并链接到 updateCANCmdFreq() 中的电机控制变量。
    void updateCANCmdFreq(MOTOR_Handle handle)
    {
    ...
    }
  16. 在无限循环中调用 updateCANCmdFreq()。
    updateCANCmdFreq(motorHandle_M1);
    
    if((motorVars_M1.cmdCAN.flagEnablCmd == true) && (motorVars_M1.faultMtrUse.all == 0))
    {
    	canComVars.flagCmdTxRun = motorVars_M1.cmdCAN.flagCmdRun;
    	canComVars.speedSet_Hz = motorVars_M1.cmdCAN.speedSet_Hz;
    
    	if(motorVars_M1.cmdCAN.flagEnablSyncLead == true)
    	{
    		motorVars_M1.flagEnableRunAndIdentify = motorVars_M1.cmdCAN.flagCmdRun;
    		motorVars_M1.speedRef_Hz = motorVars_M1.cmdCAN.speedSet_Hz;
    	}
    	else
    	{
    		motorVars_M1.flagEnableRunAndIdentify = canComVars.flagCmdRxRun;
    		motorVars_M1.speedRef_Hz = canComVars.speedRef_Hz;
    	}
    }