DSP CCS12.00 芯片:TMS320F28335 结课设计 : 电机模块 + 按键模块 + EQEP 模块 设计 + TFTLCD 的设计 第二次尝试

代码功能:

DSP  PWM  与电机速度 相互 影响

功能:

1.可以  改变 PWM  , 同时 DSP 自动更新电机 速度

2. 可以通过 外部中断  控制  改变数值的变量   (PWM --》 速度 ,  速度---》PWM)

3.可以通过控制显示 屏幕上面的 速度,来控制  DSP 的PWM , 控制 电机的速度。 (实测速度没有显示!!!)

代码:

#include <bsp_includes.h>
#include <math.h>
#include "IQmathLib.h"

///
//结构体部分:
typedef struct
{
   volatile struct EPWM_REGS *EPwmRegHandle;
   Uint16 EPwm_CMPA_Direction;
   Uint16 EPwm_CMPB_Direction;
   Uint16 EPwmTimerIntCount;
   Uint16 EPwmMaxCMPA;
   Uint16 EPwmMinCMPA;
   Uint16 EPwmMaxCMPB;
   Uint16 EPwmMinCMPB;
}EPWM_INFO;



typedef struct {float ElecTheta;    //OutPut: Motor Electrical Angle
                float MechTheta;    //Output: Motor Mechanical Angle
                float MechTheta_Beyond;  //存储超过一圈后的位置信息的变量
                  int DirectionQep; //output: Motor rotation direction

                  int PolePairs;     //Parameter: 同步电机极对数
                  int LineEncoder;   //Parameter: 码盘一周脉冲数(增量式)
                  int Encoder_N;     //Parameter: 码盘一周脉冲数的4倍(根据倍频的倍数而定,这里用4倍频)
                  int CalibrateAngle;//Parameter:电机A相绕组和码盘Index信号之间的夹角,与安装精度有关
                float Mech_Scaler;   //Parameter:1/Encoder_N
                float RawTheta;      //Variable: 初始定位后,电机转子d轴和定子A相绕组之间所相差的码盘计数值
                  int Index_sync_flag;//Output: Index sync status

                float BaseRpm;        //Parameter:额定转速

                float Speed_Mr_Rpm_Scaler;//Parameter:60000/(Encoder_N * T),其中T为M法测速时的时间间隔,单位ms//60/512线/(4倍频*0.001s)
                float Speed_Mr_Rpm;   //Output: speed int r.p.m
                float Speed_Mr;       //Output: speed in per-uint
                float Position_k_1;   //Input: Current position
                float Position_k;     //Input: Last position

                float Speed_Tr_Rpm_Scaler;//Parameter: (UPPS * 150e6 * 60)/(Encoder_N * CCPS)//150e6*60/512
                float Speed_Tr_Rpm;   //Output: spedd int r.p.m
                float Speed_Tr;       //Output: speed int per-uint

                float t1;
                float t2;
                float t3;

                float Ts; // 采样时间
                float K2; //滤波系数

                float Speed_Temp;
                float Speed;             // Output :  speed in per-unit
                Uint32 K;

                  int cnt_old; //eQEP位置计数器寄存器中上一个时刻的计数值
                  int cycles; // 电机转过的圈数
                  float position;

                void (*init)();         // Pointer to the init funcion
                void (*calc)();
                } EQEP_POS_SPEED_GET;

//-----------------------------------------------------------------------------
// Define a POSSPEED_handle
//-----------------------------------------------------------------------------
typedef EQEP_POS_SPEED_GET  *EQEP_POS_SPEED_GET_handle;

//-----------------------------------------------------------------------------
// Default initializer for the POSSPEED Object.
//-----------------------------------------------------------------------------
#if (CPU_FRQ_150MHZ)
#define EQEP_POS_SPEED_GET_DEFAULTS {0,0,0,0,\
                                     2,500,2000,0,1.0/2000,0,0,\
                                     6000.0,\
                                     9.76,0,0,0,0,\
                                     17578125,0,0,\
                                     0,0,0,0,0,0,0,0,0,0,0,\
                                     (void (*)(long))eQEP_pos_speed_get_Init,\
                                     (void (*)(long))eQEP_pos_speed_get_Calc}
                                     //注意9.76是0.003s为周期


