DSP eCAP脉冲捕获实验

本文详细介绍了TI的F28335处理器中的eCAP模块,包括其基本原理、捕获功能在电机测速、脉冲宽度测量等领域的应用,以及APWM操作模式和硬件、软件设计实例。涵盖了eCAP配置步骤、中断服务和相关寄存器操作等内容。
摘要由CSDN通过智能技术生成

1 eCAP 介绍

  1. 1脉冲捕获的基本原理

捕获单元模块(eCAP)能够捕获外部输入引脚的逻辑状态(电平的高或者低、 低电平翻转时的上升沿或下降沿),并利用内部定时器对外部事件或者引脚状态 变化进行处理。典型应用如下:

 --电机测速。

 --测量脉冲电平宽度。

 --测量一系列脉冲占空比和周期。

 --电流/电压传感器的 PWM 编码信号的解码。

 捕获单元示意图如下:

控制器给每个捕获单元模块都分配了一个捕获引脚,在捕获引脚上输入待测 脉冲波形,捕获模块会捕获到指定捕获的逻辑状态,如上图中的下降沿,捕获单 元记录下定时器的时间,两个下降沿之间的时间差值就是脉冲周期即脉冲频率。 同理也可以捕获脉冲的上升沿,计算上升沿与下降沿之间的时间差值即可或得占 空比,因此捕获单元可以用来测量脉冲周期以及脉冲的宽度(占空比)。在一些 数字脉冲测速场合,如点击的常用测速方法之一,在电机某个固定位置通过光电 传感器发出一个脉冲,每周一个脉冲,两个脉冲之间的时间,就是电机的转速。 在一些精确控制场合中,一周当然不止发出一个脉冲,这取决与传感器(光电编 码器)的选型和性能。

  1. 2F28335 eCAP 介绍

F28335 内含有 6 组 eCAP 模块,每个 eCAP 除了具有输入捕获功能,还可通过 相关配置用作 PWM 输出功能。F28335 捕获模块的主要特征如下:

--150MHz 系统时钟的情况下,32 位的时基的时间分辨率为 6.67ns。

--4 组 32 位的时间标志寄存器。

--4 级捕获事件序列,可以灵活配置捕获事件边沿极性。

--4 级触发事件均可以产生中断。

--软件配置一次捕获可以最多得到 4 个捕获时间。

--可连续循环 4 级捕获。

--绝对时间捕获。

--不同模式的时间捕获。

--所有捕获都发生在一个输入引脚上。

--如果 eCAP 模块不作捕获使用,可以配置成一个单通道输出的 PWM 模式。 eCAP 模块中一个捕获通道完成一次捕获任务,需要以下关键资源:

--专用捕获输入引脚。

--32 位时基(计数器)。

--4*32 位时间标签捕获寄存器。

--4 级序列器,与外部 eCAP 引脚的上升/下降沿同步。

--4 个事件可独立配置边沿极性。

--输入捕获信号预定标(2~62)。

--一个 2 位的比较寄存器,一次触发后可以捕获 4 个时间标签事件。

--采用 4 级深度的循环缓冲器以进行连续捕获。

--4 个捕获事件中任意一个都可以产生中断。

1.3 F28335 捕获单元与 APWM 操作模式

(1)APWM 操作模式

如果 eCAP 模块不用作输入捕获,可以将它用来产生一个单通道的 PWM。计数 器工作在计数增模式,可以提供时基能产生不同占空比的 PWM。CAP1 与 CAP2 寄 存器作为主要的周期和比较寄存器,CAP3 与 CAP4 寄存器作为周期和比较寄存器 的影子寄存器,其原理框图如下:

 

(2)F28335 捕获操作模式

F28335 DSP 中 eCAP 的原理框图如下:

 

1.4 CAP 相关寄存器

CAP 所有寄存器及地址信息如下所示:

 2 eCAP 配置步骤

前面介绍了非常多的理论知识,对于初学者来说可能有点懵,没关系,我们

可以先从软件层面来学习,先学会如何使用,再深入学习理论。接下来我们就来

学习如何配置 F28355 的 eCAP1,至于其他 eCAP 配置方法一样,只需修改数字即 可。具体步骤如下:

(1)使能 eCAP 外设时钟

要使用 eCAP 外设则需开启相应时钟,开启 eCAP 外设时钟代码如下:

EALLOW;

SysCtrlRegs.PCLKCR1.bit.ECAP1ENCLK = 1; // eCAP1

EDIS;

(2)初始化 GPIO 为 eCAP1 功能,即选择 GPIO 复用功能

eCAP1 的 GPIO 初始化函数如下:

void InitECap1Gpio(void); 

本章实验例程内使用的 eCAP1 对应的是 GPIO24 脚

(3)eCAP 外设相关参数设置,包括捕捉模式、捕获边沿信号、捕获后计数

器是否清零、捕获中断等。

要想使用 eCAP 捕获输入信号,除了使能 eCAP 时钟和配置 GPIO 外,还需要

对其进行寄存器相关参数的设置。比如捕捉模式、捕获边沿信号、捕获后计数器

是否清零、捕获中断等。下面我们就以本章 eCAP 和初始化配置为例进行介绍,

我们开发板上使用的是 eCAP1。代码如下:

