基于DSP280049C的正点原子PMSM电机驱动(四):EQEP配置与SPI主机配置

序言

在前面的文章中,我们已经能够通过开环的方式启动电机了,但是FOC开环控制中的电角度给定部分是用自增的方式所给定的,接下来则是通过加入编码器的方式取得电机的电角度位置,并在FOC开环程序中用该电角度值替代自增部分。
本文将分为两部分:EQEP的配置以及SPI的配置,并在文末会两项功能进行测试。

1.1-EQEP.h配置

/*
 * QEP.h
 *
 *  Created on: 2023年4月2日
 *      Author: 24460
 */

#ifndef USER_INC_QEP_H_
#define USER_INC_QEP_H_

void QEP_int(void);



#endif /* USER_INC_QEP_H_ */

1.2-EQEP.c配置

/*
 * QEP.c
 *
 *  Created on: 2023年4月2日
 *      Author: 24460
 */

#include "F28x_Project.h"
#include "user.h"
#include "QEP.h"

/*-----------------------<QEP相关函数>-------------------------------------------------------------------------*/
void QEP_int(void)
{
    SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EQEP1);

    //Configure the decoder for quadrature count mode
    EQEP_setDecoderConfig(EQEP1_BASE, (EQEP_CONFIG_1X_RESOLUTION |EQEP_CONFIG_QUADRATURE |EQEP_CONFIG_NO_SWAP));//(上下沿都收集|正交计数1模式|)
    EQEP_setEmulationMode(EQEP1_BASE, EQEP_EMULATIONMODE_RUNFREE);

    // Configure the position counter to reset on an index event
    EQEP_setPositionCounterConfig(EQEP1_BASE, EQEP_POSITION_RESET_IDX,3999);//IDX索引后重置计数

    // Enable the unit timer, setting the frequency to 100 Hz
    EQEP_enableUnitTimer(EQEP1_BASE, (DEVICE_SYSCLK_FREQ / 100));//Unit Timer 溢出频率100HZ

    // Configure the position counter to be latched on a unit time out
    EQEP_setLatchMode(EQEP1_BASE, EQEP_LATCH_UNIT_TIME_OUT);

    // Enable the eQEP1 module
    EQEP_disableModule(EQEP1_BASE);

    // Configure and enable the edge-capture unit. The capture clock divider is
    // SYSCLKOUT/128. The unit-position event divider is QCLK/8.
    EQEP_setCaptureConfig(EQEP1_BASE, EQEP_CAPTURE_CLK_DIV_64,EQEP_UNIT_POS_EVNT_DIV_32);
    EQEP_enableCapture(EQEP1_BASE);

    //GPIO配置
    EALLOW;
    GPIO_setPinConfig(DEVICE_GPIO_CFG_EQEP1A);
    GPIO_setPadConfig(DEVICE_GPIO_PIN_EQEP1A, GPIO_PIN_TYPE_STD);
    GPIO_setPinConfig(DEVICE_GPIO_CFG_EQEP1B);
    GPIO_setPadConfig(DEVICE_GPIO_PIN_EQEP1B, GPIO_PIN_TYPE_STD);
    GPIO_setPinConfig(DEVICE_GPIO_CFG_EQEP1I);
    GPIO_setPadConfig(DEVICE_GPIO_PIN_EQEP1I, GPIO_PIN_TYPE_STD);
    EDIS;


    EQEP_setPosition(EQEP1_BASE, 0);
    EQEP_enableModule(EQEP1_BASE);
    DELAY_US(10000L);

}

/*
void QEP_int(void)
{
    EQep1Regs.QUPRD =200000;
    EQep1Regs.QDECCTL.bit.QSRC =00;
    EQep1Regs.QEPCTL.bit.FREE_SOFT =2;
    EQep1Regs.QEPCTL.bit.PCRM =00;
    EQep1Regs.QEPCTL.bit.UTE =1;
    EQep1Regs.QEPCTL.bit.QCLM =1;
    EQep1Regs.QEPCTL.bit.QPEN =1;
    EQep1Regs.QCAPCTL.bit.UPPS =5;
    EQep1Regs.QCAPCTL.bit.CCPS =7;
    EQep1Regs.QCAPCTL.bit.CEN =1;
    EQep1Regs.QPOSMAX =4000;
    EQep1Regs.QEPCTL.bit.SWI =1;
    EALLOW;
    GPIO_setPinConfig(DEVICE_GPIO_CFG_EQEP1A);
    GPIO_setPadConfig(DEVICE_GPIO_PIN_EQEP1A, GPIO_PIN_TYPE_STD);
    GPIO_setPinConfig(DEVICE_GPIO_CFG_EQEP1B);
    GPIO_setPadConfig(DEVICE_GPIO_PIN_EQEP1B, GPIO_PIN_TYPE_STD);
    GPIO_setPinConfig(DEVICE_GPIO_CFG_EQEP1I);
    GPIO_setPadConfig(DEVICE_GPIO_PIN_EQEP1I, GPIO_PIN_TYPE_STD);
    EDIS;
}
*/
/*-----------------------<QEP相关函数>-------------------------------------------------------------------------*/