//#define EQEP_POS_SPEED_GET_DEFAULTS {0,0,0,0,\
//                                     2,500,2000,0,1.0/2000,0,0,\
//                                     6000.0,\
//                                     29.29,0,0,0,0,\
//                                     17578125,0,0,\
//                                     0,0,0,0,0,0,0,0,0,0,0,\
//                                     (void (*)(long))eQEP_pos_speed_get_Init,\
//                                     (void (*)(long))eQEP_pos_speed_get_Calc}

#endif

#if (CPU_FRQ_100MHZ)
#define EQEP_POS_SPEED_GET_DEFAULTS {0,0,0,\
                                     2,500,2000,0,1.0/2000,0,0,\
                                     6000.0,\
                                     3.0,0,0,0,0,\
                                     1125000,0,0,\
                                     0,0,0,0,0,0,0,0,\
                                     (void (*)(long))eQEP_pos_speed_get_Init,\
                                     (void (*)(long))eQEP_pos_speed_get_Calc}
#endif





struct EQEP_POS_SPEED_GET
{
                float ElecTheta;    //OutPut: Motor Electrical Angle
                float MechTheta;    //Output: Motor Mechanical Angle
                float MechTheta_Beyond;  //存储超过一圈后的位置信息的变量
                  int DirectionQep; //output: Motor rotation direction

                  int PolePairs;     //Parameter: 同步电机极对数
                  int LineEncoder;   //Parameter: 码盘一周脉冲数(增量式)
                  int Encoder_N;     //Parameter: 码盘一周脉冲数的4倍(根据倍频的倍数而定,这里用4倍频)
                  int CalibrateAngle;//Parameter:电机A相绕组和码盘Index信号之间的夹角,与安装精度有关
                float Mech_Scaler;   //Parameter:1/Encoder_N
                float RawTheta;      //Variable: 初始定位后,电机转子d轴和定子A相绕组之间所相差的码盘计数值
                  int Index_sync_flag;//Output: Index sync status

                float BaseRpm;        //Parameter:额定转速

                float Speed_Mr_Rpm_Scaler;//Parameter:60000/(Encoder_N * T),其中T为M法测速时的时间间隔,单位ms//60/512线/(4倍频*0.001s)
                float Speed_Mr_Rpm;   //Output: speed int r.p.m
                float Speed_Mr;       //Output: speed in per-uint
                float Position_k_1;   //Input: Current position
                float Position_k;     //Input: Last position

                float Speed_Tr_Rpm_Scaler;//Parameter: (UPPS * 150e6 * 60)/(Encoder_N * CCPS)//150e6*60/512
                float Speed_Tr_Rpm;   //Output: spedd int r.p.m
                float Speed_Tr;       //Output: speed int per-uint

                float t1;
                float t2;
                float t3;

                float Ts; // 采样时间
                float K2; //滤波系数

                float Speed_Temp;
                float Speed;             // Output :  speed in per-unit
                Uint32 K;

                  int cnt_old; //eQEP位置计数器寄存器中上一个时刻的计数值
                  int cycles; // 电机转过的圈数
                  float position;

                void (*init)();         // Pointer to the init funcion
                void (*calc)();
                };

//-----------------------------------------------------------------------------
// Define a POSSPEED_handle
//-----------------------------------------------------------------------------
typedef EQEP_POS_SPEED_GET  *EQEP_POS_SPEED_GET_handle;

//-----------------------------------------------------------------------------
// Default initializer for the POSSPEED Object.
//-----------------------------------------------------------------------------
#if (CPU_FRQ_150MHZ)
#define EQEP_POS_SPEED_GET_DEFAULTS {0,0,0,0,\
                                     2,500,2000,0,1.0/2000,0,0,\
                                     6000.0,\
                                     9.76,0,0,0,0,\
                                     17578125,0,0,\
                                     0,0,0,0,0,0,0,0,0,0,0,\
                                     (void (*)(long))eQEP_pos_speed_get_Init,\
                                     (void (*)(long))eQEP_pos_speed_get_Calc}
                                     //注意9.76是0.003s为周期


//#define EQEP_POS_SPEED_GET_DEFAULTS {0,0,0,0,\
//                                     2,500,2000,0,1.0/2000,0,0,\
//                                     6000.0,\
//                                     29.29,0,0,0,0,\
//                                     17578125,0,0,\
//                                     0,0,0,0,0,0,0,0,0,0,0,\
//                                     (void (*)(long))eQEP_pos_speed_get_Init,\
//                                     (void (*)(long))eQEP_pos_speed_get_Calc}