ECap1Regs.ECEINT.all = 0x0000;// Disable all capture interrupts
ECap1Regs.ECCLR.all = 0xFFFF;// Clear all CAP interrupt flags
ECap1Regs.ECCTL1.bit.CAPLDEN = 0;// Disable CAP1-CAP4 register loads
ECap1Regs.ECCTL2.bit.TSCTRSTOP = 0;// Make sure the counteris stopped

// Configure peripheral registers
ECap1Regs.ECCTL2.bit.CONT_ONESHT = 1;// One-shot
ECap1Regs.ECCTL2.bit.STOP_WRAP = 3;// Stop at 4 events
ECap1Regs.ECCTL1.bit.CAP1POL = 1;// Falling edge
ECap1Regs.ECCTL1.bit.CAP2POL = 0;// Rising edge
ECap1Regs.ECCTL1.bit.CAP3POL = 1;// Falling edge
ECap1Regs.ECCTL1.bit.CAP4POL = 0;// Rising edge
ECap1Regs.ECCTL1.bit.CTRRST1 = 1;// Difference operation
ECap1Regs.ECCTL1.bit.CTRRST2 = 1;// Difference operation
ECap1Regs.ECCTL1.bit.CTRRST3 = 1;// Difference operation
ECap1Regs.ECCTL1.bit.CTRRST4 = 1;// Difference operation
ECap1Regs.ECCTL2.bit.SYNCI_EN = 1;// Enable sync in
ECap1Regs.ECCTL2.bit.SYNCO_SEL = 0;// Pass through
ECap1Regs.ECCTL1.bit.CAPLDEN = 1;// Enable capture units
ECap1Regs.ECCTL2.bit.TSCTRSTOP = 1;// Start Counter
ECap1Regs.ECCTL2.bit.REARM = 1;// arm one-shot
ECap1Regs.ECCTL1.bit.CAPLDEN = 1;// Enable CAP1-CAP4 register loads
ECap1Regs.ECEINT.bit.CEVT4 = 1;// 4 events = interrupt

EALLOW; // This is needed to write to EALLOW protected registers
PieVectTable.ECAP1_INT = &ecap1_isr;
EDIS;

// This is needed to disable write to EALLOW protected registers
// Enable CPU INT4 which is connected to ECAP1-4 INT:
IER |= M_INT4;
// Enable eCAP INTn in the PIE: Group 3 interrupt 1-6
PieCtrlRegs.PIEIER4.bit.INTx1 = 1;
// Enable global Interrupts and higher priority real-time debug events:

EINT;// Enable Global interrupt INTM
ERTM;// Enable Global realtime interrupt DBGM

上述代码是 eCAP1 的设置,如果你使用的是其他 eCAP,那么只需要修改数字

即可。本章例程开启了 eCAP1 的中断功能,而 eCAP1 它连接在 INT4.1,所以需要对它进行使能以及中断向量表的指定,这个在前面中断章节介绍过。

(4)编写中断函数。

通过前面的配置已使能了 eCAP1 的中断,当 eCAP1 连续捕获到 4 次边沿信号

时即进入中断,因此需要编写一个中断服务函数,函数名要与前面指定的中断向

量名一致,中断函数执行完后需要清除相关中断标志。

3 硬件设计

本实验使用到硬件资源如下:

(1)D1 指示灯

(2)ePWM5A

(3)eCAP1

4 软件设计

(1)eCAP_Capture_pwm

// Configure the start/end period for the timer
#define PWM3_TIMER_MIN     10
#define PWM3_TIMER_MAX     8000

// To keep track of which way the timer value is moving
#define EPWM_TIMER_UP   1
#define EPWM_TIMER_DOWN 0

void EPWM3_Init(Uint16 tbprd);


// Configure the start/end period for the timer
#define PWM5_TIMER_MIN     10
#define PWM5_TIMER_MAX     8000

 

// TBCTL (Time-Base Control)
//==========================
// CTRMODE bits
#define	TB_COUNT_UP		0x0
#define	TB_COUNT_DOWN	0x1
#define	TB_COUNT_UPDOWN	0x2
#define	TB_FREEZE		0x3
// PHSEN bit
#define	TB_DISABLE		0x0
#define	TB_ENABLE		0x1
// PRDLD bit
#define	TB_SHADOW		0x0
#define	TB_IMMEDIATE	0x1
// SYNCOSEL bits
#define	TB_SYNC_IN		0x0
#define	TB_CTR_ZERO		0x1
#define	TB_CTR_CMPB		0x2
#define	TB_SYNC_DISABLE	0x3
// HSPCLKDIV and CLKDIV bits
#define	TB_DIV1			0x0
#define	TB_DIV2			0x1
#define	TB_DIV4			0x2
// PHSDIR bit
#define	TB_DOWN			0x0
#define	TB_UP			0x1

// CMPCTL (Compare Control)
//==========================
// LOADAMODE and LOADBMODE bits
#define	CC_CTR_ZERO		0x0
#define	CC_CTR_PRD		0x1
#define	CC_CTR_ZERO_PRD	0x2
#define	CC_LD_DISABLE	0x3
// SHDWAMODE and SHDWBMODE bits
#define	CC_SHADOW		0x0
#define	CC_IMMEDIATE	0x1

