skip to content
Logo filosefer's Blog

DSP学习笔记之中断系统

/ 6 min read

中断介绍

F28335 的中断源可分为片内外设中断源,比如 PWM、CAP、QEP、定时器等,片外中断源,外部中断输入引脚 XINT1、XINT2 引入的外部中断源。F28335 内部有 16 个中断线,其中包括 2 个不可屏蔽中断(RESET 和 NMI)与14 个可屏蔽中断。F28335 的中断采用的是 3 级中断机制,分别是外设级中断、PIE 级中断和 CPU级中断,最内核部分为 CPU 级中断,即 CPU 只能响应从 CPU 中断线上过来的中断请求,但 F28335 中断源很多,CPU 没有那么多中断线,在有限中断线的情况下,只能安排中断线进行复用,其复用管理就有了中间层的 PIE 级中断,外设要能够成功产生中断响应,就要首先经外设级中断允许,然后经 PIE 允许,最终 CPU做出响应。

image-20240508111922101

外部中断

F28335 共 支 持 7 个 外 部 中 断 XINT1-XINT7 , 其 中 XINT1-XINT2 只 能 对GPIO0-GPIO31 配置;XINT3-XINT7 只对 GPIO32-GPIO63 配置。XINT13 还有一个 不可屏蔽的外部中断 XNMI 共用中断源。每一个外部中断可以被选择为正边沿或负边沿触发,也可以被使能或者禁止(包括 XNMI)。可屏蔽中断单元包括一个16 位增计数器,该计数器在检测到有效中断边沿时复位为 0,同时用来准确记录中断发生的时间。

image-20240508130953595

定时器中断

TMS320F28335 的 CPU Time 有三个,分别为 Timer0,Timer1,Timer2,其中Timer2 是为操作系统 DSP/BIOS 保留的,当未移植操作系统时,可用来做普通的定时器。

image-20240508131040003

相关寄存器

外部中断寄存器

外部中断控制寄存器(XINTnCR)

名称描述
Polarity决定中断时产生在信号的边沿情况
0:中断产生在下降沿
1:中断产生在上升沿
2:中断产生在下降沿
3:既产生在上升沿也产生在下降沿
Enable外部中断XINT的使能位
0:禁止中断
1:使能中断

定时器寄存器

定时器控制寄存器(TIMERxTCR)

名称描述
TRB定时器重装位
0:禁止重装
1:使能重装
TSS定时器启动和停止状态为
0:启动和重启定时器
1:停止定时器

定时器预定标寄存器

低位寄存器为TIMERxTPR,高位寄存器为TIMERxTPRH

名称描述
PSC定时器预定标器计数器
TDDR定时器分频器

定时器周期寄存器

名称描述
PRD定时器周期寄存器(PRDH:PRD )

代码分析

外部中断代码

void EXTI1_Init(void)
{
EALLOW;
SysCtrlRegs.PCLKCR3.bit.GPIOINENCLK = 1;
// GPIO input clock
EDIS;
EALLOW;
//KEY 端口配置
GpioCtrlRegs.GPAMUX1.bit.GPIO12=0;
GpioCtrlRegs.GPADIR.bit.GPIO12=0;
GpioCtrlRegs.GPAPUD.bit.GPIO12=0;
GpioCtrlRegs.GPAQSEL1.bit.GPIO12 = 0;
// 外部中断 1
(XINT1)与系统时钟 SYSCLKOUT 同步
GpioCtrlRegs.GPBMUX2.bit.GPIO48=0;
GpioCtrlRegs.GPBDIR.bit.GPIO48=1;
GpioCtrlRegs.GPBPUD.bit.GPIO48=0;
GpioDataRegs.GPBCLEAR.bit.GPIO48=1;
EDIS;
EALLOW;
GpioIntRegs.GPIOXINT1SEL.bit.GPIOSEL = 12;
// XINT1 是 GPIO12
EDIS;
EALLOW;
// 修改被保护的寄存器,修改前应添加 EALLOW 语句
PieVectTable.XINT1 = &EXTI1_IRQn;
EDIS;
// EDIS 的意思是不允许修改被保护的寄存器
PieCtrlRegs.PIEIER1.bit.INTx4 = 1;
// 使能 PIE 组 1 的
INT4
XIntruptRegs.XINT1CR.bit.POLARITY = 0;
// 下降沿触发中断
XIntruptRegs.XINT1CR.bit.ENABLE= 1;
// 使能 XINT1
IER |= M_INT1;
// 使能 CPU 中断 1
(INT1)
EINT;
// 开全局中断
ERTM;
}
interrupt void EXTI1_IRQn(void)
{
PieCtrlRegs.PIEACK.bit.ACK1=1;
}

定时器中断代码

void TIM0_Init(float Freq, float Period)
{
EALLOW;
SysCtrlRegs.PCLKCR3.bit.CPUTIMER0ENCLK = 1; // CPU Timer 0
EDIS;
//设置定时器 0 的中断入口地址为中断向量表的 INT0
EALLOW;
PieVectTable.TINT0 = &TIM0_IRQn;
EDIS;
//指向定时器 0 的寄存器地址
CpuTimer0.RegsAddr = &CpuTimer0Regs;
//设置定时器 0 的周期寄存器值
CpuTimer0Regs.PRD.all = 0xFFFFFFFF;
//设置定时器预定标计数器值为 0
CpuTimer0Regs.TPR.all = 0;
CpuTimer0Regs.TPRH.all = 0;
//确保定时器 0 为停止状态
CpuTimer0Regs.TCR.bit.TSS = 1;
//重载使能
CpuTimer0Regs.TCR.bit.TRB = 1;
// Reset interrupt counters:
CpuTimer0.InterruptCount = 0;
ConfigCpuTimer(&CpuTimer0, Freq, Period);
//开始定时器功能
CpuTimer0Regs.TCR.bit.TSS=0;
//开启 CPU 第一组中断并使能第一组中断的第 7 个小中断,即定时器 0
IER |= M_INT1;
PieCtrlRegs.PIEIER1.bit.INTx7 = 1;
//使能总中断
EINT;
ERTM;
}
interrupt void TIM0_IRQn(void)
{
EALLOW;
PieCtrlRegs.PIEACK.bit.ACK1=1;
EDIS;
}