#endif

#if (CPU_FRQ_100MHZ)
#define EQEP_POS_SPEED_GET_DEFAULTS {0,0,0,\
                                     2,500,2000,0,1.0/2000,0,0,\
                                     6000.0,\
                                     3.0,0,0,0,0,\
                                     1125000,0,0,\
                                     0,0,0,0,0,0,0,0,\
                                     (void (*)(long))eQEP_pos_speed_get_Init,\
                                     (void (*)(long))eQEP_pos_speed_get_Calc}
#endif






///定义部分 :
#define Key_Read *((Uint16 *)0x4700)
#define KeyValue ((Key_Read)&0x0f)
#define keyon1 GpioDataRegs.GPADAT.bit.GPIO29

// Configure the period for each timer
#define EPWM1_TIMER_TBPRD  2000  // Period register
#define EPWM1_MAX_CMPA     1950
#define EPWM1_MIN_CMPA       50
#define EPWM1_MAX_CMPB     1950
#define EPWM1_MIN_CMPB       50

// To keep track of which way the compare value is moving
#define EPWM_CMP_UP   1
#define EPWM_CMP_DOWN 0



/
//函数部分:
interrupt void xint1_isr(void);//中断函数
void delay_loop_2(void);//一秒的延时函数
void delay_loop_1(void);//超短时间的延时
void InitEPwm1Example(void);//PWM 初始化
void update_compare(EPWM_INFO*);//电机转速改变函数
void Init_Port(void);//电机初始化函数
void return_PWM(void);//PWM 计算函数
void kkkk();//只改变 PWM 数值位置的数字
void pppp();//只改变 速度位置的数字
void bianhua();//改变所有的数值  更新模块
void TFTLCD(uchar str3,uchar st4);//更新TFT LCD
void interrupt_init();//外部中断初始化
void eQEP_pos_speed_get_Init(EQEP_POS_SPEED_GET *p);//EQEP 测速模块的初始化
void eQEP_pos_speed_get_Calc(EQEP_POS_SPEED_GET *p);//EQEP 测速模块的计算



//全局变量模块
EPWM_INFO epwm1_info;//PWM  模块的计算变量

int num=200;//PWM的数值
int speed=0;//测量的速度
int fangxiang=0;//当fangxiang=0  电机转动的方向为  调PWM    , fangxiang==1  电机转动的方向为  调速度
/********************************************************************************************
 * 在做TFTLCD时,找到对用的头文件,改变宏定义即可,
 * */
#if (TFTLCD_TEST == 1)
uchar class[]= {"班级 :"};
uchar Name[]= {"名字: "};
uchar student_ID[]={"学号:"};
uchar Str1[] = {"PWM :   "};//方向的提示语句
uchar Str2[] = {"速度: "};//速度的提示语句
uchar lll1[] = {"change options: 速度"};
uchar lll2[] = {"change options: PWM"};
#endif

///EQEP模块
int DirectionQep=0;
int LineEncoder=500;
int Encoder_N=2000;
unsigned int motor_speed=100;
float Speed_Mr_RPM=0;
float Position_k_1=0;
float Position_k=0;
unsigned int delay_show=0;
EQEP_POS_SPEED_GET Pos_speed = EQEP_POS_SPEED_GET_DEFAULTS;//测速模块的初始化
int mmm=0;//判定模式
int nnn=0;//
int hhh=0;
int hhh1=0;

