本文主要是介绍CCS F28355 ePWM波 看门狗 中断 CPU定时器,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
记录这几天学的生成ePWM波,看门狗以及CPU定时器中断的相关知识点
参考文献:《轻松玩转DSP——基于TMS320F2833x》是2018年机械工业出版社出版的图书,作者:马骏杰
一、生成频率为1KHz、占空比为50%的方波信号
这里呢就不具体介绍原理了,大家有空可以看看书125页,讲的比较详细,下面直接上代码,解释每一行代码,主要是方便我记。这次主要讲基本的ePWM波生成(死区,移相角,AD采样,PID什么的一步一步学了来)
void EPWM_Init(void)
{
//------------- EPWM1A初始化-------------------------------------EPwm1Regs.TBCTL.bit.CLKDIV = 0; // 定时器时间分频系数 默认为0EPwm1Regs.TBCTL.bit.HSPCLKDIV = 1; // 高速外设时间分频系数 默认1EPwm1Regs.TBCTL.bit.CTRMODE = 2; // 定义ePWM单元的工作模式:增减计数模式// ePWM1A 计数值等于0,置高电平。// ePWM1A计数值等于PRD,置低电平。EPwm1Regs.AQCTLA.all = 0x0006; //具体位格式表见P134EPwm1Regs.TBPRD = 37500; // 1KHz PWM//TBPRD计算公式//TBPRD=系统时钟频率/(2*开关频率*2^(CLKDIV)*2^(HSPCLKDIV))//TBPRD=150M/(2*1K*2^0*2^1)=37500EPwm1Regs.CMPA.half.CMPA = 37500/2; // 50%占空比//CMPA计算公式//CMPA=(100%-占空比)*TBPRD=(100%-50%)*37500
//==============================================================
}
前两行代码,一般默认就行了
第三行代码EPwm1Regs.TBCTL.bit.CTRMODE = 2; 是选择具体的工作模式,总共分为三种计数模式,递增、递减、递增递减模式(0 1 2)

第四行代码 EPwm1Regs.AQCTLA.all = 0x0006;则具体选择控制位的,这里不具体讲所有的,仅以代码为例子
// ePWM1A 计数值等于0,置高电平。所以ZERO位 10
// ePWM1A计数值等于PRD,置低电平。同理TBPRD位 01

然后其他位置0 0110=6 所以转为十六进制=0x0006
EPwm1Regs.TBPRD = 37500;这个是周期计算,公式如代码里所示,递增递减模式,是需要完成递增递减两个动作才算一个周期,但是由图1可知,TBPRD又在中间,所以需要除以2,其他模式是不需要除2的。
EPwm1Regs.CMPA.half.CMPA = 37500/2;计算公式如代码所示,其实在这个例子里面AQCTLA如此设置以及选择了递增递减模式后,已经完成了1KHz占空比50%的ePWM波输出,删掉也不妨事。已经实践过了,示波器波形确实和以前一致。
ePWM波的生成呢比较简单,但是想要完整工作的话,需要加上看门狗程序,防止出现意外情况,可以随时重启程序,看门狗就需要定时器中断去定时喂狗。
二、看门狗
看门狗呢,就讲我认为比较实用的,一个是如何开启看门狗,并设置喂狗周期时间;第二个就是喂狗程序。