// AQCTLA and AQCTLB (Action Qualifier Control)
//=============================================
// ZRO, PRD, CAU, CAD, CBU, CBD bits
#define	AQ_NO_ACTION	0x0
#define	AQ_CLEAR		0x1
#define	AQ_SET			0x2
#define	AQ_TOGGLE		0x3

// DBCTL (Dead-Band Control)
//==========================
// OUT MODE bits
#define	DB_DISABLE		0x0
#define	DBA_ENABLE		0x1
#define	DBB_ENABLE		0x2
#define	DB_FULL_ENABLE	0x3
// POLSEL bits
#define	DB_ACTV_HI		0x0
#define	DB_ACTV_LOC		0x1
#define	DB_ACTV_HIC		0x2
#define	DB_ACTV_LO		0x3
// IN MODE
#define DBA_ALL         0x0
#define DBB_RED_DBA_FED 0x1
#define DBA_RED_DBB_FED 0x2
#define DBB_ALL         0x3

// CHPCTL (chopper control)
//==========================
// CHPEN bit
#define	CHP_DISABLE		0x0
#define	CHP_ENABLE		0x1
// CHPFREQ bits
#define	CHP_DIV1		0x0
#define	CHP_DIV2		0x1
#define	CHP_DIV3		0x2
#define	CHP_DIV4		0x3
#define	CHP_DIV5		0x4
#define	CHP_DIV6		0x5
#define	CHP_DIV7		0x6
#define	CHP_DIV8		0x7
// CHPDUTY bits
#define	CHP1_8TH		0x0
#define	CHP2_8TH		0x1
#define	CHP3_8TH		0x2
#define	CHP4_8TH		0x3
#define	CHP5_8TH		0x4
#define	CHP6_8TH		0x5
#define	CHP7_8TH		0x6

// TZSEL (Trip Zone Select)
//==========================
// CBCn and OSHTn bits
#define	TZ_DISABLE		0x0
#define	TZ_ENABLE		0x1

// TZCTL (Trip Zone Control)
//==========================
// TZA and TZB bits
#define	TZ_HIZ			0x0
#define	TZ_FORCE_HI		0x1
#define	TZ_FORCE_LO		0x2
#define	TZ_NO_CHANGE	0x3

// ETSEL (Event Trigger Select)
//=============================
#define	ET_CTR_ZERO		0x1
#define	ET_CTR_PRD		0x2
#define	ET_CTRU_CMPA	0x4
#define	ET_CTRD_CMPA	0x5
#define	ET_CTRU_CMPB	0x6
#define	ET_CTRD_CMPB	0x7

// ETPS (Event Trigger Pre-scale)
//===============================
// INTPRD, SOCAPRD, SOCBPRD bits
#define	ET_DISABLE		0x0
#define	ET_1ST			0x1
#define	ET_2ND			0x2
#define	ET_3RD			0x3


//--------------------------------
// HRPWM (High Resolution PWM)
//================================
// HRCNFG
#define	HR_Disable		0x0
#define	HR_REP			0x1
#define	HR_FEP			0x2
#define	HR_BEP			0x3

#define	HR_CMP			0x0
#define	HR_PHS			0x1

#define	HR_CTR_ZERO		0x0
#define	HR_CTR_PRD		0x1

 

void InitECap1Gpio(void)
{
   EALLOW;
/* Enable internal pull-up for the selected pins */
// Pull-ups can be enabled or disabled by the user.
// This will enable the pullups for the specified pins.
// Comment out other unwanted lines.

// GpioCtrlRegs.GPAPUD.bit.GPIO5 = 0;      // Enable pull-up on GPIO5 (CAP1)
   GpioCtrlRegs.GPAPUD.bit.GPIO24 = 0;     // Enable pull-up on GPIO24 (CAP1)
// GpioCtrlRegs.GPBPUD.bit.GPIO34 = 0;     // Enable pull-up on GPIO34 (CAP1)


// Inputs are synchronized to SYSCLKOUT by default.
// Comment out other unwanted lines.

// GpioCtrlRegs.GPAQSEL1.bit.GPIO5 = 0;    // Synch to SYSCLKOUT GPIO5 (CAP1)
   GpioCtrlRegs.GPAQSEL2.bit.GPIO24 = 0;   // Synch to SYSCLKOUT GPIO24 (CAP1)
// GpioCtrlRegs.GPBQSEL1.bit.GPIO34 = 0;   // Synch to SYSCLKOUT GPIO34 (CAP1)

/* Configure eCAP-1 pins using GPIO regs*/
// This specifies which of the possible GPIO pins will be eCAP1 functional pins.
// Comment out other unwanted lines.

// GpioCtrlRegs.GPAMUX1.bit.GPIO5 = 3;     // Configure GPIO5 as CAP1
   GpioCtrlRegs.GPAMUX2.bit.GPIO24 = 1;    // Configure GPIO24 as CAP1
// GpioCtrlRegs.GPBMUX1.bit.GPIO34 = 1;    // Configure GPIO24 as CAP1

    EDIS;
}

