这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 活动中心 » 板卡试用 » 【LAUNCHXL-F280049C】⑤作品提交:电机控制交互系统

共3条 1/1 1 跳转至

【LAUNCHXL-F280049C】⑤作品提交:电机控制交互系统

菜鸟
2025-07-28 23:09:27     打赏


【LAUNCHXL-F280049C】②初试driverlib驱动串口-电子产品世界论坛

https://forum.eepw.com.cn/thread/393642/1

【LAUNCHXL-F280049C】③eCAP、PWM模块测试及电机测速小试牛刀-电子产品世界论坛

https://forum.eepw.com.cn/thread/393681/1


综合测评的第2、第3贴,本篇完成作品提交:电机控制交互系统

核心交互系统采用的是迪文串口480X272电容触摸屏:

2825054625754f01f30b55ab857cff1.jpg



串口屏的电路部分很简单

VCC

TXD--------->开发板RXD/ GPIO28

RXD--------->开发板TXD/ GPIO29

GND

如下图,需拔掉短接帽(TXD,RXD),将串口屏端子接到J101下部分(而非去XDS110虚拟串口)。

image.png



串口屏软件设计部分在此篇不过多赘述:

如下图:最下方文本框,对应变量地址0x1020,变量类型:2Byte无符号整数

屏幕截图 2025-07-24 213529.png


第3篇帖子中,已测得编码电机的单个脉冲时间t,就可以通过60/t计算得到电机转速rpm

然后持续将电机转速指令输出给串口屏文本框即可

    //RPM,初始值为0
    uint16_t msg1[8] = {0x5A, 0xA5, 0x05, 0x82, 0x10, 0x20, 0x00, 0x00};
    //0~1  0x5A 0xA5 串口屏指令识别符
    //2    0x05 数据长度=5
    //3    0x82 写指令  0x83读指令
    //4~5  0x1020 串口屏对象地址
    //6~7  0x00 0x00 2Byte数据   
    
    SCI_writeCharArray(SCIA_BASE, msg1, 8);


需要注意的是,计算出来的电机转速rpm是整数,而发给串口屏的数据需要是16进制,因此需要进行转换。

另外,本程序预留了左上角、右上角两个按钮,按下分别可加减可变文本框(图中71),

开发板定时抓取其中数字,作为PWM占空比,可进行100挡位电机调速接口。


项目实物图如下:

70ca09354f51d814ffc200681dcaf0d.jpg


运行视频如下:

电机交互.gif


程序源码见以下:

//
// Included Files
//
#include "driverlib.h"
#include "device.h"
#include "board.h"
#include <stdlib.h>

//
// Defines
//
#define PWM3_TIMER_MIN     500U
#define PWM3_TIMER_MAX     8000U
#define EPWM_TIMER_UP      1U
#define EPWM_TIMER_DOWN    0U

//
// Globals
//
uint32_t ecap1IntCount;
uint32_t motor_cycle,motor_cycle1,motor_cycle2,motor_cycle3;
uint16_t rpm;
uint32_t ecap1PassCount;
uint32_t epwm3TimerDirection;
volatile uint32_t cap2Count;
volatile uint32_t cap3Count;
volatile uint32_t cap4Count;
volatile uint16_t epwm3PeriodCount;

//
// Function Prototypes
//
void error(void);
void initECAP(void);
void initEPWM(void);

uint16_t loopCounter = 0;
    char hexNum;




void decToHex(int decNum) 
{
    char rem1=0,rem2=0,i = 0;
    hexNum=0;

    rem1 = decNum / 16 +'0';  
    rem2 = decNum % 16;
    if (rem2 < 10)
     {
    rem2 = rem2 + '0'; // 将数字转换为字符
    } 
    else if (rem2==10)     {rem2=0x0A;}
    else if (rem2==11)     {rem2=0x0B;}
    else if (rem2==12)     {rem2=0x0C;}
    else if (rem2==13)     {rem2=0x0D;}
    else if (rem2==14)     {rem2=0x0E;}
    else if (rem2==15)     {rem2=0x0F;}    

    hexNum = rem1<<1;
    hexNum= hexNum + rem2;
   
}





//
// Main
//
void main(void)
{



    //
    // Initialize device clock and peripherals
    //
    Device_init();

    //
    // Disable pin locks and enable internal pullups.
    //
    Device_initGPIO();

    //
    // GPIO28 is the SCI Rx pin.
    //
    GPIO_setControllerCore(DEVICE_GPIO_PIN_SCIRXDA, GPIO_CORE_CPU1);
    GPIO_setPinConfig(DEVICE_GPIO_CFG_SCIRXDA);
    GPIO_setDirectionMode(DEVICE_GPIO_PIN_SCIRXDA, GPIO_DIR_MODE_IN);
    GPIO_setPadConfig(DEVICE_GPIO_PIN_SCIRXDA, GPIO_PIN_TYPE_STD);
    GPIO_setQualificationMode(DEVICE_GPIO_PIN_SCIRXDA, GPIO_QUAL_ASYNC);

    //
    // GPIO29 is the SCI Tx pin.
    //
    GPIO_setControllerCore(DEVICE_GPIO_PIN_SCITXDA, GPIO_CORE_CPU1);
    GPIO_setPinConfig(DEVICE_GPIO_CFG_SCITXDA);
    GPIO_setDirectionMode(DEVICE_GPIO_PIN_SCITXDA, GPIO_DIR_MODE_OUT);
    GPIO_setPadConfig(DEVICE_GPIO_PIN_SCITXDA, GPIO_PIN_TYPE_STD);
    GPIO_setQualificationMode(DEVICE_GPIO_PIN_SCITXDA, GPIO_QUAL_ASYNC);




    //
    // Initialize PIE and clear PIE registers. Disables CPU interrupts.
    //
    Interrupt_initModule();

    //
    // Initialize the PIE vector table with pointers to the shell Interrupt
    // Service Routines (ISR).
    //
    Interrupt_initVectorTable();

   //
    // Initialize SCIA and its FIFO.
    //
    SCI_performSoftwareReset(SCIA_BASE);

    //
    // Configure SCIA for echoback.
    //
    SCI_setConfig(SCIA_BASE, DEVICE_LSPCLK_FREQ, 115200, (SCI_CONFIG_WLEN_8 |
                                                        SCI_CONFIG_STOP_ONE |
                                                        SCI_CONFIG_PAR_NONE));
    SCI_resetChannels(SCIA_BASE);
    SCI_resetRxFIFO(SCIA_BASE);
    SCI_resetTxFIFO(SCIA_BASE);
    SCI_clearInterruptStatus(SCIA_BASE, SCI_INT_TXFF | SCI_INT_RXFF);
    SCI_enableFIFO(SCIA_BASE);
    SCI_enableModule(SCIA_BASE);
    SCI_performSoftwareReset(SCIA_BASE);

#ifdef AUTOBAUD
    //
    // Perform an autobaud lock.
    // SCI expects an 'a' or 'A' to lock the baud rate.
    //
    SCI_lockAutobaud(SCIA_BASE);
#endif





    //
    // Configure GPIO4/5 as ePWM3A/3B
    //
    GPIO_setPadConfig(4,GPIO_PIN_TYPE_STD);
    GPIO_setPinConfig(GPIO_4_EPWM3_A);
    GPIO_setPadConfig(5,GPIO_PIN_TYPE_STD);
    GPIO_setPinConfig(GPIO_5_EPWM3_B);

    //
    // Board initialization
    // Configure GPIO 16 as eCAP input
    // Enable interrupts required for this example
    //
    Board_init();
    
    //
    // Configure ePWM
    //
    initEPWM();

    //
    // Initialize counters:
    //
    cap2Count = 0U;
    cap3Count = 0U;
    cap4Count = 0U;
    ecap1IntCount = 0U;
    ecap1PassCount = 0U;
    epwm3PeriodCount = 0U;

    //
    // Enable Global Interrupt (INTM) and Real time interrupt (DBGM)
    //
    EINT;
    ERTM;

    //RPM,初始值为0
    uint16_t msg1[8] = {0x5A, 0xA5, 0x05, 0x82, 0x10, 0x20, 0x00, 0x00};
    //0~1  0x5A 0xA5 串口屏指令识别符
    //2    0x05 数据长度=5
    //3    0x82 写指令  0x83读指令
    //4~5  0x1020 串口屏对象地址
    //6~7  0x00 0x00 2Byte数据   


    SCI_writeCharArray(SCIA_BASE, msg1, 8);

    //
    // Loop forever. Suspend or place breakpoints to observe the buffers.
    //
    for(;;)
    {
    DEVICE_DELAY_US(500);   
    decToHex(rpm);
    msg1[7] = hexNum;

    //itoa(rpm, msg1[7], 16);

    //msg1[7] = (rpm / 16 < 10) ? (rpm / 16 + '0') : (rpm / 16 - 10 + 'A');
    //msg1[7] = (rpm % 16 < 10) ? (rpm % 16 + '0') : (rpm % 16 - 10 + 'A');

    //decimalToHex(rpm, msg1[7]) ;

    SCI_writeCharArray(SCIA_BASE, msg1, 8);
    
    }
}

