最新电影在线观看,jrs低调看直播,avav天堂,囯产精品宾馆在线精品酒店,亚洲精品成人区在线观看

兩輪平衡車_4_ 電機驅動代碼實現

電機模塊電路圖如下:

電機驅動芯片TB6612FNG驅動邏輯如下:

電機驅動代碼邏輯:通過改變驅動芯片輸入腳IN1、IN2的電平來控制電機的正反轉;通過改變芯片驅動PWM輸入腳的占空比改變電機的轉速。

/******************************************************************************

 *    FILENAME : Bsp_Motor.c

 *    PURPOSE  : 電機驅動函數接口

 *       Author: 電筆小新                      Created on: 2025年9月12日

******************************************************************************/

#include 

#include "User_Include.h"

//======================================================

// *  Variables & Function_Defines

//======================================================

// Motor_AIN1 引腳宏定義

    #define Motor_AIN1_H       (GpioDataRegs.GPBSET.bit.GPIO42=1)       

    #define Motor_AIN1_L       (GpioDataRegs.GPBCLEAR.bit.GPIO42=1)    

// Motor_AIN2 引腳宏定義

    #define Motor_AIN2_H       (GpioDataRegs.GPBSET.bit.GPIO33=1)       

    #define Motor_AIN2_L       (GpioDataRegs.GPBCLEAR.bit.GPIO33=1)    

// Motor_BIN1 引腳宏定義

    #define Motor_BIN1_H       (GpioDataRegs.GPASET.bit.GPIO3=1)      

    #define Motor_BIN1_L       (GpioDataRegs.GPACLEAR.bit.GPIO3=1)     

// Motor_BIN2 引腳宏定義

    #define Motor_BIN2_H       (GpioDataRegs.GPASET.bit.GPIO2=1)    

    #define Motor_BIN2_L       (GpioDataRegs.GPACLEAR.bit.GPIO2=1)   

//======================================================

// * Function    :  InitMotor

// * Purpose     :  Initialize the resource ports required for motor drive.

// * Parameters  :  Null

// * Return      :      Null

//======================================================

void InitMotor(void)

{

 /* ===== 步驟1:GPIO配置 ===== */

    EALLOW;  // 解除寄存器寫保護     

  // Motor_AIN1 初始化 

  GpioCtrlRegs.GPBMUX1.bit.GPIO42=0;    //IO口 

  GpioCtrlRegs.GPBDIR.bit.GPIO42=1;     //端口設置輸出 

  GpioCtrlRegs.GPBPUD.bit.GPIO42=1;     //上拉

    // Motor_AIN2 初始化   

GpioCtrlRegs.GPBMUX1.bit.GPIO33=0;    //IO口 

GpioCtrlRegs.GPBDIR.bit.GPIO33=1;     //端口設置輸出   

GpioCtrlRegs.GPBPUD.bit.GPIO33=1;     //上拉

    // Motor_BIN1 初始化 

  GpioCtrlRegs.GPAMUX1.bit.GPIO3=0;    //IO口 

  GpioCtrlRegs.GPADIR.bit.GPIO3=1;     //端口設置輸出 

  GpioCtrlRegs.GPAPUD.bit.GPIO3=1;     //上拉

    // Motor_BIN2 初始化 

  GpioCtrlRegs.GPAMUX1.bit.GPIO2=0;    //IO口   

  GpioCtrlRegs.GPADIR.bit.GPIO2=1;     //端口設置輸出   

  GpioCtrlRegs.GPAPUD.bit.GPIO2=1;     //上拉       

// 啟用 ePWM1 時鐘   

SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;   // 暫停所有 ePWM 時基

 SysCtrlRegs.PCLKCR1.bit.EPWM1ENCLK = 1;  // 開啟 ePWM1 時鐘

 // 配置 GPIO 引腳為 PWM 功能   

GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 1;   // 配置 GPIO0 為 PWM1A   

GpioCtrlRegs.GPAMUX1.bit.GPIO1 = 1;   // 配置 GPIO1 為 PWM1B

 EDIS;   // 恢復寄存器保護

 

    /* ===== 步驟2:配置 ePWM1 時基模塊 ===== */

    // PWM 頻率 = SYSCLKOUT / (TBPRD + 1) / (HSPCLKDIV * CLKDIV)

    EPwm1Regs.TBPRD = 60000;             // 周期值 (60MHz / 60000 = 1KHz PWM)

    EPwm1Regs.TBPHS.half.TBPHS = 0;      // 相位偏移

    EPwm1Regs.TBCTR = 0;                 // 計數器清零

 

    // 時基時鐘配置

    EPwm1Regs.TBCTL.bit.CTRMODE = 0;     // 增減計數模式 

    EPwm1Regs.TBCTL.bit.PHSEN = 0;       // 禁用相位加載

    EPwm1Regs.TBCTL.bit.HSPCLKDIV = 0;   // 高速時鐘分頻 (0=/1, 1=/2)

    EPwm1Regs.TBCTL.bit.CLKDIV = 0;      // 基準時鐘分頻 (0=/1, 1=/2...)

 

    /* ===== 步驟3:配置比較模塊 ===== */

    // PWM1A 占空比 = CMPA / TBPRD

    EPwm1Regs.CMPA.half.CMPA = 30000;    // 50% 占空比 (30000/60000)

    // PWM1B 占空比 = CMPB / TBPRD

    EPwm1Regs.CMPB = 15000;              // 25% 占空比 (15000/60000)

    /* ===== 步驟4:配置動作限定模塊 (關鍵步驟) ===== */

    // PWM1A 配置:

    EPwm1Regs.AQCTLA.bit.ZRO = 2;        // CTR=0 時設置高 (2=SET)

    EPwm1Regs.AQCTLA.bit.CAU = 1;        // CTR=CMPA 時清除 (1=CLEAR)

    // PWM1B 配置:

    EPwm1Regs.AQCTLB.bit.ZRO = 2;        // CTR=0 時設置高

    EPwm1Regs.AQCTLB.bit.CBU = 1;        // CTR=CMPB 時清除

    /* ===== 步驟5:禁用不需要的模塊 ===== */

    // 死區模塊 (DB) - 適用于獨立輸出

    EPwm1Regs.DBCTL.bit.OUT_MODE = 0;    // 禁用死區生成

    EPwm1Regs.DBCTL.bit.IN_MODE = 0;      // 禁用輸入控制

    // 事件觸發 (ET) - 可選禁用

    EPwm1Regs.ETSEL.bit.INTSEL = 0;      // 禁用中斷觸發

    EPwm1Regs.ETCLR.bit.INT = 1;          // 清除中斷標志

    // 斬波模塊 (PC) - 禁用

    EPwm1Regs.PCCTL.bit.CHPEN = 0;        // 禁用斬波生成

    /* ===== 步驟6:啟動 PWM ===== */

    EALLOW;

    SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;  // 啟動所有 ePWM 時基

    EDIS;

}