在EQEP的引脚配置中,选取了:

  • #2引脚(GPIO28)作为EQEP_A
  • #29引脚(GPIO13)作为EQEP_Z
  • #31引脚(GPIO11)作为EQEP_B
    其中引脚配置要打开device.h,找到EQEP相关的定义修改成如下
//
// eQEP
//
#define DEVICE_GPIO_PIN_EQEP1A      28U  // GPIO number for EQEP 1A IO2
#define DEVICE_GPIO_PIN_EQEP1B      11U  // GPIO number for EQEP 1B IO31
#define DEVICE_GPIO_PIN_EQEP1I      13U  // GPIO number for EQEP 1I IO29
#define DEVICE_GPIO_CFG_EQEP1A      GPIO_28_EQEP1A  // "pinConfig" for EQEP 1A
#define DEVICE_GPIO_CFG_EQEP1B      GPIO_11_EQEP1B  // "pinConfig" for EQEP 1B
#define DEVICE_GPIO_CFG_EQEP1I      GPIO_13_EQEP1I  // "pinConfig" for EQEP 1I

1.3-编码器的数值读取测试(取电机逆时针旋转为正方向增计数)

如此配置main函数进行编码器测试即可:



/**
 * main.c
 */

#include "F28x_Project.h"
#include "IQmathLib.h"
#include "FOC.h"
#include "PWM.h"
#include "QEP.h"

/*全局变量区*/
uint16_t now_position;

int main(void)
{
    InitSysCtrl();
    DINT;
    InitPieCtrl();
    IER=0x0000;
    IFR=0x0000;
    InitPieVectTable();
    DELAY_US(1000L);

    QEP_int();
    //EPWM1_int();
    EINT;                                       //使能全局中断
    ERTM;
    while (1)
    {
        now_position = EQEP_getPosition(EQEP1_BASE);
        DELAY_US(20000L);
    }
}

然后点击CCS左上角功能栏中的小甲壳虫(debug)按钮进入调试状态,用手逆时针转动电机,观看参数观察窗口中的now_position 数值变化。

2.1-userSPI.h配置

SPI的头文件配置中呢,主要是申明了三个函数,其一是SPI的初始化函数,其二是发送两个16位的数据发送函数,其三是具体的发送数据函数。

/*
 * userSPI.h
 *
 *  Created on: 2023年4月29日
 *      Author: 24460
 */

#ifndef USER_INC_USERSPI_H_
#define USER_INC_USERSPI_H_

void SPIA_int (void);

uint16_t  SPIA_sendtwo(uint16_t txdata1,uint16_t txdata2);
void SPISendData(uint8_t *data, unsigned int len);

#endif /* USER_INC_USERSPI_H_ */

2.2-userSPI.c配置

2.21 初始化函数

void SPIA_int (void)
{
    //GPIO配置
    // SPISOMI.
    //
    GPIO_SetupPinMux(17, GPIO_MUX_CPU1, 1);
    GPIO_SetupPinOptions(17, GPIO_PULLUP, GPIO_ASYNC);
    //
    // SPISIMO clock pin.
    //
    GPIO_SetupPinMux(16, GPIO_MUX_CPU1, 1);
    GPIO_SetupPinOptions(16, GPIO_PULLUP, GPIO_ASYNC);
    //
    // SPICLK.
    //
    GPIO_SetupPinMux(9, GPIO_MUX_CPU1, 7);
    GPIO_SetupPinOptions(9, GPIO_PULLUP, GPIO_ASYNC);
    //
    // SPICS.
    //
    GPIO_SetupPinMux(33, GPIO_MUX_CPU1, 0);
    GPIO_SetupPinOptions(33, GPIO_OUTPUT, GPIO_ASYNC);
    GPIO_WritePin(33, 1);
    //SPI配置
    // Set reset low before configuration changes
    // Clock polarity (0 == rising, 1 == falling)
    // 16-bit character
    // Enable loop-back
    //
    SpiaRegs.SPICCR.bit.SPISWRESET = 0;
    SpiaRegs.SPICCR.bit.CLKPOLARITY = 0;
    SpiaRegs.SPICCR.bit.SPICHAR = (8 - 1);
    SpiaRegs.SPICCR.bit.SPILBK = 0;

    //
    // Enable master (0 == slave, 1 == master)
    // Enable transmission (Talk)
    // Clock phase (0 == normal, 1 == delayed)
    // SPI interrupts are disabled
    //
    SpiaRegs.SPICTL.bit.MASTER_SLAVE = 1;
    SpiaRegs.SPICTL.bit.TALK = 1;
    SpiaRegs.SPICTL.bit.CLK_PHASE = 0;
    SpiaRegs.SPICTL.bit.SPIINTENA = 0;

    //
    // Set the baud rate using a 2 MHz SPICLK
    // BRR = (LSPCLK / SPICLK) - 1
    //
    SpiaRegs.SPIBRR.bit.SPI_BIT_RATE = ((25000000 / 1000000) - 1);

    //
    // Set FREE bit
    // Halting on a breakpoint will not halt the SPI
    //
    SpiaRegs.SPIPRI.bit.FREE = 1;

    //
    // Release the SPI from reset
    //
    SpiaRegs.SPICCR.bit.SPISWRESET = 1;

}

