📄 cputimer.c
字号:
/************************************************************************************
版权(c) 2003- 北京合众达电子技术有限责任公司 *
* 设计者: 戴展波
*************************************************************************************/
#include "DSP28_Device.h"
#include "ext_inf.h"
void GetEncoder();
void ConfigQEP();
void InitialQEP();
void StartQEP();
void QEP_speed();
void QEP_angle();
interrupt void eva_timer1_isr(void);
unsigned int Delta,T1CNT0,T1CNT1,T1CNT2,T2CNT0,T2CNT1,T2CNT2;
float speed,Theta,f0,Pn,pi;
void main(void)
{
/*初始化系统*/
InitSysCtrl();
/*关中断*/
DINT;
IER = 0x0000;
IFR = 0x0000;
/*初始化PIE*/
InitPieCtrl();
/*初始化PIE中断矢量表*/
InitPieVectTable();
/*初始化外设*/
InitPeripherals();
EALLOW;
PieVectTable.T1PINT = &T1PINT_ISR;
PieVectTable.CAPINT1= &CAPINT1_ISR;
EDIS;
PieCtrl.PIEIER2.all = M_INT4;
PieCtrl.PIEIER3.all = M_INT5;
IER |= (M_INT2 | M_INT3);
EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM
GetEncoder();
}
void GetEncoder()////通过QEP 电路获得电机的转速和转动的角度
{
InitialQEP(); //初始化,打开捕捉单元1,2,4
while(EvaRegs.CAPFIFO.all ==0);//等待捕捉到码盘的上升沿
ConfigQEP();//设置QEP模式,重设定时器
StartQEP(); //开始对码盘脉冲进行捕捉
while(EvaRegs.EVAIFRA.bit.T1PINT !=1) //等待定时器T1中断
{
if (EvbRegs.CAPFIFOB.all!=0) //Z 脉冲是否到来,表明电机已经转过一圈
{
T1CNT0=EvaRegs.T1CNT;
T2CNT0=EvaRegs.T2CNT;
}
}
T1CNT2=EvaRegs.T1CNT;
T2CNT2=EvaRegs.T2CNT;
QEP_speed();//通过捕获到的脉冲数,计算码盘速度
QEP_angle();//计算码盘转过的角度
}
void QEP_speed()
{
if (T2CNT2>=T2CNT1)
{
Delta=T2CNT2-T2CNT1;
}else
{
Delta=T2CNT2-T2CNT1+0xFFFF;
}
speed=60*Delta*f0/(Pn*T1CNT2-T1CNT1);
}
void QEP_angle()
{
Theta=2*pi*(T2CNT2-T2CNT0)*f0/(Pn*T1CNT2-T1CNT0);
}
void ConfigQEP()
{
// Initialize EVA Timer 1: 定时器1用于产生采样周期 T0
// Setup Timer 1 Registers (EV A)
EvaRegs.GPTCONA.all = 0;
// Set the Period for the GP timer 1 to 0x0200;
EvaRegs.T1PR = 0x0200; // Period 设定采样时间为8-10ms
EvaRegs.T1CMPR = 0x0000; // Compare Reg
// Enable Period interrupt bits for GP timer 1
// Count up, x128, internal clk, enable compare, use own period
EvaRegs.EVAIMRA.bit.T1PINT = 0;//禁止中断标志位
EvaRegs.EVAIFRA.bit.T1PINT = 1;//复位中断标志位
// Clear the counter for GP timer 1
EvaRegs.T1CNT = 0x0000;
EvaRegs.T1CON.all = 0x1742;
// Initialize EVA Timer 2://定时器2工作在QEP的计数模式下
// Set the Period for the GP timer 2 to 0x0200;
EvaRegs.T2PR = 0x0000; // Period
EvaRegs.T2CMPR = 0x0000; // Compare Reg
// Enable Period interrupt bits for GP timer 2
// Count up, x128, internal clk, enable compare, use own period
EvaRegs.EVAIMRB.bit.T2PINT = 1;
EvaRegs.EVAIFRB.bit.T2PINT = 1;
// Clear the counter for GP timer 2
EvaRegs.T2CNT = 0x0000;
EvaRegs.T2CON.all =0x1830;
// Initialize EVB Timer 4://设置定时器3工作在捕获模式下
// Setup Timer 3 Registers (EV B)
EvbRegs.GPTCONB.all = 0;
// Set the Period for the GP timer 3 to 0x0200;
EvbRegs.T3PR = 0x1000; // Period
EvbRegs.T3CMPR = 0x0000; // Compare Reg
// Enable Period interrupt bits for GP timer 3
// Count up, x128, internal clk, enable compare, use own period
EvbRegs.EVBIMRA.bit.T3PINT = 1;
EvbRegs.EVBIFRA.bit.T3PINT = 1;
// Clear the counter for GP timer 3
EvbRegs.T3CNT = 0x0000;
EvbRegs.T3CON.all = 0x1742;
EvbRegs.CAPCONB.all=0x2240; //设定捕捉单元控制寄存器
EvbRegs.CAPFIFOB.all=0;//清除FIFO
EvbRegs.EVBIMRC.all=0x0001;//使能CAP4的中断
}
void InitialQEP() //初始化,打开捕捉单元1,2,4
{
///设置定时器一
// Setup Timer 1 Registers (EV A)
EvaRegs.GPTCONA.all = 0;
// Set the Period for the GP timer 1 to 0x0200;
EvaRegs.T1PR = 0x2000; // Period
EvaRegs.T1CMPR = 0x0000; // Compare Reg
// Enable Period interrupt bits for GP timer 1
// Count up, x128, internal clk, enable compare, use own period
EvaRegs.EVAIMRA.bit.T1PINT = 1;//复位中断标志位
EvaRegs.EVAIFRA.bit.T1PINT = 1;
// Clear the counter for GP timer 1
EvaRegs.T1CNT =0x0000;
EvaRegs.T1CON.all =0x1742;
///设置捕捉单元CAP1,CAP2 使用定时器一
EvaRegs.CAPCON.all=0xA2F0; //设定捕捉单元控制寄存器
EvaRegs.CAPFIFO.all=0x0000;//清除CAP1,CAP2 FIFO
EvaRegs.EVAIMRC.all=0x0003;//CAP1,CAP2的中断,采用查询FIFO的形式
while(1);
///设置捕捉单元四,使用定时器三
EvbRegs.CAPCONB.all=0x2240; //设定捕捉单元控制寄存器
EvbRegs.CAPFIFOB.all=0;//清除FIFO
EvbRegs.EVBIMRC.all=0x0001;//使能CAP4的中断
//设置定时器三
EvbRegs.GPTCONB.all = 0;
// Set the Period for the GP timer 3 to 0x0200;
EvbRegs.T3PR = 0x1000; // Period
EvbRegs.T3CMPR = 0x0000; // Compare Reg
// Enable Period interrupt bits for GP timer 3
// Count up, x128, internal clk, enable compare, use own period
EvbRegs.EVBIMRA.bit.T3PINT = 1;
EvbRegs.EVBIFRA.bit.T3PINT = 1;
// Clear the counter for GP timer 3
EvbRegs.T3CNT = 0x0000;
EvbRegs.T3CON.all = 0x1742;
}
void StartQEP()//启动QEP
{
T1CNT1=EvaRegs.T1CNT;
T2CNT1=EvaRegs.T2CNT;
}
interrupt void eva_timer1_isr(void)
{
// Enable more interrupts from this timer
EvaRegs.EVAIMRA.bit.T1PINT = 1;
// Note: To be safe, use a mask value to write to the entire
// EVAIFRA register. Writing to one bit will cause a read-modify-write
// operation that may have the result of writing 1's to clear
// bits other then those intended.
EvaRegs.EVAIFRA.all = BIT7;
// Acknowledge interrupt to recieve more interrupts from PIE group 2
PieCtrl.PIEACK.all = PIEACK_GROUP2;
}
//===========================================================================
// No more.
//===========================================================================
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -