CCS F28355 ePWM波 看门狗 中断 CPU定时器

2023-11-27 00:50

本文主要是介绍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)

图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++;//每次中断后自加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定时器的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/426637

相关文章

第10章 中断和动态时钟显示

第10章 中断和动态时钟显示 从本章开始,按照书籍的划分,第10章开始就进入保护模式(Protected Mode)部分了,感觉从这里开始难度突然就增加了。 书中介绍了为什么有中断(Interrupt)的设计,中断的几种方式:外部硬件中断、内部中断和软中断。通过中断做了一个会走的时钟和屏幕上输入字符的程序。 我自己理解中断的一些作用: 为了更好的利用处理器的性能。协同快速和慢速设备一起工作

Java程序到CPU上执行 的步骤

相信很多的小伙伴在最初学习编程的时候会容易产生一个疑惑❓,那就是编写的Java代码究竟是怎么一步一步到CPU上去执行的呢?CPU又是如何执行的呢?今天跟随小编的脚步去化解开这个疑惑❓。 在学习这个过程之前,我们需要先讲解一些与本内容相关的知识点 指令 指令是指导CPU运行的命令,主要由操作码+被操作数组成。 其中操作码用来表示要做什么动作,被操作数是本条指令要操作的数据,可能是内存地址,也

FreeRTOS学习笔记(四)Freertos的中断管理及临界保护

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、Cortex-M 中断管理1.1 中断优先级分组1.2 相关寄存器1.3 相关宏定义1.4 FreeRTOS 开关中断 二、临界段及其保护2.1 taskENTER_CRITICAL( ) 和 taskEXIT_CRITICAL( )2.2 taskENTER_CRITICAL_FROM_ISR( )

【Qt】定时器事件

定时器事件 在之前学习QTimer中实现了定时器的功能,而在QTimer背后是QTimerEvent定时器事件进行支撑的。在QObject中提供了一个timeEvent这个函数。 startTimer启动定时器killTimer关闭定时器 Qt 中在进⾏窗⼝程序的处理过程中,经常要周期性的执⾏某些操作,或者制作⼀些动画效果,使⽤定 时器就可以实现。所谓定时器就是在间隔⼀定时间后,去执⾏某⼀

独立按键单击检测(延时消抖+定时器扫描)

目录 独立按键简介 按键抖动 模块接线 延时消抖 Key.h Key.c 定时器扫描按键代码 Key.h Key.c main.c 思考  MultiButton按键驱动 独立按键简介 ​ 轻触按键相当于一种电子开关,按下时开关接通,松开时开关断开,实现原理是通过轻触按键内部的金属弹片受力弹动来实现接通与断开。  ​ 按键抖动 由于按键内部使用的是机

Cortex-A7:ARM官方推荐的嵌套中断实现机制

0 参考资料 ARM Cortex-A(armV7)编程手册V4.0.pdf ARM体系结构与编程第2版 1 前言 Cortex-M系列内核MCU中断硬件原生支持嵌套中断,开发者不需要为了实现嵌套中断而进行额外的工作。但在Cortex-A7中,硬件原生是不支持嵌套中断的,这从Cortex-A7中断向量表中仅为外部中断设置了一个中断向量可以看出。本文介绍ARM官方推荐使用的嵌套中断实现机

win10不用anaconda安装tensorflow-cpu并导入pycharm

记录一下防止忘了 一、前提:已经安装了python3.6.4,想用tensorflow的包 二、在pycharm中File-Settings-Project Interpreter点“+”号导入很慢,所以直接在cmd中使用 pip install -i https://mirrors.aliyun.com/pypi/simple tensorflow-cpu下载好,默认下载的tensorflow

定位cpu占用过高的线程和对应的方法

如何定位cpu占用过高的线程和对应的方法? 主要是通过线程id找到对应的方法。 1 查询某个用户cpu占用最高的进程号 top -u 用户名 2 查询这个进程中占用cpu最高的线程号 top –p 进程号-H    3 查询到进程id后把进程相关的代码打印到jstack文件 jstack -l pid > jstack.txt 4 在jstack文件中通过16进制的线程id搜索到

外部中断的边缘触发和电平触发

MCS-51单片机中的边缘触发是指当输入引脚电平由高到低发生跳变时,才引起中断。而电平触发是指只要外部引脚为低电平就引起中断。         在电平触发方式下,当外部引脚的低电平在中断服务返回前没有被拉高时(即撤除中断请求状态),会引起反复的不需要的中断,造成程序执行的错误。这类中断方式下,需要在中断服务程序中设置指令,清除外部中断的低电平状态,使之变为高电平。

CPU亲和性设置 代码示例 sched_setaffinity sched_getaffinity

视频教程在这: cpu亲和性设置,NCCL,sched_setaffinity sched_getaffinity,CPU_ZERO、SET、ISSET、linux_哔哩哔哩_bilibili 一、CPU亲和性简介 CPU亲和性(CPU Affinity)设置是操作系统中一个重要的性能优化手段,它允许程序或进程被绑定到特定的CPU核心上运行。这样做的好处包括减少缓存未命中、降低线程迁移(co