//======================================================

// * Function    :  Set_Pwm()

// * Purpose     :  Assign to PWM register.

// * Parameters  :  motor_left->Left wheel PWM;motor_right->Right wheel PWM

// * Return      :  Null

//======================================================

void Set_Pwm(int motor_left,int motor_right)

{

    if(motor_left>0)

    {

        Motor_AIN1_H;

        Motor_AIN2_L;  //前進

    }

    else

    {

        Motor_AIN1_L;

        Motor_AIN2_H;  //后退

    }

    EPwm1Regs.CMPA.half.CMPA = Cal_abs(motor_left);

    if(motor_right>0)

    {

        Motor_BIN1_H;

        Motor_BIN2_L;  //前進

    }

    else

    {

        Motor_BIN1_L;

        Motor_BIN2_H;  //后退

    }

    EPwm1Regs.CMPB=Cal_abs(motor_right);

}

//======================================================

// End of file.

//======================================================

編碼器的為AB兩相輸出的信號,如下圖

F28035集成了1個eQEP(Enhanced Quadrature Encoder Pulse)模塊(eQEP1),專門用于處理正交編碼器(AB相)的信號。

電機測速代碼邏輯:檢測左右兩個電機的轉速需要用到兩個eQEP,F28035內部的eQEP模塊不夠;但是F28035提供了6路可屏蔽外部中斷(XINT1至XINT6),每個中斷線可配置為響應特定GPIO引腳的邊沿(上升沿、下降沿或雙邊沿)或電平變化觸發。我們可以考慮用一路外部中斷和一個普通IO口組合起來檢測電機轉速;具體操作為設置外部中斷為上升沿觸發中斷,然后在中斷響應里面檢測IO的高低電平,高電平為正轉,計數值加一;低電平為反轉,計數值減一;通過固定時間讀取計數值計算電機轉速。

/******************************************************************************

 *    FILENAME : Bsp_Encoder.c

 *    PURPOSE  : 編碼器應用函數接口

 *     Author: 電筆小新                      Created on: 2025年9月12日

******************************************************************************/

#include "User_Include.h"

#include "Bsp_Encoder.h"

//======================================================

// *  Variables & Function_Defines

//======================================================

// XINT1B 引腳宏定義

    #define XINT1B()       (GpioDataRegs.GPADAT.bit.GPIO24)         /* 讀XINT1B狀態 */

// XINT2B 引腳宏定義

    #define XINT2B()       (GpioDataRegs.GPBDAT.bit.GPIO32)         /* 讀XINT2B狀態 */

 

int16 Encoder_left,Encoder_Right;

//======================================================

// * Function    :  InitEncoder

// * Purpose     :  Initialize the resource ports required for the encoder.

// * Parameters  :  Null

// * Return      :  Null

//======================================================

void InitEncoder(void)