//函数入口:
void main()
{
    //TFTLCD 初始化
       InitSysCtrl();
       DINT;
       InitPieCtrl();
       IER = 0x0000;
       IFR = 0x0000;
       InitPieVectTable();
       InitEPwm1Gpio();//PWM 控制电机的引脚初始化
       InitEPwm1Example();//PWM  控制电机的初始化 函数
       InitEQepGpio();//EQEP 模块引脚初始化
       Pos_speed.init(&Pos_speed);//EQEP 模块初始化


       InitXintf();//流水灯模块初始化
       InitSpiaGpio();//LCD 模块初始化
       interrupt_init();//中断初始化
       bianhua();//开始的显示


         EALLOW;
         SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;
         EDIS;
         InitEPwm1Example();//PWM初始化
         EALLOW;
         SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;
         EDIS;
         IER |= M_INT3;
         EINT;
         ERTM;

         update_compare(&epwm1_info);//电机速度加载
         Pos_speed.calc(&Pos_speed);//开始的时候根据 PWM 计算速度

             ///小灯模块
            EALLOW;
            GpioCtrlRegs.GPAMUX1.bit.GPIO6 = 00;      // GPIO6为GPIO功能
            GpioCtrlRegs.GPADIR.bit.GPIO6 = 1;      // GPIO6为输出功能
            GpioCtrlRegs.GPAMUX1.bit.GPIO7 = 00;      // GPIO7为GPIO功能
            GpioCtrlRegs.GPADIR.bit.GPIO7 = 1;      // GPIO7为输出功能
            EDIS;

            GpioDataRegs.GPATOGGLE.bit.GPIO6= 1;// GPIO06翻转  开始的时候为1  led 灯关闭
            GpioDataRegs.GPATOGGLE.bit.GPIO7= 1;// GPIO07翻转  开始的时候为1  led 灯关闭


       while(1)
       {
             Pos_speed.calc(&Pos_speed);//速度 用 EQEP 模块 计算
             if(fangxiang==0)//当我们的 改变的值是 PWM 的时候
             {
                 if(nnn>=10) //计算速度的平均值
                 {
                     motor_speed=mmm/10;//计算速度的平均值
                     pppp();//自动改变速度的值
                     mmm=0;
                     nnn=0;
                 }
                 hhh=(int)abs(Pos_speed.Speed_Tr_Rpm);//记录 转速的值
                 if(hhh>290 || hhh<=0)//防止 数字太离谱 直接去掉
                 {
                     mmm+=hhh1;
                     nnn++;
                 }
                 else
                 {
                     hhh1=hhh;
                     mmm+=hhh;
                     nnn++;
                 }

                 delay_loop_1();//这里加一个延时是为了保证 key   按键按下去的时候能够识别的到
                 if(KeyValue==0x0e)//1110  e//按键判断
                 {
                     if(num<EPWM1_TIMER_TBPRD/2-110)
                     {
                         num+=100;
                     }
                     kkkk();//刷新 PWM
                 }
                 delay_loop_1();//这里加一个延时是为了保证 key   按键按下去的时候能够识别的到
                 if(KeyValue==0x0d) //1101  13->d
                 {
                     if(num>110)
                     {
                         num-=100;
                     }
                     kkkk();//刷新 PWM
                 }
                 delay_loop_1();
                 if(KeyValue==0x0b)//1011  11->b
                 {
                     if(num<EPWM1_TIMER_TBPRD/2-10)
                     {
                         num+=10;
                     }
                     kkkk();//刷新 PWM
                 }
                 delay_loop_1();
                 if(KeyValue==0x07)//0111  7
                 {
                       if(num>=20)
                       {
                          num=num-10;
                       }
                      kkkk();//刷新 PWM
                 }
             }

             else if(fangxiang==1)//当我们  改变的值 是 速度 的时候
             {
                 if(nnn==10)
                 {
                     nnn=0;
                 }
                 delay_loop_1();//这里加一个延时是为了保证 key   按键按下去的时候能够识别的到
                 if(KeyValue==0x0e)//1110  e//按键判断
                 {
                     if(motor_speed<140)
                     {
                         motor_speed+=10;
                     }
                     pppp();//改变速度的值
                     return_PWM();
                     update_compare(&epwm1_info);//改变电机的速度
                     kkkk();//刷新 PWM
                 }
                 delay_loop_1();//这里加一个延时是为了保证 key   按键按下去的时候能够识别的到
                 if(KeyValue==0x0d) //1101  13->d
                 {
                     if(motor_speed>50)
                     {
                         motor_speed-=10;
                         if(motor_speed==90)
                         {
                             bianhua();
                         }
                     }

                     pppp();//改变速度的值
                     return_PWM();
                     update_compare(&epwm1_info);//改变电机的速度
                     kkkk();//刷新 PWM
                 }
                 delay_loop_1();
                 if(KeyValue==0x0b)//1011  11->b
                 {
                     if(motor_speed<148)
                     {
                         motor_speed+=1;
                     }
                     pppp();//改变速度的值
                     return_PWM();
                     update_compare(&epwm1_info);//改变电机的速度
                     kkkk();//刷新 PWM
                 }
                 delay_loop_1();
                 if(KeyValue==0x07)//0111  7
                 {
                     if(motor_speed>46)
                     {
                         motor_speed-=1;
                         if(motor_speed==99)
                          {
                              bianhua();
                          }
                     }
                     pppp();//改变速度的值
                     return_PWM();
                     update_compare(&epwm1_info);//改变电机的速度
                     kkkk();//刷新 PWM
                 }

             }
       }
}


