本文记录dsp28335的中断的配置方法:
目录
F28335 的 ePWM 模块是个加强模块,与 F2812 的 PWM 模块有较大不同,在 F2812 中,PWM 模块采用事件管理器控制,与 eCAP 和 eQEP 共享定时器信号,而 F28335 中每个 ePWM 模块都是一个独立的小模块,这样的体系结构更方便我们使用与理 解。每个 ePWM 模块由两路 ePWM 输出组成,分别为 ePWMxA 和 ePWMxB,这一对 PWM 输出,可以配置成两路独立的单边沿 PWM 输出,或者两路独立的但互相相对称的 双边沿 PWM 输出,或者一对双边沿非对称的 PWM 输出,共有 6 对这样的 ePWM 模 普中 DSP28335 开发攻略 www.prechin.cn 276 块,因为每对 PWM 模块中的两个 PWM 输出均可以单独使用,所以也可以认为有 12 路单路 ePWM,除此之外还有 6 个 APWM,这 6 个 APWM 通过 CAP 模块扩展配置, 可以独立使用,所以 F28335 最多可以有 18 路 PWM 输出。每一组 ePWM 模块都包 含以下 7 个模块:时基模块 TB、计数比较模块 CC、动作模块 AQ、死区产生模块 DB、PWM 斩波模块 PC、错误联防模块 TZ、时间触发模块 ET,如下所示,
每组 ePWM 模块支持以下特点:
TB模块的主要作用是定时器,计数器。
需要设置时钟预分频,分频,周期,相位,计数方向,周期重载使能,其他通道时钟同步,影子寄存器使能。
通过影子寄存器修改参数。因为定时器中每个脉冲来了都要在寄存器中修改值,读写频率很高,如果用户随意读写寄存器的值,很容易发生冲突,产生问题。影子寄存器相当于一个缓存器,专门给用户实时修改寄存器提供一个通道,只要开启影子寄存器功能,读写寄存器和源寄存器一样。
计数器比较模块是以时基计数器的计数值作为输入,与比较寄存器CMPA和CMPB不断进行比较,当时基计数器的值等于CMPA时,就产生比较事件CTR = CMPA;当时基计数器的值等于CMPB时,就产生比较事件CTR = CMPB。计数寄存器模块有以下要点进行说明:
配置pwm的高低电平变化的位置和极性。
每个通道主要有3个点,0点,设置比较点,周期点。我们设置两个点就好。
例如向上计数,从0到周期点,前两个点就是0点,和比较点。
我们设置=0时,低电平;等于CMPA时,高电平。就得到下图波形。
EPwm6Regs.AQCTLA.bit.ZRO = AQ_CLEAR; //ZRO 是0; PRD是周期点
EPwm6Regs.AQCTLA.bit.CAU = AQ_SET; //CAU 是比较点A,向上计数
向下计数,同理。B通道也是一样设置。
- // 禁止CPU全局中断
- DINT;
-
- // // 禁止CPU中断和清除所有CPU中断标志
- // IER = 0x0000;
- // IFR = 0x0000;
- // InitPieCtrl();
- // InitPieVectTable();
-
- //步骤 2.
- EALLOW;//关闭写保护
- SysCtrlRegs.PCLKCR3.bit.GPIOINENCLK = 1;
- EDIS;//打开写保护
- InitEPwm6Gpio();
-
- EALLOW;//关闭写保护
- SysCtrlRegs.PCLKCR1.bit.EPWM6ENCLK = 1; // ePWM
-
- SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0; // Stop all the TB clocks
-
-
- // 设置TBCLK寄存器功能
- EPwm6Regs.TBPRD = 10000; // 设置周期值为10000,等于15k
- EPwm6Regs.TBPHS.half.TBPHS = 0x0000; // 设置相移值为0
- EPwm6Regs.TBCTR = 0x0000; // 清除计数器的值
-
- // 设置比较寄存器功能
- EPwm6Regs.CMPA.half.CMPA = 0; // 设置CMPA比较寄存器A的值为0
- EPwm6Regs.CMPB = 0; // 设置CMPB比较寄存器B的值为0
-
- // 设置计数模式功能
- EPwm6Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // 上下计数模式
- EPwm6Regs.TBCTL.bit.PHSEN = TB_DISABLE; // 禁止相移值装载到计数器
- EPwm6Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE; // 计数器值为0的时候发出同步信号,使得ePWM2/3/4/5/6的计数与1同步,不会产生误差偏移累加
- EPwm6Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // 高速时钟预分频为1 TBCLK=150MHz
- EPwm6Regs.TBCTL.bit.CLKDIV = TB_DIV1; // 时钟预分频为1, 最终时钟频率:TBCLK=SYSCKOUT/(HSPCLKDIV*CLKDIV)=150MHz/(1*1)=150MHz
- // ePWM频率=TBCLK/(2*TBPRD)=150000000/(2*50000)=1500Hz
- // EPwm6Regs.TBCTL.bit.PRDLD = TB_SHADOW; //TBPRD 寄存器采用影子寄存器模式
- SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1; //使能时基计时器
-
-
- // 设置装载模式功能
- EPwm6Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; // 设定CMPA为影子模式
- EPwm6Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW; // 设定CMPB为影子模式
- EPwm6Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // 设定在计数值CTR=ZERO时,装载CMPA比较值
- EPwm6Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; // 设定在计数值CTR=ZERO时,装载CMPB比较值
-
- // 设置动作功能
- EPwm6Regs.AQCTLA.bit.ZRO = AQ_SET; // Set PWM1A on Zero
- EPwm6Regs.AQCTLA.bit.CAU = AQ_CLEAR; // Clear PWM1A on event A, up count
- EPwm6Regs.AQCTLB.bit.ZRO = AQ_SET; // Set PWM1B on Zero
- EPwm6Regs.AQCTLB.bit.CBU = AQ_CLEAR; // Clear PWM1B on event B, up count
-
- PieCtrlRegs.PIEIER3.bit.INTx6 = 1;//使能ePWM6中断
- EDIS;//打开写保护
-
- //步骤 3. 使能CPU级中断及全局中断
- IER |= M_INT3;
- EINT;//打开全局中断
-
- ERTM;//当使用仿真器调试时 开启DEBUG中断
配置AB两个通道之间的死区。
在控制同一桥臂上的两个开关管不能同时导通,如果同时导通,就会造成电源短路。因此输入同一桥臂上的两个开关管的驱动信号必须 要进行互补控制。
模块框图:
通过三个寄存器配置:
工作模式:
模式波形图演示:
可以忽略文档中的名字,让人迷惑。
实际上就是延时 + 翻转的排列组合。
互补主高:双延时+B翻转
互补主低:双延时+A翻转
主高:双延时+不翻转
主低:双延时+双翻转
- //死区参数
- #define DB_IN_A 0 //上下均输入A
- #define DB_IN_A_UP_B_DOWN 2 //上升沿输入A,下降沿输入B
- #define DB_IN_B_UP_A_DOWN 1 //上升沿输入B,下降沿输入A
- #define DB_IN_B 3 //上下均输入B
-
- #define DB_SEL_0 0 //不翻转
- #define DB_SEL_A_F 1 //A翻转
- #define DB_SEL_B_F 2 //B翻转
- #define DB_SEL_A_B_F 3 //AB都翻转
-
- #define DB_OUT_0 0 //上下沿都不延时
- #define DB_Y_DOWN 1 //下降沿延时
- #define DB_Y_UP 2 //上升沿延时
- #define DB_Y_UP_DOWN 3 //上下沿都延时
-
-
-
- //设置死区模块
- EPwm6Regs.DBCTL.bit.IN_MODE = DB_IN_A_UP_B_DOWN; //EPWMA上边沿延时输入源,EPWMB下边沿延时输入源
- EPwm6Regs.DBCTL.bit.POLSEL = DB_SEL_0; //EPWMA 和 EPWMB都不翻转
- EPwm6Regs.DBCTL.bit.OUT_MODE = DB_Y_UP_DOWN; //EPWMA 和 EPWMB 双边沿延时
- EPwm6Regs.DBRED = 750; //上升沿延时一个时钟周期 5us
- EPwm6Regs.DBFED = 750; //下升沿延时一个时钟周期 5us
该功能主要用于基于脉冲变压器的门级驱动型功率器件控制中。一次模块OSHT主要用于提供较大能量的第一个脉冲,迅速有效地开通功率开关,接下来的脉冲只要维持开关的状态就行,例如多数功率器件的开通电流要比维持电流大得多。
效果就是这样子,把PWM波的高电平,编程高频脉冲序列。
斩波模块框图:
系统时钟8分频进入模块。
T(1stpulse)=T(SYSCLKOUT)*8*OSHTWTH // (OSHTWTH = 1-16)
PWM 斩波器这 一功能模块可以用 CHPEN 位进行使能控制与禁止。
例程,
- //PC斩波模块
- #define PC_FREQ_DIV1 1 //频率PSCLK = 系统时钟频率/8之后,再/PC_FREQ_DIV
- #define PC_DUTY_50 4 //占空比CHPDUTY = PC_DUTY*12.5%
- #define PC_OSHTWTH 16 //第一个脉冲持续时间T1stpulse = 系统时钟周期 × 8 × OSHTWTH
-
-
-
- //设置斩波模块
- EPwm6Regs.PCCTL.bit.CHPFREQ = PC_FREQ_DIV1; //载波分频
- EPwm6Regs.PCCTL.bit.CHPDUTY = PC_DUTY_50; //载波占空比
- EPwm6Regs.PCCTL.bit.OSHTWTH = PC_OSHTWTH; //首脉冲宽度
- EPwm6Regs.PCCTL.bit.CHPEN = 1; //启动PC模块
通常用于系统保护,出现故障时,需要快速关闭PWM。
每个 ePWM 模块都与 GPIO 多路复用引脚中的 6 个 TZn(TZ1-TZ6)信号脚连接。 这些信号脚用来响应外部错误或外部触发条件,当错误发生时,PWM 模块可以通过编程来响应这些问题。
错误联防模块的主要作用如下:
针对错误信息,ePWMxA 和 ePWMxB 可以被强制或如下几种状态:
--高电平。
--低电平。
--高阻抗。
--无动作。
每个 TZn 输入引脚可以单独配置一次触发或者周期触发。
需要配置寄存器:
需要配置寄存器:
例程,
- //错误联防
- #define High_Impedance 0 //高阻态
- #define Force_High 1 //强制高
- #define Force_Low 2 //强制低
- #define NO_Change 3 //不变
-
-
-
-
- //错误联防模块
- EPwm6Regs.TZSEL.bit.OSHT2 = 1; //单次触发,选择通道TZ2 GPIO13复用2
- EPwm6Regs.TZCTL.bit.TZA = Force_High; //触发之后强制低
- EPwm6Regs.TZCTL.bit.TZB = Force_High; //触发之后强制低
- EPwm6Regs.TZEINT.bit.OST = 1; //TZ模块使能
-
- SysCtrlRegs.PCLKCR3.bit.GPIOINENCLK = 1;
- GpioCtrlRegs.GPBMUX2.bit.GPIO50 = 0;
- GpioCtrlRegs.GPBDIR.bit.GPIO50 = 1;
- GpioCtrlRegs.GPBPUD.bit.GPIO50 = 0;
- GpioDataRegs.GPBCLEAR.bit.GPIO50 = 1;
- GpioCtrlRegs.GPAMUX1.bit.GPIO13 = 1; //GPIO13为故障输入口 TZ2
- GpioCtrlRegs.GPADIR.bit.GPIO13 = 0;
- GpioCtrlRegs.GPAPUD.bit.GPIO13 = 0;
- GpioCtrlRegs.GPAMUX1.bit.GPIO12 = 0; //GPIO12为故障复位
- GpioCtrlRegs.GPADIR.bit.GPIO12 = 0;
- GpioCtrlRegs.GPAPUD.bit.GPIO12 = 0;
-
- //设置中断PIE
- PieVectTable.EPWM6_TZINT = &PMW_TZ_ISR;
- PieCtrlRegs.PIEIER2.bit.INTx6 = 1; //使能错误联防TZ2的触发中断
-
- IER |= M_INT2; //别忘了使能CPU INT2通道
-
-
-
-
- interrupt void PMW_TZ_ISR(void)
- {
- int i;
- //接下来写错误清除信号的检测,当接收到错误联防信号,错误联防中断被触发进入此程序,
- //接下来检测按键是否被按下,当按键被按下,则表明故障已经清除,可以恢复PWM信号输出,
- while(EPwm6Regs.TZFLG.bit.OST == 1)
- {
- //这里写当按键被按下,则:
- //1.把错误联防中断清除寄存器TZCLR.bit.OST = 1以清除OST事件标志位,恢复PWM信号输出
- if(GpioDataRegs.GPADAT.bit.GPIO12 == 0)
- {
- for(i=0;i<20000;i++)//延时去抖
- {}
- if(GpioDataRegs.GPADAT.bit.GPIO12 == 0)
- {
- EALLOW;
- EPwm6Regs.TZCLR.bit.OST = 1; //清除OST事件标志位
- EDIS;
-
- }
- while(GpioDataRegs.GPADAT.bit.GPIO12 == 0);
- }
- }
- EALLOW;
- EPwm6Regs.TZCLR.bit.INT = 1;
- PieCtrlRegs.PIEACK.bit.ACK6 = 1;//清零PIEACK对应位
- EDIS;
- }
事件触发模块的功能主要如下:
①接收来自时基模块和计数比较模块产生的相关事件的输入。
②利用时基模块中的方向信息识别是递增还是递减计数模式以便产生相应 的事件。
③使用预定标判断逻辑发出中断请求或者 ADC 开始转换启动信号:
--每个事件。
--每两个事件。
--每三个事件。
④允许软件配置,强制产生中断事件或者 ADC 启动信号。
主要是再PWM周期内,特定时间点会产生事件,用这个信号来触发启动ADC。
例如我们要在PWM的每个周期开始时刻采样系统参数,就会用到这个。
1、事件触发选择寄存器 ETSEL
2、事件触发分频寄存器 ETPS 各位功能描述如下
3、事件触发标志寄存器 ETFLG 各位功能描述如
4、事件触发清除寄存器 ETCLR 各位功能描述如
5、事件触发强制寄存器 ETFRC
上面5个寄存器中的名字有SOC开头的,有INT开头的。
SOC开头的是SOC事件触发相关。
INT开头的是epwm的事件中断相关,两个没有关系。只是放在一个寄存器里了。
在SOC模块中只需要设置:
例程,
epwm部分:
- //SOC
- #define SOC_SEL_ZRO 1 //TBCTR = 0
- #define SOC_SEL_PRD 2 //TBCTR = TBPRD
- #define SOC_SEL_CAU 3 //TBCTR = CMPA, 向上计数
- #define SOC_SEL_CAD 4 //TBCTR = CMPA, 向下计数
- #define SOC_SEL_CBU 5 //TBCTR = CMPB, 向上计数
- #define SOC_SEL_CBD 6 //TBCTR = CMPB, 向下计数
-
- #define SOC_PRD_DIS 0 //禁止事件计数器
- #define SOC_PRD_1 1 //第1个事件,产生SOC信号
- #define SOC_PRD_2 2 //第2个事件,产生SOC信号
- #define SOC_PRD_3 3 //第3个事件,产生SOC信号
-
-
-
- //SOC事件ADC触发
- EPwm6Regs.ETSEL.bit.SOCASEL = SOC_SEL_PRD; //在0处产生soc
- EPwm6Regs.ETSEL.bit.SOCAEN = 1; //SOCA使能
- EPwm6Regs.ETPS.bit.SOCAPRD = SOC_PRD_1; //第一个事件时,产生soc
- EPwm6Regs.ETCLR.bit.SOCA = 1; //清楚SOCA标志位
ADC部分:很简单。
- // Start SEQ1
- AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1 = 1; //使能epwm_SOCA信号的触发SQE1
- AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1; //使能SEQ1
配置寄存器和1.7中一样,只是不同位。
设置思路和1.7类似。
只需要设置:
例程,
- // 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
-
-
- EALLOW;//关闭写保护
-
- // 设置事件模块的中断功能
- EPwm6Regs.ETSEL.bit.INTSEL = ET_CTR_PRD; // 在CTR=TBPRD时,产生中断
- EPwm6Regs.ETSEL.bit.INTEN = 1; // 使能中断
- EPwm6Regs.ETPS.bit.INTPRD = ET_1ST; // 每一次满足中断条件就产生一次中断
-
-
- //ET事件触发模块的PIE设置
- PieVectTable.EPWM6_INT = &EPWM_IRQ;
- PieCtrlRegs.PIEIER3.bit.INTx6 = 1;//使能ePWM1中断
- EDIS;//打开写保护
-
- //步骤 3. 使能CPU级中断及全局中断
- IER |= M_INT2;
- IER |= M_INT3;
- EINT;//打开全局中断
-
- ERTM;//当使用仿真器调试时 开启DEBUG中断
-
-
-
-
- interrupt void EPWM_IRQ(void)
- {
- //pwm计数器周期开始时会进来,
-
-
-
- EPwm6Regs.ETCLR.bit.INT = 1; //清除epwm中断标志位
- PieCtrlRegs.PIEACK.bit.ACK6 = 1;//清零PIEACK对应位
- }
待续。。