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;    // 定时器时间分频系数  默认为0
    EPwm1Regs.TBCTL.bit.HSPCLKDIV = 1;  // 高速外设时间分频系数   默认1
    EPwm1Regs.TBCTL.bit.CTRMODE = 2;    // 定义ePWM单元的工作模式:增减计数模式
    // ePWM1A 计数值等于0,置高电平。
    // ePWM1A计数值等于PRD,置低电平。
    EPwm1Regs.AQCTLA.all = 0x0006;      //具体位格式表见P134
    EPwm1Regs.TBPRD = 37500;            // 1KHz PWM
    //TBPRD计算公式
    //TBPRD=系统时钟频率/(2*开关频率*2^(CLKDIV)*2^(HSPCLKDIV))
    //TBPRD=150M/(2*1K*2^0*2^1)=37500
    EPwm1Regs.CMPA.half.CMPA = 37500/2;  // 50%占空比
    //CMPA计算公式
    //CMPA=(100%-占空比)*TBPRD=(100%-50%)*37500
//==============================================================
}

前两行代码,一般默认就行了

第三行代码EPwm1Regs.TBCTL.bit.CTRMODE = 2; 是选择具体的工作模式,总共分为三种计数模式,递增、递减、递增递减模式(0 1 2)

图1

第四行代码 EPwm1Regs.AQCTLA.all = 0x0006;则具体选择控制位的,这里不具体讲所有的,仅以代码为例子

// ePWM1A 计数值等于0,置高电平。所以ZERO位  10
// ePWM1A计数值等于PRD,置低电平。同理TBPRD位 01

图2

 然后其他位置0  0110=6  所以转为十六进制=0x0006

EPwm1Regs.TBPRD = 37500;这个是周期计算,公式如代码里所示,递增递减模式,是需要完成递增递减两个动作才算一个周期,但是由图1可知,TBPRD又在中间,所以需要除以2,其他模式是不需要除2的。

EPwm1Regs.CMPA.half.CMPA = 37500/2;计算公式如代码所示,其实在这个例子里面AQCTLA如此设置以及选择了递增递减模式后,已经完成了1KHz占空比50%的ePWM波输出,删掉也不妨事。已经实践过了,示波器波形确实和以前一致。

ePWM波的生成呢比较简单,但是想要完整工作的话,需要加上看门狗程序,防止出现意外情况,可以随时重启程序,看门狗就需要定时器中断去定时喂狗。

二、看门狗

        看门狗呢,就讲我认为比较实用的,一个是如何开启看门狗,并设置喂狗周期时间;第二个就是喂狗程序。

图3.1
图3.2

 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++;//每次中断后自加1
    EALLOW;
    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);// 定时时间为100ms
       PieCtrlRegs.PIEIER1.bit.INTx7 = 1;// 使能PIE定时器0中断
       IER |=1;// 使能INT1中断
       EINT;   //使能总中断
       ERTM;
       CpuTimer0Regs.TCR.bit.TSS = 0;  // 启动定时器0
       while(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 复用成 ePWM1A
    GpioCtrlRegs.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     定时器时间分频系数  默认为0
    EPwm1Regs.TBCTL.bit.HSPCLKDIV = 1;  // HSPCLKDIV = 2  高速外设时间分频系数   默认1
    EPwm1Regs.TBCTL.bit.CTRMODE = 2;    // 定义ePWM单元的工作模式:增减计数模
    EPwm1Regs.AQCTLA.all = 0x0006;//具体位格式表见P134
    EPwm1Regs.TBPRD = 37500;            // 1KHz PWM
    EPwm1Regs.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位来应答中断。

  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值