void eQEP_pos_speed_get_Calc(EQEP_POS_SPEED_GET *p)
{

    int cnt_inc , cnt_cur;
    float tmp1;
    unsigned int t2_t1;
    unsigned long M1,M2,fclk;

    //Check the rotational direction
    p->DirectionQep = EQep1Regs.QEPSTS.bit.QDF;
    cnt_cur = EQep1Regs.QPOSCNT;

    //Check the position counter for EQep1
    p->RawTheta = cnt_cur + p->CalibrateAngle;
    if(p->RawTheta < 0)
    {
        p->RawTheta = p->RawTheta + EQep1Regs.QPOSMAX;
    }
    else if(p->RawTheta > EQep1Regs.QPOSMAX)
    {
        p->RawTheta = p->RawTheta - EQep1Regs.QPOSMAX;
    }

    //Compute the mechanical angle

    p->MechTheta = p->Mech_Scaler * p->RawTheta;

    /*****************超过一圈后的角度计算*************/
    // Check the counter for QEP
    cnt_inc = cnt_cur - p->cnt_old;
    if (abs(cnt_inc) > 200)     //6000 RPM, 1ms能读到的最大差值就是200,  除非转角超过1圈.
    {
        if (cnt_inc < 0)
            p->cycles +=1;
        else
            p->cycles -=1;
    }

    p->cnt_old = cnt_cur;

    //Compute the mechanical angle
    tmp1=p->MechTheta_Beyond;   // old position
    p->MechTheta_Beyond = p->MechTheta+p->cycles;

    p->Speed = 60*(p->MechTheta_Beyond-tmp1)/p->Ts;   // speed in RPM values


    // Check an index occurrence
    if (EQep1Regs.QFLG.bit.IEL == 1)
    {
        p->Index_sync_flag = 0x00F0;
        EQep1Regs.QCLR.bit.IEL=1;                   // Clear interrupt flag
    }


    //
    // High Speed Calculation using QEP Position counter
    // Check unit Time out-event for speed calculation:
    // Unit Timer is configured for 100Hz in INIT function
    //


     if(EQep1Regs.QFLG.bit.UTO==1)// If unit timeout (one 100Hz period)
         {
          p->Position_k =1.0 * EQep1Regs.QPOSLAT;
          if(p->DirectionQep==0) // POSCNT is counting down
            {
             if(p->Position_k > p->Position_k_1)
               { tmp1 = -(p->Encoder_N - (p->Position_k - p->Position_k_1)); }
             else
               { tmp1 = p->Position_k - p->Position_k_1;}// x2-x1 should be negative
            }
          else if(p->DirectionQep==1)    // POSCNT is counting up
            {
             if(p->Position_k < p->Position_k_1)
               { tmp1 = p->Encoder_N - (p->Position_k_1 - p->Position_k); }
             else
               { tmp1 = p->Position_k - p->Position_k_1;}// x2-x1 should be positive
            }

          if(tmp1 > p->Encoder_N)
            { p->Speed_Mr_Rpm = p->BaseRpm;  }
          else if(tmp1 < -p->Encoder_N)
            { p->Speed_Mr_Rpm = -p->BaseRpm; }
          else
            { p->Speed_Mr_Rpm = tmp1 * p->Speed_Mr_Rpm_Scaler; }

           p->Speed_Mr = p->Speed_Mr_Rpm / p->BaseRpm;

           p->Position_k_1 = p->Position_k;

           EQep1Regs.QCLR.bit.UTO=1; // Clear interrupt flag
         }


//    // Low-speed computation using QEP capture counter // T法
    if(EQep1Regs.QEPSTS.bit.UPEVNT==1)                          // Unit position event
    {
        if(EQep1Regs.QEPSTS.bit.COEF==0)                        // No Capture overflow
            t2_t1 =  EQep1Regs.QCPRD;
        else                                                    // Capture overflow, saturate the result
            t2_t1 = 0xFFFF;

        //
        // Convert p->Speed_pr to RPM
        //

        if(p->DirectionQep==0)
            p->Speed_Tr_Rpm = - p->Speed_Tr_Rpm_Scaler / t2_t1; //negative
        else
            p->Speed_Tr_Rpm =  p->Speed_Tr_Rpm_Scaler / t2_t1;
        //       if(p->Speed_Tr_Rpm > p->BaseRpm)
        //         p->Speed_Tr_Rpm = p->BaseRpm;
        //       else if(p->Speed_Tr_Rpm < -p->BaseRpm)
        //         p->Speed_Tr_Rpm = -p->BaseRpm;
        //
        EQep1Regs.QEPSTS.all=0x88;          // Clear Unit position event flag
                                            // Clear overflow error flag
    }
    GpioDataRegs.GPATOGGLE.bit.GPIO6= 1;// GPIO06翻转  开始的时候为1  led 灯关闭
    GpioDataRegs.GPATOGGLE.bit.GPIO7= 1;// GPIO07翻转  开始的时候为1  led 灯关闭
    delay_loop_2();
    GpioDataRegs.GPATOGGLE.bit.GPIO6= 1;// GPIO06翻转  开始的时候为1  led 灯关闭
    GpioDataRegs.GPATOGGLE.bit.GPIO7= 1;// GPIO07翻转  开始的时候为1  led 灯关闭


}