void eCAP1_Init(void)
{
	EALLOW;
	SysCtrlRegs.PCLKCR1.bit.ECAP1ENCLK = 1;  // eCAP1
	EDIS;

	InitECap1Gpio();

	ECap1Regs.ECEINT.all = 0x0000;             // Disable all capture interrupts
	ECap1Regs.ECCLR.all = 0xFFFF;              // Clear all CAP interrupt flags
	ECap1Regs.ECCTL1.bit.CAPLDEN = 0;          // Disable CAP1-CAP4 register loads
	ECap1Regs.ECCTL2.bit.TSCTRSTOP = 0;        // Make sure the counter is stopped

	// Configure peripheral registers
	ECap1Regs.ECCTL2.bit.CONT_ONESHT = 1;      // One-shot
	ECap1Regs.ECCTL2.bit.STOP_WRAP = 3;        // Stop at 4 events
	ECap1Regs.ECCTL1.bit.CAP1POL = 1;          // Falling edge
	ECap1Regs.ECCTL1.bit.CAP2POL = 0;          // Rising edge
	ECap1Regs.ECCTL1.bit.CAP3POL = 1;          // Falling edge
	ECap1Regs.ECCTL1.bit.CAP4POL = 0;          // Rising edge
	ECap1Regs.ECCTL1.bit.CTRRST1 = 1;          // Difference operation
	ECap1Regs.ECCTL1.bit.CTRRST2 = 1;          // Difference operation
	ECap1Regs.ECCTL1.bit.CTRRST3 = 1;          // Difference operation
	ECap1Regs.ECCTL1.bit.CTRRST4 = 1;          // Difference operation
	ECap1Regs.ECCTL2.bit.SYNCI_EN = 1;         // Enable sync in
	ECap1Regs.ECCTL2.bit.SYNCO_SEL = 0;        // Pass through
	ECap1Regs.ECCTL1.bit.CAPLDEN = 1;          // Enable capture units


	ECap1Regs.ECCTL2.bit.TSCTRSTOP = 1;        // Start Counter
	ECap1Regs.ECCTL2.bit.REARM = 1;            // arm one-shot
	ECap1Regs.ECCTL1.bit.CAPLDEN = 1;          // Enable CAP1-CAP4 register loads
	ECap1Regs.ECEINT.bit.CEVT4 = 1;            // 4 events = interrupt

	EALLOW;  // This is needed to write to EALLOW protected registers
	PieVectTable.ECAP1_INT = &ecap1_isr;
	EDIS;    // This is needed to disable write to EALLOW protected registers

	// Enable CPU INT4 which is connected to ECAP1-4 INT:
	IER |= M_INT4;
	// Enable eCAP INTn in the PIE: Group 3 interrupt 1-6
	PieCtrlRegs.PIEIER4.bit.INTx1 = 1;

	// Enable global Interrupts and higher priority real-time debug events:
	EINT;   // Enable Global interrupt INTM
	ERTM;   // Enable Global realtime interrupt DBGM
}

__interrupt void ecap1_isr(void)
{
   // Cap input is syc'ed to SYSCLKOUT so there may be
   // a +/- 1 cycle variation

   if(ECap1Regs.CAP2 > EPwm5Regs.TBPRD*2+1 || ECap1Regs.CAP2 < EPwm5Regs.TBPRD*2-1)
   {
       Fail();
   }

   if(ECap1Regs.CAP3 > EPwm5Regs.TBPRD*2+1 || ECap1Regs.CAP3 < EPwm5Regs.TBPRD*2-1)
   {
       Fail();
   }

   if(ECap1Regs.CAP4 > EPwm5Regs.TBPRD*2+1 || ECap1Regs.CAP4 < EPwm5Regs.TBPRD*2-1)
   {
       Fail();
   }

   ECap1IntCount++;

   if(EPwm5TimerDirection == EPWM_TIMER_UP)
   {
		if(EPwm5Regs.TBPRD < PWM5_TIMER_MAX)
		{
		   EPwm5Regs.TBPRD++;
		}
		else
		{
		   EPwm5TimerDirection = EPWM_TIMER_DOWN;
		   EPwm5Regs.TBPRD--;
		}
   }
   else
   {
        if(EPwm5Regs.TBPRD > PWM5_TIMER_MIN)
        {
           EPwm5Regs.TBPRD--;
        }
        else
        {
           EPwm5TimerDirection = EPWM_TIMER_UP;
           EPwm5Regs.TBPRD++;
        }
   }

   ECap1PassCount++;

   ECap1Regs.ECCLR.bit.CEVT4 = 1;
   ECap1Regs.ECCLR.bit.INT = 1;
   ECap1Regs.ECCTL2.bit.REARM = 1;

   // Acknowledge this interrupt to receive more interrupts from group 4
   PieCtrlRegs.PIEACK.all = PIEACK_GROUP4;
}

void Fail()
{
    __asm("   ESTOP0");
}
void main()
{
	Uint16 i=0;


	InitSysCtrl();
	InitPieCtrl();
	IER = 0x0000;
	IFR = 0x0000;
	InitPieVectTable();

	LED_Init();
	TIM0_Init(150,200000);//200ms
	UARTa_Init(4800);

	EPWM5_Init(PWM5_TIMER_MIN);
	eCAP1_Init();

	while(1)
	{

	}
}

(2)eCAP_apwm