在SPI的引脚配置中,选取了:

  • #62引脚(GPIO9)作为SPI_CLK
  • #34引脚(GPIO17)作为SPI_SOMI
  • #33引脚(GPIO16)作为SPI_SIMO
  • #32引脚(GPIO33)作为SPI_CS

2.22 发送两个数据函数

uint16_t  SPIA_sendtwo(uint16_t txdata1,uint16_t txdata2)
{
    uint8_t data[6];
    data[0] = 1;
    data[5] = 255;
    data[1] = txdata1/256;
    data[2] = txdata1%256;
    data[3] = txdata2/256;
    data[4] = txdata2%256;
    SPISendData(data, 6);
}

由于所要发送的数据是16位的,但是STM32方面只能接收8位的数据,所以要先将两个16位数据转换为4个8位数据进行存储,并且在数据发送中还要加上头尾标识数用以确保数据的准确发送于接收。

2.23 发送函数

void SPISendData(uint8_t *data, unsigned int len)
{
int i;
uint16_t rxdata;
GPIO_WritePin(33, 0);
for (i = 0; i < len; i++)
{
// 写入数据到SPI缓冲区
SpiaRegs.SPITXBUF = data[i]<<8;

    // 等待数据发送完成
    while (SpiaRegs.SPISTS.bit.INT_FLAG != 1);
    rxdata = SpiaRegs.SPIRXBUF;
}
GPIO_WritePin(33, 1);

}

2.3-SPI通讯测试

从机STM32配置部分请参考这篇文章:
DSP280049C初学(3)-DSP280049C的ECAP配置,STM32F103C8T6作为信号发生端



/**
 * main.c
 */

#include "F28x_Project.h"
#include "IQmathLib.h"
#include "FOC.h"
#include "PWM.h"
#include "QEP.h"
#include "userSPI.h"

/*全局变量区*/
uint16_t now_position;

int main(void)
{
    InitSysCtrl();
    DINT;
    InitPieCtrl();
    IER=0x0000;
    IFR=0x0000;
    InitPieVectTable();
    DELAY_US(1000L);

    SPIA_int ();
    QEP_int();
    //EPWM1_int();
    EINT;                                       //使能全局中断
    ERTM;
    while (1)
    {
        SPIA_sendtwo(1234,4321);
        DELAY_US(1000L);
    }
}

在这里插入图片描述

基于DSP280049C的电机驱动系列回顾:

(一):CCS文件夹的建立与IQmath导入
(二):FOC文件的建立与开环代码编写
(三):EPWM配置
(四):EQEP配置与SPI主机配置

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
PMSM电机驱动器方框图是指永磁同步电机(Permanent Magnet Synchronous Motor)的控制系统结构图。PMSM电机驱动器方框图由以下几个主要组成部分组成: 1. PMSM电机:PMSM电机是驱动器的被控对象,它由固定在转子上的永磁体和位于固定位置的定子组成。PMSM电机的旋转速度和转矩通过对其相电流进行控制而实现。 2. 传感器:驱动器方框图中通常包括位置传感器和电流传感器。位置传感器用于测量转子的位置和速度信息,电流传感器用于测量电机相电流大小。 3. 控制算法:驱动器方框图中的控制算法用于根据电机的运行需求来计算所需的电机相电流。常用的控制算法包括电流环控制、位置环控制和速度环控制。 4. 控制器:控制器是整个驱动器系统的核心部分,它执行控制算法来生成合适的电机相电流控制信号。控制器通常由微控制器或数字信号处理器构成,可以根据传感器反馈的信息对电机进行精确的控制。 5. 功率电子器件:驱动器方框图中的功率电子器件主要用于控制电机相电流的大小和方向。常用的功率电子器件包括功率开关管(如MOSFET、IGBT等)和高频PWM控制信号发生器。 6. 电源:驱动器方框图中的电源用于提供系统所需的电能,为所有电子器件提供电源供电。 综上所述,PMSM电机驱动器方框图展示了PMSM电机控制系统的整体架构,通过传感器、控制算法、控制器和功率电子器件的协同工作,实现对电机速度和转矩的精确控制,满足不同应用中的需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Tony0925

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值