void eQEP_pos_speed_get_Init(EQEP_POS_SPEED_GET *p)
{


#if (CPU_FRQ_150MHZ)
//  EQep1Regs.QUPRD=1500000;            // Unit Timer for 100Hz at 150 MHz SYSCLKOUT
//案例给的程序错误的地方 这个是单位事件使能 也就是说M法
    EQep1Regs.QUPRD=150000*3;            // Unit Timer for 100Hz at 150 MHz SYSCLKOUT
#endif

#if (CPU_FRQ_100MHZ)
    EQep1Regs.QUPRD=1000000;            // Unit Timer for 100Hz at 100 MHz SYSCLKOUT
#endif


    p->Encoder_N=4*p->LineEncoder;
    p->Mech_Scaler=1.0/p->Encoder_N;

    EQep1Regs.QDECCTL.bit.QSRC=0x00;        // QEP quadrature count mode
    EQep1Regs.QEPCTL.bit.FREE_SOFT=2;
    EQep1Regs.QEPCTL.bit.PCRM=0x01;         // PCRM=00 mode - QPOSCNT reset on index event
    EQep1Regs.QEPCTL.bit.UTE=1;         // Unit Timeout Enable
    EQep1Regs.QEPCTL.bit.QCLM=1;        // Latch on unit time out
    EQep1Regs.QPOSMAX=p->Encoder_N;     // Encoder_N
    EQep1Regs.QEPCTL.bit.QPEN=1;        // QEP enable

    EQep1Regs.QCAPCTL.bit.UPPS=1;       // 1/2 for unit position
    EQep1Regs.QCAPCTL.bit.CCPS=3;       // 1/8 for CAP clock
    EQep1Regs.QCAPCTL.bit.CEN=1;        // QEP Capture Enable
//  EQep1Regs.QPOSMAX=0xffffffff;

    p->cycles=0;
    p->Speed_Tr_Rpm_Scaler=60.0*150*1000000/4/p->Encoder_N;
    p->Speed_Tr_Rpm=0;

    //EQep1Regs.QEPCTL.bit.SWI=1;// software generate index pulse

}
void interrupt_init()外部中断初始化
{
    EALLOW;  // 修改被保护的寄存器,修改前应添加EALLOW语句
   PieVectTable.XINT1 = &xint1_isr;
   EDIS;   // EDIS的意思是不允许修改被保护的寄存器

   // 在外设中断扩展模块中断使能寄存器中允许XINT1和XINT2: (组1中断4 & 5)
   // 使能CPU中断1(INT1):
      PieCtrlRegs.PIECTRL.bit.ENPIE = 1;          // 使能外设中断扩展PIE模块
      PieCtrlRegs.PIEIER1.bit.INTx4 = 1;          // 使能PIE组1的INT4
      IER |= M_INT1;                              // 使能CPU中断1(INT1)
      EINT;                                       // 开全局中断

      // GPIO29配置为输入引脚通用I/O口,接按键TZ1,TZ2
         EALLOW;
         GpioCtrlRegs.GPAMUX2.bit.GPIO29 = 0;         // 选择为通用I/O口
         GpioCtrlRegs.GPADIR.bit.GPIO29 = 0;          // 方向定义为输入
         GpioCtrlRegs.GPAPUD.bit.GPIO29=0;
         GpioCtrlRegs.GPAQSEL2.bit.GPIO29 = 0;        // 外部中断1(XINT1)与系统时钟SYSCLKOUT同步
         GpioCtrlRegs.GPACTRL.bit.QUALPRD0 = 0x80;   // 每个采样窗口的周期
         EDIS;


 // 通过GPIO外部中断选择寄存器,选择GPIO12为外部中断1,选择GPIO13为外部中断2
    EALLOW;
    GpioIntRegs.GPIOXINT1SEL.bit.GPIOSEL = 0x1D;   // XINT1是GPIO29
    EDIS;

    // 配置外部中断1和2的中断控制寄存器
       XIntruptRegs.XINT1CR.bit.POLARITY = 0;      // 下降沿触发中断

    // 使能外部中断1和外部中断2
       XIntruptRegs.XINT1CR.bit.ENABLE = 1;        // 使能XINT1
}