void InitECap1Gpio(void)
{
   EALLOW;
/* Enable internal pull-up for the selected pins */
// Pull-ups can be enabled or disabled by the user.
// This will enable the pullups for the specified pins.
// Comment out other unwanted lines.

// GpioCtrlRegs.GPAPUD.bit.GPIO5 = 0;      // Enable pull-up on GPIO5 (CAP1)
   GpioCtrlRegs.GPAPUD.bit.GPIO24 = 0;     // Enable pull-up on GPIO24 (CAP1)
// GpioCtrlRegs.GPBPUD.bit.GPIO34 = 0;     // Enable pull-up on GPIO34 (CAP1)


// Inputs are synchronized to SYSCLKOUT by default.
// Comment out other unwanted lines.

// GpioCtrlRegs.GPAQSEL1.bit.GPIO5 = 0;    // Synch to SYSCLKOUT GPIO5 (CAP1)
   GpioCtrlRegs.GPAQSEL2.bit.GPIO24 = 0;   // Synch to SYSCLKOUT GPIO24 (CAP1)
// GpioCtrlRegs.GPBQSEL1.bit.GPIO34 = 0;   // Synch to SYSCLKOUT GPIO34 (CAP1)

/* Configure eCAP-1 pins using GPIO regs*/
// This specifies which of the possible GPIO pins will be eCAP1 functional pins.
// Comment out other unwanted lines.

// GpioCtrlRegs.GPAMUX1.bit.GPIO5 = 3;     // Configure GPIO5 as CAP1
   GpioCtrlRegs.GPAMUX2.bit.GPIO24 = 1;    // Configure GPIO24 as CAP1
// GpioCtrlRegs.GPBMUX1.bit.GPIO34 = 1;    // Configure GPIO24 as CAP1

    EDIS;
}

void eCAP1_APWM_Init(void)
{
	EALLOW;
	SysCtrlRegs.PCLKCR1.bit.ECAP1ENCLK = 1;  // eCAP1
	EDIS;

	InitECap1Gpio();

	// Setup APWM mode on CAP1, set period and compare registers
	ECap1Regs.ECCTL2.bit.CAP_APWM = 1;	// Enable APWM mode
	ECap1Regs.CAP1 = 0x01312D00;			// Set Period value
	ECap1Regs.CAP2 = 0x00989680;			// Set Compare value
	ECap1Regs.ECCLR.all = 0x0FF;			// Clear pending interrupts
	ECap1Regs.ECEINT.bit.CTR_EQ_CMP = 1; // enable Compare Equal Int

	// Start counters
	ECap1Regs.ECCTL2.bit.TSCTRSTOP = 1;

}

 

// Global variables
Uint16 direction = 0;