//
// initEPWM - Configure ePWM
//
void initEPWM()
{
    //
    // Disable sync(Freeze clock to PWM as well)
    //
    SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);

    //
    // Configure ePWM
    //       Counter runs in up-count mode.
    //       Action qualifier will toggle output on period match
    //
    EPWM_setTimeBaseCounterMode(EPWM3_BASE, EPWM_COUNTER_MODE_UP);
    EPWM_setTimeBasePeriod(EPWM3_BASE, PWM3_TIMER_MIN);
    EPWM_setPhaseShift(EPWM3_BASE, 0U);
    EPWM_setActionQualifierAction(EPWM3_BASE,
                                  EPWM_AQ_OUTPUT_A,
                                  EPWM_AQ_OUTPUT_TOGGLE,
                                  EPWM_AQ_OUTPUT_ON_TIMEBASE_PERIOD);
    EPWM_setClockPrescaler(EPWM3_BASE,
                           EPWM_CLOCK_DIVIDER_1,
                           EPWM_HSCLOCK_DIVIDER_2);

    epwm3TimerDirection = EPWM_TIMER_UP;

    //
    // Enable sync and clock to PWM
    //
    SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
}

//
// myECAP0 ISR
//
__interrupt void INT_myECAP0_ISR(void)
{
    //
    // Get the capture counts. Each capture should be 2x the ePWM count
    // because of the ePWM clock divider.
    //
    cap2Count = ECAP_getEventTimeStamp(myECAP0_BASE, ECAP_EVENT_2);
    cap3Count = ECAP_getEventTimeStamp(myECAP0_BASE, ECAP_EVENT_3);
    cap4Count = ECAP_getEventTimeStamp(myECAP0_BASE, ECAP_EVENT_4);

    motor_cycle1=cap2Count/100;  //单个编码脉冲时间 单位us 
    motor_cycle2=cap3Count/100;
    motor_cycle3=cap4Count/100;

    motor_cycle = motor_cycle1*2*1152/1000; //电机转一圈时间 单位ms (电机输出轴转一圈输出1152个脉冲)
    rpm=60000/motor_cycle;  //6000ms


    
    epwm3PeriodCount = EPWM_getTimeBasePeriod(EPWM3_BASE);

    

    ecap1IntCount++;

    //
    // Keep track of the ePWM direction and adjust period accordingly to
    // generate a variable frequency PWM.
    //
    
    //
    // Count correct captures
    //
    ecap1PassCount++;

    //
    // Clear interrupt flags for more interrupts.
    //
    ECAP_clearInterrupt(myECAP0_BASE,ECAP_ISR_SOURCE_CAPTURE_EVENT_4);
    ECAP_clearGlobalInterrupt(myECAP0_BASE);

    //
    // Start eCAP
    //
    ECAP_reArm(myECAP0_BASE);

    //
    // Acknowledge the group interrupt for more interrupts.
    //
    Interrupt_clearACKGroup(INT_myECAP0_INTERRUPT_ACK_GROUP);
}

//
// error - Error function
//
void error()
{
    ESTOP0;
}







关键词: C2000    

院士
2025-07-29 07:26:05     打赏
2楼

电机转起来,电机转起来


高工
2025-07-29 09:17:29     打赏
3楼

意思是,用定时器 + IO电平检测做占空比检测,不是常规的PWM输入捕获模式进行占空比计算?


共3条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]