void TFTLCD(uchar str3,uchar str4)
{
    //TFTLCD实验
  #if (TFTLCD_TEST == 1)
      ILI9325_Init();         //TFT初始化
      //显示字符
      LCD_PutString(37, 20,class, WHITE,RED);//显示班级
      LCD_PutString(37, 50,Name,  WHITE,RED);//显示名字
      LCD_PutString(37, 80,student_ID, RED,WHITE);//显示学号
      LCD_PutString(37, 110,Str1, WHITE,RED);//PWM
      LCD_PutString(120,110,str4, WHITE,RED);//PWM 的值
      LCD_PutString(37,140,Str2, WHITE,RED);//速度
      LCD_PutString(110,140,str3, WHITE,RED);//速度的数值

      if(fangxiang==0)
      {
          LCD_PutString(37,170,lll2, WHITE,RED);//PWM的数值
      }
      else
      {
          LCD_PutString(37,170,lll1, WHITE,RED);//速度的数值
      }

  #endif
}

void bianhua()//改变显示器的 显示数据
{

    if(num>(EPWM1_TIMER_TBPRD/2+1))
    {
        return;
    }
    update_compare(&epwm1_info);//更新电机的转速
    TFTLCD("0","0");
    kkkk();//显示PWM
    pppp();//显示速度
}





void pppp()//只改变速度
{

        if(motor_speed>290)
        {
            motor_speed=200;
            kkkk();

            return ;
        }
       int n1,n2,n3;
       if(motor_speed<100)
       {
           uchar str3[5];
           n1=motor_speed/10;
           str3[0]=n1+48;
           n2=motor_speed%10;
           str3[1]=n2+48;
            str3[2]=32;
            str3[3]=32;
           LCD_PutString(110,140,str3, WHITE,RED);//PWM 的值
       }
       else if(motor_speed<1000)
       {
           uchar str3[5];
           n1=motor_speed/100;
           str3[0]=n1+48;
           n2=motor_speed%100/10;
           str3[1]=n2+48;
           n3=motor_speed%10;
           str3[2]=n3+48;
           str3[3]=0;
           LCD_PutString(110,140,str3, WHITE,RED);//PWM 的值
       }

}




void kkkk()//只改变  PWM 的值
{

    int n1;
   int n2;
   int n3;
   int n4;
    if(num>(EPWM1_TIMER_TBPRD/2+1))
    {
        return;
    }
    update_compare(&epwm1_info);//改变电机的速度

       if(num<10)
        {
            n1=num;
        }
        else if(num<100)
        {
            uchar str3[3];
            n1=num/10;
            str3[0]=n1+48;
            n2=num%10;
            str3[1]=n2+48;
             str3[2]=32;
            LCD_PutString(120,110,str3, WHITE,RED);//PWM 的值


        }
        else if(num<1000)
        {
            uchar str3[4];
            n1=num/100;
            str3[0]=n1+48;
            n2=num%100/10;
            str3[1]=n2+48;
            n3=num%10;
            str3[2]=n3+48;
            LCD_PutString(120,110,str3, WHITE,RED);//PWM 的值
        }
        else if(num<10000)
        {
            uchar str3[5];
            n1=num/1000;
            str3[0]=n1+48;
            n2=num%1000/100;
            str3[1]=n2+48;
            n3=num%100/10;
            str3[2]=n3+48;
            n4=num%10;
            str3[3]=n4+48;
            LCD_PutString(120,110,str3, WHITE,RED);//PWM 的值
        }

}