/*******************************************************************************
* 函 数 名         : main
* 函数功能		   : 主函数
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
void main()
{
	Uint16 i=0;


	InitSysCtrl();
	InitPieCtrl();
	IER = 0x0000;
	IFR = 0x0000;
	InitPieVectTable();

	LED_Init();
	TIM0_Init(150,200000);//200ms
	UARTa_Init(4800);

	eCAP1_APWM_Init();

	while(1)
	{
		// set next duty cycle to 50%
		ECap1Regs.CAP4 = ECap1Regs.CAP1 >> 1;

		// vary freq between 7.5 Hz and 15 Hz (for 150MHz SYSCLKOUT) 5 Hz and 10 Hz (for 100 MHz SYSCLKOUT)
		if(ECap1Regs.CAP1 >= 0x01312D00)
		{
			direction = 0;
		}
		else if (ECap1Regs.CAP1 <= 0x00989680)
		{
			direction = 1;
		}

		if(direction == 0)
		{
			ECap1Regs.CAP3 = ECap1Regs.CAP1 - 500000;
		}
		else
		{
			ECap1Regs.CAP3 = ECap1Regs.CAP1 + 500000;
		}
	}
}

(3)eQEP_freqcal

FREQCAL freq=FREQCAL_DEFAULTS;

interrupt void prdTick(void);


#if (CPU_FRQ_150MHZ)
  #define CPU_CLK   150e6
#endif
#if (CPU_FRQ_100MHZ)
  #define CPU_CLK   100e6
#endif
#define PWM_CLK   5e3                 // If diff freq. desired, change freq here.
#define SP        CPU_CLK/(2*PWM_CLK)
#define TBCTLVAL  0x200E              // Up-down cnt, timebase = SYSCLKOUT


void EPwm1Setup(void)
{
    InitEPwm1Gpio();
    EPwm1Regs.TBSTS.all=0;
    EPwm1Regs.TBPHS.half.TBPHS=0;
    EPwm1Regs.TBCTR=0;

    EPwm1Regs.CMPCTL.all=0x50;        // Immediate mode for CMPA and CMPB
    EPwm1Regs.CMPA.half.CMPA =SP/2;
    EPwm1Regs.CMPB=0;

    EPwm1Regs.AQCTLA.all=0x60;        // EPWMxA = 1 when CTR=CMPA and counter inc
                                      // EPWMxA = 0 when CTR=CMPA and counter dec
    EPwm1Regs.AQCTLB.all=0;
    EPwm1Regs.AQSFRC.all=0;
    EPwm1Regs.AQCSFRC.all=0;

    EPwm1Regs.DBCTL.all=0xb;          // EPWMxB is inverted
    EPwm1Regs.DBRED=0;
    EPwm1Regs.DBFED=0;

    EPwm1Regs.TZSEL.all=0;
    EPwm1Regs.TZCTL.all=0;
    EPwm1Regs.TZEINT.all=0;
    EPwm1Regs.TZFLG.all=0;
    EPwm1Regs.TZCLR.all=0;
    EPwm1Regs.TZFRC.all=0;

    EPwm1Regs.ETSEL.all=9;            // Interrupt when TBCTR = 0x0000
    EPwm1Regs.ETPS.all=1;              // Interrupt on first event
    EPwm1Regs.ETFLG.all=0;
    EPwm1Regs.ETCLR.all=0;
    EPwm1Regs.ETFRC.all=0;

    EPwm1Regs.PCCTL.all=0;

    EPwm1Regs.TBCTL.all=0x0010+TBCTLVAL;            // Enable Timer
    EPwm1Regs.TBPRD=SP;

    EALLOW;  // This is needed to write to EALLOW protected registers
    PieVectTable.EPWM1_INT= &prdTick;
    EDIS;

    IER |= M_INT3;
    PieCtrlRegs.PIEIER3.bit.INTx1 = 1;
    EINT;   // Enable Global interrupt INTM
    ERTM;   // Enable Global realtime interrupt DBGM

}


void EQEP1_Init(void)
{
    EALLOW;  // This is needed to write to EALLOW protected registers
    SysCtrlRegs.PCLKCR1.bit.EQEP1ENCLK = 1;  // eQEP1
    EDIS;

    InitEQep1Gpio();

    EPwm1Setup();

    freq.init();   // Initializes eQEP for frequency calculation in
                        // FREQCAL_Init(void)function in Example_EPwmSetup.c
}

interrupt void prdTick(void) // Interrupts once per ePWM period
{
   freq.calc(&freq); // Checks for event and calculates frequency in FREQCAL_Calc(FREQCAL *p)
                     // function in Example_EPwmSetup.c
   // Acknowledge this interrupt to receive more interrupts from group 1
   PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;
   EPwm1Regs.ETCLR.bit.INT=1;
}
void main()
{
	Uint16 i=0;


	InitSysCtrl();
	InitPieCtrl();
	IER = 0x0000;
	IFR = 0x0000;
	InitPieVectTable();

	LED_Init();
	TIM0_Init(150,200000);//200ms
	UARTa_Init(4800);

	EQEP1_Init();

	while(1)
	{

	}
}

(4)eQEP_pos_speed

/*-----------------------------------------------------------------------------
Define the structure of the POSSPEED Object 
-----------------------------------------------------------------------------*/
typedef struct {int theta_elec;     	// Output: Motor Electrical angle (Q15)  
                int theta_mech;     	// Output: Motor Mechanical Angle (Q15) 
                int DirectionQep;      	// Output: Motor rotation direction (Q0) 
                int QEP_cnt_idx; 	 	// Variable: Encoder counter index (Q0)
                int theta_raw;     		// Variable: Raw angle from Timer 2 (Q0)            
                int mech_scaler;    	// Parameter: 0.9999/total count, total count = 4000 (Q26)
                int pole_pairs;     	// Parameter: Number of pole pairs (Q0) 
                int cal_angle;     		// Parameter: Raw angular offset between encoder and phase a (Q0) 
                int index_sync_flag; 	// Output: Index sync status (Q0)                   

                Uint32 SpeedScaler;     // Parameter :  Scaler converting 1/N cycles to a GLOBAL_Q speed (Q0) - independently with global Q
                _iq Speed_pr;           // Output :  speed in per-unit
                Uint32 BaseRpm;         // Parameter : Scaler converting GLOBAL_Q speed to rpm (Q0) speed - independently with global Q
                int32 SpeedRpm_pr;      // Output : speed in r.p.m. (Q0) - independently with global Q                               

                _iq  oldpos;  			// Input: Electrical angle (pu) 
                _iq Speed_fr;           // Output :  speed in per-unit
                int32 SpeedRpm_fr;     	// Output : Speed in rpm  (Q0) - independently with global Q
                void (*init)();     	// Pointer to the init funcion          
                void (*calc)();    		// Pointer to the calc funtion        
                }  POSSPEED;

POSSPEED qep_posspeed=POSSPEED_DEFAULTS;
Uint16 Interrupt_Count = 0;

interrupt void prdTick(void);


#if (CPU_FRQ_150MHZ)
  #define CPU_CLK   150e6
#endif
#if (CPU_FRQ_100MHZ)
  #define CPU_CLK   100e6
#endif

#define PWM_CLK   5e3              // 5kHz (300rpm) EPWM1 frequency. Freq. can be changed here
#define SP        CPU_CLK/(2*PWM_CLK)
#define TBCTLVAL  0x200E           // up-down count, timebase=SYSCLKOUT