SysCtrlRegs.WDCR位格式表如图3.1所示
首先讲WDPS位,这是看门狗计数时钟,也就是喂狗周期设置,由看门狗电路图3.2可知,
外部晶振时钟OSCCLK除以512后,再经过看门狗预分频寄存器,后看门狗计数器加1,一共八位二进制,也就是2^8=256,满了过后,如果这期间没有进行喂狗,那么就会进行看门狗复位。
OSCCLK=30MHz,当不分频时,此时中断时间最短为:
T=1/f=1/(30M/512)*2^8=4.37ms
如果为最大分频64时
T=1/(30M/512/64)*2^8=279.62ms
WDCHK必须为101,其他位看图就可以了。
下面是喂狗程序,记住就行。
SysCtrlRegs.WDKEY = 0x55;SysCtrlRegs.WDKEY = 0xAA; // 喂狗
三、CPU定时器
具体代码如下
//中断初始化
//--------------------定时器初始设置 每100ms喂一次狗------------------EALLOW;PieVectTable.TINT0 = &Time0_ISR;//将定时器0的函数入口提供给PIE中断向量表EDIS;InitCpuTimers(); // 初始化定时器ConfigCpuTimer(&CpuTimer0,150,100000);// 定时时间为100ms//参数一:选择所需定时器CpuTimer0 CpuTimer1 CpuTimer2//参数二:系统时钟频率(MHz)//参数三:定时(us)PieCtrlRegs.PIEIER1.bit.INTx7 = 1;// 使能PIE定时器0中断IER |=1;// 使能INT1中断EINT; //使能总中断ERTM; //启用实时模式CpuTimer0Regs.TCR.bit.TSS = 0; // 启动定时器0//每一次CPU定时器满后,中断执行喂狗程序
interrupt void Time0_ISR(void)
{CpuTimer0.InterruptCount++;//每次中断后自加1EALLOW;SysCtrlRegs.WDKEY = 0x55;SysCtrlRegs.WDKEY = 0xAA; // 喂狗EDIS;PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;//应答
}
总代码以及具体实现功能
功能1:1KHz占空比50%的ePWM波输出
功能2:开启看门狗,设置最大喂狗时间为279.62ms
功能3:开启CPU定时器中断,每100ms喂一次狗,以及LED灯闪烁一次
#include "DSP28x_Project.h"
#include "math.h"
#include "IQmathLib.h"
#define LED1 GpioDataRegs.GPADAT.bit.GPIO6
//这部分代码是引入一些头文件,并定义了一个宏LED1用于控制GPIO6引脚的状态。
void GPIO_Init(void);
void EPWM_Init(void);
interrupt void Time0_ISR(void);
//这里声明了三个函数:GPIO_Init用于初始化GPIO配置,
//EPWM_Init用于初始化ePWM模块配置,Time0_ISR是一个中断服务函数。
void main(void)
{int counter=0; // 记录产生中断次数/*系统初始化*/InitSysCtrl();DINT;InitPieCtrl();IER = 0x0000;IFR = 0x0000;InitPieVectTable();
//在main函数中,首先初始化了系统控制、关闭全局中断、
//初始化PIE (Peripheral Interrupt Expansion) 控制器、
//清除中断使能寄存器、清除中断标志寄存器、初始化PIE中断向量表。EALLOW;SysCtrlRegs.WDCR= 0x00AF; // 使能看门狗EDIS;GPIO_Init(); // GPIO初始化EPWM_Init(); // ePWM1, ePWM2 and ePWM3初始化EALLOW;PieVectTable.TINT0 = &Time0_ISR;//将定时器0的函数入口提供给PIE中断向量表EDIS;InitCpuTimers(); // 初始化定时器ConfigCpuTimer(&CpuTimer0,150,100000);// 定时时间为100msPieCtrlRegs.PIEIER1.bit.INTx7 = 1;// 使能PIE定时器0中断IER |=1;// 使能INT1中断EINT; //使能总中断ERTM;CpuTimer0Regs.TCR.bit.TSS = 0; // 启动定时器0while(1){LED1 = 0; //点亮LED1;因为我的原理图的低电平,点亮while(CpuTimer0.InterruptCount == 0);//延时程序,每发生一次中断CpuTimer0.InterruptCount 加1,刚开始其值为0,所以一直循环//当发生一次中断后,其值加1,跳出循环LED1 = 1;while(CpuTimer0.InterruptCount == 1);CpuTimer0.InterruptCount = 0;counter++;}}
// 在这部分代码中,首先使能了看门狗,然后调用GPIO_Init()初始化GPIO配置,调用EPWM_Init()初始化ePWM模块配置。
// 接下来,通过EALLOW和EDIS启用和禁用中断的访问权限,并将Time0_ISR的函数地址赋值给PIE中断向量表的TINT0位。
// 然后,通过InitCpuTimers()初始化CPU定时器,使用ConfigCpuTimer()配置CpuTimer0的计数器参数,使得其每隔100ms计数值触发一次中断
// 接着,设置PIEIER1寄存器的INTx7位使能PIE定时器0中断,设置IER寄存器的INT1位使能INT1中断。
// 然后,通过EINT使能总中断,ERTM开启允许直接接触全局中断控制。
// 最后,启动定时器0,进入一个无限循环,循环中通过LED1控制GPIO6引脚点亮和熄灭,并在定时器中断发生后对计数器进行自增操作。
void GPIO_Init(void)
{EALLOW;GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 1; // GPIO0 复用成 ePWM1AGpioCtrlRegs.GPAMUX1.bit.GPIO6 = 0; // GPIO1复用为GPIO功能GpioCtrlRegs.GPADIR.bit.GPIO6 = 1; // GPIO1设置为输出GpioCtrlRegs.GPAPUD.bit.GPIO6 = 0; // GPIO1允许上拉EDIS;
}
//GPIO_Init()函数用于初始化GPIO配置。这里通过设置GPAMUX1寄存器的GPIO0位将GPIO0复用为ePWM1A功能,
//通过设置GPAMUX1寄存器的GPIO6位将GPIO6复用为GPIO功能。
//然后设置GPADIR寄存器的GPIO6位为输出模式,GPAPUD寄存器的GPIO6位允许上拉。
void EPWM_Init(void)
{EPwm1Regs.TBCTL.bit.CLKDIV = 0; // CLKDIV = 1 定时器时间分频系数 默认为0EPwm1Regs.TBCTL.bit.HSPCLKDIV = 1; // HSPCLKDIV = 2 高速外设时间分频系数 默认1EPwm1Regs.TBCTL.bit.CTRMODE = 2; // 定义ePWM单元的工作模式:增减计数模EPwm1Regs.AQCTLA.all = 0x0006;//具体位格式表见P134EPwm1Regs.TBPRD = 37500; // 1KHz PWMEPwm1Regs.CMPA.half.CMPA = 37500/2;// 50%占空比
}
//EPWM_Init()函数用于初始化ePWM模块配置。这里设置了一些寄存器来配置ePWM模块的工作参数,
//例如定时器的分频系数、高速外设时间分频系数、工作模式等。然后通过设置AQCTLA寄存器来定义ePWM输出行为。
//最后,设置TBPRD寄存器为37500,即1KHz的PWM频率,设置CMPA寄存器为TBPRD的一半,即50%的占空比。
interrupt void Time0_ISR(void)
{CpuTimer0.InterruptCount++;EALLOW;SysCtrlRegs.WDKEY = 0x55;SysCtrlRegs.WDKEY = 0xAA; // 喂狗EDIS;PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;//应答
}
//Time0_ISR是中断服务函数,当定时器0触发中断时会执行这个函数。在这个函数中,
//首先对CpuTimer0.InterruptCount进行自增操作,然后通过EALLOW和EDIS使能对系统控制寄存器的访问权限,
//通过赋值0x55和0xAA到WDKEY寄存器喂狗,最后通过设置PIEACK寄存器的PIEACK_GROUP1位来应答中断。
这篇关于CCS F28355 ePWM波 看门狗 中断 CPU定时器的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!