void  return_PWM()//计算PWM 的值
{
    int m=(int) (motor_speed - 38)/(0.1122);
    num=m;

}

void update_compare(EPWM_INFO *epwm_info)//电机调速函数
{
        epwm_info->EPwmRegHandle->CMPB=EPWM1_TIMER_TBPRD/2 - num;
        epwm_info->EPwmRegHandle->CMPA.half.CMPA=EPWM1_TIMER_TBPRD/2 + num;
}


interrupt void xint1_isr(void)
{
    Uint32 i;
    for(i=0;i<1000000;i++);    //键盘消抖动
    while(keyon1==0);
    if(fangxiang==0)
    {
        fangxiang=1;
    }
    else if(fangxiang==1)
    {
        fangxiang=0;
    }

    bianhua();
    delay_loop_2();
    delay_loop_2();
    delay_loop_2();
    delay_loop_2();
    // 应答寄存器的位1清0,以响应同组内其他中断;
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
}


void delay_loop_2()
{
    Uint32      i;
    Uint32      j;

    for(i=0;i<40;i++)
    {
        for (j = 0; j < 100000; j++);
    }

}


void delay_loop_1()//超短时间的延时
{
        Uint32      i;
        Uint32      j;

        for(i=0;i<20;i++)
        {
            for (j = 0; j < 10000; j++);
        }
}


void InitEPwm1Example()//PWM 控制电机的 初始化
{

   // Setup TBCLK
   EPwm1Regs.TBPRD = EPWM1_TIMER_TBPRD;           // Set timer period 801 TBCLKs
   EPwm1Regs.TBPHS.half.TBPHS = 0x0000;           // Phase is 0
   EPwm1Regs.TBCTR = 0x0000;                      // Clear counter

   // Set Compare values
   EPwm1Regs.CMPA.half.CMPA = EPWM1_MIN_CMPA;     // Set compare A value
   EPwm1Regs.CMPB = EPWM1_MAX_CMPB;               // Set Compare B value

   // Setup counter mode
   EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up
   EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE;        // Disable phase loading
   EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;       // Clock ratio to SYSCLKOUT
   EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;

   // Setup shadowing
   EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
   EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
   EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;  // Load on Zero
   EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;


   // Set actions
   EPwm1Regs.AQCTLA.bit.CAU = AQ_SET;             // Set PWM1A on event A, up count
   EPwm1Regs.AQCTLA.bit.CAD = AQ_CLEAR;           // Clear PWM1A on event A, down count

   EPwm1Regs.AQCTLB.bit.CBU = AQ_SET;             // Set PWM1B on event B, up count
   EPwm1Regs.AQCTLB.bit.CBD = AQ_CLEAR;           // Clear PWM1B on event B, down count

   // Interrupt where we will change the Compare Values
   EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO;      // Select INT on Zero event
   EPwm1Regs.ETSEL.bit.INTEN = 1;                 // Enable INT
   EPwm1Regs.ETPS.bit.INTPRD = ET_3RD;            // Generate INT on 3rd event

   // Information this example uses to keep track
   // of the direction the CMPA/CMPB values are
   // moving, the min and max allowed values and
   // a pointer to the correct ePWM registers
   epwm1_info.EPwm_CMPA_Direction = EPWM_CMP_UP;   // Start by increasing CMPA &
   epwm1_info.EPwm_CMPB_Direction = EPWM_CMP_DOWN; // decreasing CMPB
   epwm1_info.EPwmTimerIntCount = 0;               // Zero the interrupt counter
   epwm1_info.EPwmRegHandle = &EPwm1Regs;          // Set the pointer to the ePWM module
   epwm1_info.EPwmMaxCMPA = EPWM1_MAX_CMPA;        // Setup min/max CMPA/CMPB values
   epwm1_info.EPwmMinCMPA = EPWM1_MIN_CMPA;
   epwm1_info.EPwmMaxCMPB = EPWM1_MAX_CMPB;
   epwm1_info.EPwmMinCMPB = EPWM1_MIN_CMPB;

}

  • 4
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值