void EPwm1Setup(void)
{
    InitEPwm1Gpio();

    EALLOW;
	GpioCtrlRegs.GPADIR.bit.GPIO4 = 1;    // GPIO4 as output simulates Index signal
	GpioDataRegs.GPACLEAR.bit.GPIO4 = 1;  // Normally low
	EDIS;

	EPwm1Regs.TBSTS.all=0;
	EPwm1Regs.TBPHS.half.TBPHS =0;
	EPwm1Regs.TBCTR=0;

	EPwm1Regs.CMPCTL.all=0x50;     // immediate mode for CMPA and CMPB
	EPwm1Regs.CMPA.half.CMPA=SP/2;
	EPwm1Regs.CMPB=0;

	EPwm1Regs.AQCTLA.all=0x60;     // CTR=CMPA when inc->EPWM1A=1, when dec->EPWM1A=0
	EPwm1Regs.AQCTLB.all=0x09;     // CTR=PRD ->EPWM1B=1, CTR=0 ->EPWM1B=0
	EPwm1Regs.AQSFRC.all=0;
	EPwm1Regs.AQCSFRC.all=0;

	EPwm1Regs.TZSEL.all=0;
	EPwm1Regs.TZCTL.all=0;
	EPwm1Regs.TZEINT.all=0;
	EPwm1Regs.TZFLG.all=0;
	EPwm1Regs.TZCLR.all=0;
	EPwm1Regs.TZFRC.all=0;

	EPwm1Regs.ETSEL.all=0x0A;      // Interrupt on PRD
	EPwm1Regs.ETPS.all=1;
	EPwm1Regs.ETFLG.all=0;
	EPwm1Regs.ETCLR.all=0;
	EPwm1Regs.ETFRC.all=0;

	EPwm1Regs.PCCTL.all=0;

	EPwm1Regs.TBCTL.all=0x0010+TBCTLVAL; // Enable Timer
	EPwm1Regs.TBPRD=SP;

	EALLOW;  // This is needed to write to EALLOW protected registers
	PieVectTable.EPWM1_INT= &prdTick;
	EDIS;

	IER |= M_INT3;
	PieCtrlRegs.PIEIER3.bit.INTx1 = 1;
	EINT;   // Enable Global interrupt INTM
	ERTM;   // Enable Global realtime interrupt DBGM

}


void InitEQep1Gpio(void)
{
   EALLOW;

/* Enable internal pull-up for the selected pins */
// Pull-ups can be enabled or disabled by the user.
// This will enable the pullups for the specified pins.
// Comment out other unwanted lines.

//    GpioCtrlRegs.GPAPUD.bit.GPIO20 = 0;   // Enable pull-up on GPIO20 (EQEP1A)
//    GpioCtrlRegs.GPAPUD.bit.GPIO21 = 0;   // Enable pull-up on GPIO21 (EQEP1B)
//    GpioCtrlRegs.GPAPUD.bit.GPIO22 = 0;   // Enable pull-up on GPIO22 (EQEP1S)
//    GpioCtrlRegs.GPAPUD.bit.GPIO23 = 0;   // Enable pull-up on GPIO23 (EQEP1I)

    GpioCtrlRegs.GPBPUD.bit.GPIO50 = 0;   // Enable pull-up on GPIO50 (EQEP1A)
    GpioCtrlRegs.GPBPUD.bit.GPIO51 = 0;   // Enable pull-up on GPIO51 (EQEP1B)
    GpioCtrlRegs.GPBPUD.bit.GPIO52 = 0;   // Enable pull-up on GPIO52 (EQEP1S)
    GpioCtrlRegs.GPBPUD.bit.GPIO53 = 0;   // Enable pull-up on GPIO53 (EQEP1I)


// Inputs are synchronized to SYSCLKOUT by default.
// Comment out other unwanted lines.

//    GpioCtrlRegs.GPAQSEL2.bit.GPIO20 = 0;   // Sync to SYSCLKOUT GPIO20 (EQEP1A)
//    GpioCtrlRegs.GPAQSEL2.bit.GPIO21 = 0;   // Sync to SYSCLKOUT GPIO21 (EQEP1B)
//    GpioCtrlRegs.GPAQSEL2.bit.GPIO22 = 0;   // Sync to SYSCLKOUT GPIO22 (EQEP1S)
//    GpioCtrlRegs.GPAQSEL2.bit.GPIO23 = 0;   // Sync to SYSCLKOUT GPIO23 (EQEP1I)

    GpioCtrlRegs.GPBQSEL2.bit.GPIO50 = 0;   // Sync to SYSCLKOUT GPIO50 (EQEP1A)
    GpioCtrlRegs.GPBQSEL2.bit.GPIO51 = 0;   // Sync to SYSCLKOUT GPIO51 (EQEP1B)
    GpioCtrlRegs.GPBQSEL2.bit.GPIO52 = 0;   // Sync to SYSCLKOUT GPIO52 (EQEP1S)
    GpioCtrlRegs.GPBQSEL2.bit.GPIO53 = 0;   // Sync to SYSCLKOUT GPIO53 (EQEP1I)

/* Configure eQEP-1 pins using GPIO regs*/
// This specifies which of the possible GPIO pins will be eQEP1 functional pins.
// Comment out other unwanted lines.

//    GpioCtrlRegs.GPAMUX2.bit.GPIO20 = 1;   // Configure GPIO20 as EQEP1A
//    GpioCtrlRegs.GPAMUX2.bit.GPIO21 = 1;   // Configure GPIO21 as EQEP1B
//    GpioCtrlRegs.GPAMUX2.bit.GPIO22 = 1;   // Configure GPIO22 as EQEP1S
//    GpioCtrlRegs.GPAMUX2.bit.GPIO23 = 1;   // Configure GPIO23 as EQEP1I

    GpioCtrlRegs.GPBMUX2.bit.GPIO50 = 1;   // Configure GPIO50 as EQEP1A
    GpioCtrlRegs.GPBMUX2.bit.GPIO51 = 1;   // Configure GPIO51 as EQEP1B
    GpioCtrlRegs.GPBMUX2.bit.GPIO52 = 1;   // Configure GPIO52 as EQEP1S
    GpioCtrlRegs.GPBMUX2.bit.GPIO53 = 1;   // Configure GPIO53 as EQEP1I


    EDIS;
}

