中断介绍
F28335 的中断源可分为片内外设中断源,比如 PWM、CAP、QEP、定时器等,片外中断源,外部中断输入引脚 XINT1、XINT2 引入的外部中断源。F28335 内部有 16 个中断线,其中包括 2 个不可屏蔽中断(RESET 和 NMI)与14 个可屏蔽中断。F28335 的中断采用的是 3 级中断机制,分别是外设级中断、PIE 级中断和 CPU级中断,最内核部分为 CPU 级中断,即 CPU 只能响应从 CPU 中断线上过来的中断请求,但 F28335 中断源很多,CPU 没有那么多中断线,在有限中断线的情况下,只能安排中断线进行复用,其复用管理就有了中间层的 PIE 级中断,外设要能够成功产生中断响应,就要首先经外设级中断允许,然后经 PIE 允许,最终 CPU做出响应。
外部中断
F28335 共 支 持 7 个 外 部 中 断 XINT1-XINT7 , 其 中 XINT1-XINT2 只 能 对GPIO0-GPIO31 配置;XINT3-XINT7 只对 GPIO32-GPIO63 配置。XINT13 还有一个 不可屏蔽的外部中断 XNMI 共用中断源。每一个外部中断可以被选择为正边沿或负边沿触发,也可以被使能或者禁止(包括 XNMI)。可屏蔽中断单元包括一个16 位增计数器,该计数器在检测到有效中断边沿时复位为 0,同时用来准确记录中断发生的时间。
定时器中断
TMS320F28335 的 CPU Time 有三个,分别为 Timer0,Timer1,Timer2,其中Timer2 是为操作系统 DSP/BIOS 保留的,当未移植操作系统时,可用来做普通的定时器。
相关寄存器
外部中断寄存器
外部中断控制寄存器(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;}