{

    //--- 1. GPIO配置 ---

    EALLOW;

    // Encoder_XINT1A 初始化

    GpioCtrlRegs.GPADIR.bit.GPIO15=0;    // 設置為輸入模式

    GpioCtrlRegs.GPAPUD.bit.GPIO15=0;    // 啟用上拉

    GpioCtrlRegs.GPAMUX1.bit.GPIO15=0;

    GpioCtrlRegs.GPAQSEL1.bit.GPIO15 = 0; 

 // 外部中斷1(XINT1)與系統時鐘SYSCLKOUT同步

    // Encoder_XINT1B 初始化

    GpioCtrlRegs.GPADIR.bit.GPIO24=0;    // 設置為輸入模式

    GpioCtrlRegs.GPAPUD.bit.GPIO24=0;    // 啟用上拉

    GpioCtrlRegs.GPAMUX2.bit.GPIO24 = 0; // 普通IO模式

    // Encoder_XINT2A 初始化

    GpioCtrlRegs.GPADIR.bit.GPIO13=0;    // 設置為輸入模式

    GpioCtrlRegs.GPAPUD.bit.GPIO13=0;    // 啟用上拉

    GpioCtrlRegs.GPAMUX1.bit.GPIO13=0;

    GpioCtrlRegs.GPAQSEL1.bit.GPIO13 = 0;  

  // 外部中斷2(XINT2)與系統時鐘SYSCLKOUT同步

    // Encoder_XINT2B 初始化

    GpioCtrlRegs.GPBDIR.bit.GPIO32=0;    // 設置為輸入模式

    GpioCtrlRegs.GPBPUD.bit.GPIO32=0;    // 啟用上拉

    GpioCtrlRegs.GPBMUX1.bit.GPIO32 = 0; // 普通IO模式

    EDIS;

    //--- 2. 觸發源配置 ---

    EALLOW;

    GpioIntRegs.GPIOXINT1SEL.bit.GPIOSEL = 15;   // XINT1是GPIO15

    GpioIntRegs.GPIOXINT2SEL.bit.GPIOSEL = 13;   // XINT2是GPIO13

    EDIS;

    //--- 3. 觸發模式配置 ---

    XIntruptRegs.XINT1CR.bit.POLARITY = 1;      // 上升沿觸發中斷

    XIntruptRegs.XINT1CR.bit.ENABLE= 1;         // 使能XINT1

    XIntruptRegs.XINT2CR.bit.POLARITY = 1;      // 上升沿觸發中斷

    XIntruptRegs.XINT2CR.bit.ENABLE= 1;         // 使能XINT

    //--- 4. 中斷配置 ---

    EALLOW;

    PieVectTable.XINT1 = &XINT1_ISR;       // 注冊ISR

    PieCtrlRegs.PIEIER1.bit.INTx4 = 1;     // 使能PIE組1的INT4

    PieVectTable.XINT2 = &XINT2_ISR;       // 注冊ISR

    PieCtrlRegs.PIEIER1.bit.INTx5 = 1;     // 使能PIE組1的INT5

    EDIS;

    //--- 5. 全局中斷使能 ---

    IER |= M_INT1;               // 使能CPU中斷1

    EINT;                                  // 開全局中斷

}

 

 

//============================================================================

// * Function     :  Read_Encoder()

// * Purpose      :  Read encoder count per unit time.

// * Parameters  :  TIMX->External interrupt number

// * Return          :    Encoder_Cnt

//======================================================

int Read_Encoder(u8 TIMX)

{

   int16 Encoder_Cnt;    

   switch(TIMX)

     {

        case 1:  Encoder_Cnt= Encoder_left;  Encoder_left= 0;break;

        case 2:  Encoder_Cnt= Encoder_Right; Encoder_Right=0;break;

        default: Encoder_Cnt=0;

     }

        return Encoder_Cnt;

}

//---------------------------------------------------------------------------

// INT_ISR for XINT1:

//---------------------------------------------------------------------------

// INT1.4

interrupt void  XINT1_ISR(void)

{

    // Insert ISR Code here

    if (XINT1B()== 1)

    {

        Encoder_left++;

    }

    else

    {

        Encoder_left--;

    }

    PieCtrlRegs.PIEACK.bit.ACK1=1;

    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;  // 確認PIE組1中斷

}

//---------------------------------------------------------------------------

// INT_ISR for XINT2:

//---------------------------------------------------------------------------

// INT1.5

__interrupt void  XINT2_ISR(void)

{

    // Insert ISR Code here

    if (XINT2B() == 1)

      {

        Encoder_Right++;

      }

      else

      {

          Encoder_Right--;

      }

    PieCtrlRegs.PIEACK.bit.ACK1=1;

    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;  // 確認PIE組1中斷

}

//======================================================

// End of file.

//======================================================
聲明:本內容為作者獨立觀點,不代表電子星球立場。未經允許不得轉載。授權事宜與稿件投訴,請聯系:editor@netbroad.com
本篇所含全部資料,點擊此處留下郵箱我會發給你
資料明細:電機驅動程序
覺得內容不錯的朋友,別忘了一鍵三連哦!
贊 2
收藏 3
關注 85
成為作者 賺取收益
全部留言
0/200
  • zhoucwyh 3天前
    老師,能不能發我一下資料,謝謝! zh****@****.com
    回復 1條回復