程序功能:
1.可以通过PWM 信号的占空比 控制驱动模块的输出电压 从而控制 直流电机的转速
2.通过控制显示屏幕的 速度 控制 PWM 的输出
3.时刻显示 实测速度
4.能完成 控制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 ssss();//屏幕控制速度的显示
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"};
uchar tttt[] = {"实测速度: "};
#endif
///EQEP模块
int DirectionQep=0;
int LineEncoder=500;
int Encoder_N=2000;
unsigned int motor_speed=100;//实测速度
unsigned int motor_speed1=50;//屏幕显示的速度
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(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++;
}
if(fangxiang==0)//当我们的 改变的值是 PWM 的时候
{
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)//当我们 改变的值 是 速度 的时候
{
delay_loop_1();//这里加一个延时是为了保证 key 按键按下去的时候能够识别的到
if(KeyValue==0x0e)//1110 e//按键判断
{
if(motor_speed1<140)
{
motor_speed1+=10;
}
ssss();//改变速度的值
return_PWM();
update_compare(&epwm1_info);//改变电机的速度
kkkk();//刷新 PWM
}
delay_loop_1();//这里加一个延时是为了保证 key 按键按下去的时候能够识别的到
if(KeyValue==0x0d) //1101 13->d
{
if(motor_speed1>50)
{
motor_speed1-=10;
if(motor_speed1==90)
{
bianhua();
}
}
ssss();//改变速度的值
return_PWM();
update_compare(&epwm1_info);//改变电机的速度
kkkk();//刷新 PWM
}
delay_loop_1();
if(KeyValue==0x0b)//1011 11->b
{
if(motor_speed1<148)
{
motor_speed1+=1;
}
ssss();//改变速度的值
return_PWM();
update_compare(&epwm1_info);//改变电机的速度
kkkk();//刷新 PWM
}
delay_loop_1();
if(KeyValue==0x07)//0111 7
{
if(motor_speed1>46)
{
motor_speed1-=1;
if(motor_speed1==99)
{
bianhua();
}
}
ssss();//改变速度的值
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);//速度
if(fangxiang==0)
{
LCD_PutString(37,170,lll2, WHITE,RED);//PWM的数值
}
else
{
LCD_PutString(37,170,lll1, WHITE,RED);//速度的数值
}
LCD_PutString(37,200,tttt, WHITE,RED);//实测速度的数值
LCD_PutString(130,200,str3, 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()//只改变速度
{
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(130,200,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(130,200,str3, WHITE,RED);//PWM 的值
}
}
void ssss()//屏幕控制速度的显示
{
int n1,n2,n3;
if(motor_speed1<100)
{
uchar str3[5];
n1=motor_speed1/10;
str3[0]=n1+48;
n2=motor_speed1%10;
str3[1]=n2+48;
str3[2]=32;
str3[3]=32;
LCD_PutString(110,140,str3, WHITE,RED);//PWM 的值
}
else if(motor_speed1<1000)
{
uchar str3[5];
n1=motor_speed1/100;
str3[0]=n1+48;
n2=motor_speed1%100/10;
str3[1]=n2+48;
n3=motor_speed1%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 的值
{
if(motor_speed1<100)
{
int m=(int) (motor_speed1 - 28.34)/(0.1166)+80;
num=m;
}
else if(motor_speed1<118)
{
int m=(int) (motor_speed1 - 28.34)/(0.1166)+40;
num=m;
}
else if(motor_speed1<122)
{
int m=(int) (motor_speed1 - 28.34)/(0.1166)+30;
num=m;
}
else
{
int m=(int) (motor_speed1 - 28.34)/(0.1166);
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;
}