void InitEPwm1Gpio(void)
{
   EALLOW;
   
/* Enable internal pull-up for the selected pins */
// Pull-ups can be enabled or disabled by the user. 
// This will enable the pullups for the specified pins.
// Comment out other unwanted lines.

    GpioCtrlRegs.GPAPUD.bit.GPIO0 = 0;    // Enable pull-up on GPIO0 (EPWM1A)
    GpioCtrlRegs.GPAPUD.bit.GPIO1 = 0;    // Enable pull-up on GPIO1 (EPWM1B)   
   
/* Configure ePWM-1 pins using GPIO regs*/
// This specifies which of the possible GPIO pins will be ePWM1 functional pins.
// Comment out other unwanted lines.

    GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 1;   // Configure GPIO0 as EPWM1A
    GpioCtrlRegs.GPAMUX1.bit.GPIO1 = 1;   // Configure GPIO1 as EPWM1B
   
    EDIS;
}
void EPwm1Setup(void)
{
    InitEPwm1Gpio();

    EALLOW;
	GpioCtrlRegs.GPADIR.bit.GPIO4 = 1;    // GPIO4 as output simulates Index signal
	GpioDataRegs.GPACLEAR.bit.GPIO4 = 1;  // Normally low
	EDIS;

	EPwm1Regs.TBSTS.all=0;
	EPwm1Regs.TBPHS.half.TBPHS =0;
	EPwm1Regs.TBCTR=0;

	EPwm1Regs.CMPCTL.all=0x50;     // immediate mode for CMPA and CMPB
	EPwm1Regs.CMPA.half.CMPA=SP/2;
	EPwm1Regs.CMPB=0;

	EPwm1Regs.AQCTLA.all=0x60;     // CTR=CMPA when inc->EPWM1A=1, when dec->EPWM1A=0
	EPwm1Regs.AQCTLB.all=0x09;     // CTR=PRD ->EPWM1B=1, CTR=0 ->EPWM1B=0
	EPwm1Regs.AQSFRC.all=0;
	EPwm1Regs.AQCSFRC.all=0;

	EPwm1Regs.TZSEL.all=0;
	EPwm1Regs.TZCTL.all=0;
	EPwm1Regs.TZEINT.all=0;
	EPwm1Regs.TZFLG.all=0;
	EPwm1Regs.TZCLR.all=0;
	EPwm1Regs.TZFRC.all=0;

	EPwm1Regs.ETSEL.all=0x0A;      // Interrupt on PRD
	EPwm1Regs.ETPS.all=1;
	EPwm1Regs.ETFLG.all=0;
	EPwm1Regs.ETCLR.all=0;
	EPwm1Regs.ETFRC.all=0;

	EPwm1Regs.PCCTL.all=0;

	EPwm1Regs.TBCTL.all=0x0010+TBCTLVAL; // Enable Timer
	EPwm1Regs.TBPRD=SP;

	EALLOW;  // This is needed to write to EALLOW protected registers
	PieVectTable.EPWM1_INT= &prdTick;
	EDIS;

	IER |= M_INT3;
	PieCtrlRegs.PIEIER3.bit.INTx1 = 1;
	EINT;   // Enable Global interrupt INTM
	ERTM;   // Enable Global realtime interrupt DBGM

}

void EQEP1_Init(void)
{
	EALLOW;  // This is needed to write to EALLOW protected registers
	SysCtrlRegs.PCLKCR1.bit.EQEP1ENCLK = 1;  // eQEP1
	EDIS;

	InitEQep1Gpio();

	EPwm1Setup();

	qep_posspeed.init(&qep_posspeed);
}

interrupt void prdTick(void)                  // EPWM1 Interrupts once every 4 QCLK counts (one period)
{
	Uint16 i;
	// Position and Speed measurement
	qep_posspeed.calc(&qep_posspeed);

	// Control loop code for position control & Speed contol
	Interrupt_Count++;
	if (Interrupt_Count==1000)                 // Every 1000 interrupts(4000 QCLK counts or 1 rev.)
	{
		EALLOW;
		GpioDataRegs.GPASET.bit.GPIO4 = 1;     // Pulse Index signal  (1 pulse/rev.)
		for (i=0; i<700; i++){
	}
	GpioDataRegs.GPACLEAR.bit.GPIO4 = 1;
	Interrupt_Count = 0;                   // Reset count
	EDIS;
	}

	// Acknowledge this interrupt to receive more interrupts from group 1
	PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;
	EPwm1Regs.ETCLR.bit.INT=1;
}
void main()
{
	Uint16 i=0;


	InitSysCtrl();
	InitPieCtrl();
	IER = 0x0000;
	IFR = 0x0000;
	InitPieVectTable();

	LED_Init();
	TIM0_Init(150,200000);//200ms
	UARTa_Init(4800);

	EQEP1_Init();

	while(1)
	{

	}
}

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值