PIC18 中断优先级怎么配:IPEN、0008h/0018h 双向量与 3~4 TCY 响应拆解

PIC18 中断配错优先级,ISR 会互相打断、现场保护也会失效。按 DS39510A_CN 第 10 章拆解 IPEN、0008h/0018h 双向量、影子寄存器与 3~4 TCY 响应延时,给出七步初始化和六条排查。

2026-11-07
PIC18中断优先级IPEN中断向量现场保护响应延时

一台 12 路 IO 采集板用 PIC18 做 Modbus 从机,串口接收和 1 ms 定时采样都放在中断里。跑久了偶发丢帧,示波器抓到低优先级 ISR 执行到一半又被高优先级打断,返回后变量已经乱了。结论先给:PIC18 有两个中断向量,高优先级在 000008h、低优先级在 000018h,靠 RCON 的 IPEN 打开;高优先级能打断低优先级 ISR,反过来不行;外部中断响应固定 3~4 个指令周期,真正的风险在现场保护和长写,而不是向量地址。

本文按 Microchip《PICmicro 高档单片机系列参考手册》DS39510A_CN 第 10 章“中断”整理,寄存器位定义、嵌套规则、例程与延时说明均取自该章;文中 10 MHz、20 MHz 的纳秒换算是按 TCY=4/FOSC 代入的算例。

一、两个向量和三个全局位

PIC18 的中断源很多:INT0~INT2、RB7:RB4 电平变化、TMR0~TMR3、USART、SSP、A/D、CCP、LVD、PSP、CAN。控制和状态分散在 INTCON、INTCON1~3、PIR1/2、PIE1/2、IPR1/2 这十个寄存器里。真正决定“能不能进、进哪个向量”的,是 INTCON 里的三个全局位和 RCON 里的 IPEN。

位IPEN=0 时IPEN=1 时
GIE/GIEH(INTCON<7>)全局中断总开关高优先级全局开关,同时管所有中断
PEIE/GIEL(INTCON<6>)外设中断总开关只开关低优先级中断
IPRx 优先级位不使用,全部按高优先级1=高优先级,0=低优先级

IPEN=0 时没有优先级概念,所有中断都走高优先级向量 000008h,PEIE/GIEL 退回成普通外设中断总开关。IPEN=1 后,GIE/GIEH 管全局,PEIE/GIEL 只管低优先级;此时低优先级外设要同时满足 GIEH=1、GIEL=1、PIE=1、IPR=0 才会被响应。手册的初始化例程也是先写 RCON 的 IPEN,再装 IPR1、清 PIR1、装 PIE1,最后把 INTCON 写成 0xC0。

二、优先级位:复位后全是高优先级

每个中断源在 IPR1、IPR2、IPR3、INTCON2、INTCON3 里有自己的优先级位,写 1 是高,写 0 是低。手册明确说所有优先级位复位为 1,也就是复位后每个中断都被当成高优先级。这一点很关键:只开 IPEN、不重新分配 IPR,所有中断都会挤进 000008h,低优先级向量根本用不上。

分配原则按实时性来:急停、过流、通信接收这类不能等的放高优先级;定时采样、显示刷新、按键扫描放低优先级。高优先级 ISR 要短,能只清标志、置事件就不要再做浮点运算或整帧搬运。

三、嵌套规则:高可以打断低,低不能打断高

响应高优先级中断时,硬件自动清 GIE/GIEH,返回地址压栈,PC 装 000008h;响应低优先级时,硬件清 PEIE/GIEL,PC 装 000018h。低优先级 ISR 执行期间 GIE/GIEH 仍为 1,所以高优先级可以随时插进来;反过来,低优先级不能打断高优先级 ISR。两者同时被采样到,永远先响应高优先级。

场景硬件动作返回时
进入高优先级 ISR清 GIE/GIEH,PC=000008hRETFIE 重新置 GIE/GIEH
进入低优先级 ISR清 PEIE/GIEL,PC=000018hRETFIE 重新置 PEIE/GIEL
低优先级执行中被高优先级打断高优先级再清 GIE/GIEH,压栈后跳到 000008h高优先级先返回,低优先级继续
高优先级执行中来了低优先级低优先级挂起,等所有高优先级处理完高优先级返回后再响应低优先级

RETFIE 的行为不一样:从高优先级返回会重新置 GIE/GIEH,从低优先级返回会重新置 PEIE/GIEL。写 ISR 时不要把 RETFIE 换成普通 return,也不要在低优先级 ISR 里手动置 GIEH,否则嵌套关系会被打乱。

四、现场保护:影子寄存器只有一级

高优先级中断有一个“快速现场保护”选项:WREG、BSR、STATUS 三个寄存器各有影子寄存器,进高优先级 ISR 时自动装入,执行 RETFIE 0x01 时自动装回。影子寄存器不可读,深度只有一级。手册专门加了一条注:如果高、低优先级都使能,快速保护不可靠——任何中断都会写影子寄存器,高优先级会覆盖低优先级刚存进去的值。

结论很直接:只用高优先级时,可以用 RETFIE 0x01 省掉三条保存指令;同时开两级时,两个 ISR 都老老实实用软件保存 WREG、BSR、STATUS。手册例 10-2 给的就是后者,进中断先 MOVWF/MOVFF 存到 RAM,退出前再恢复,最后 RETFIE 0x00。

五、3~4 TCY 的响应延时怎么算

外部中断(INT0、RB 电平变化)的响应延时是 3~4 个指令周期。中断在 Q4 采样,单周期指令在下一个周期的 Q2 应答,双周期指令在 Q1 应答,随后插入强制 NOP,把 PC 压栈,再把向量装进 PC。手册强调:单周期和双周期指令的响应延时完全相同,别按“指令长短”去估。

FOSCTCY3~4 TCY 延时
4 MHz1.0 µs3.0~4.0 µs
10 MHz0.4 µs1.2~1.6 µs
20 MHz0.2 µs0.6~0.8 µs

20 MHz 下 TCY=200 ns,3~4 TCY 就是 600~800 ns;10 MHz 下翻倍到 1.2~1.6 µs。这个数字只算到“进入向量”,还没算 ISR 里的现场保护和业务判断。对 1 ms 控制环来说不算大,但对微秒级捕获或高速通信,就要把这段固定开销算进去。

还有一个硬约束:MOVFF 指令把 PCL、TOSU、TOSH、TOSL 当目标寄存器时,必须关闭所有中断。这几条指令分两个周期改 PC 或堆栈,中途进中断会把返回地址写坏。

六、长写与中断:只留一个终止源

内部 EPROM 编程用长写,指令在长写期间停止执行,任何使能的中断都会终止长写。要保证编程时间,通常用一个定时器中断来定时并终止长写;手册建议只用这一个中断,避免别的中断提前把长写打断。写表场景还要注意标志位:进 ISR 先清标志,再处理,否则会反复进出。

这条规则和“中断越少越好”是两回事。长写期间不是不能开中断,而是不能开一堆不确定什么时候来的中断;把终止源收敛到一个定时器,时间才是可算的。

七、七步落地与验证

  1. 打开 IPEN,确认器件支持双向量。
  2. 按实时性把 IPR 各位重新分配,别沿用复位值。
  3. 先清 PIR 标志,再装 PIE 使能。
  4. 配 INTCON2/3 的外部中断边沿与优先级。
  5. 先开 GIEL,再开 GIEH,避免初始化过程中误入中断。
  6. 两个 ISR 都做软件现场保护,除非确定只用高优先级。
  7. 用示波器或 IO 翻转量 ISR 执行时间,确认高优先级不会把低优先级饿死。
/* IPEN=1;INT0 高优先级,TMR1 低优先级 */
    RCONbits.IPEN = 1;          /* 双向量生效 */
    IPR1 = 0x00;                /* 外设先全部低优先级 */
    INTCON2bits.INT0IP = 1;     /* INT0 抬成高优先级 */
    PIR1 = 0x00;                /* 清 TMR1IF 等标志 */
    PIE1bits.TMR1IE = 1;        /* TMR1 低优先级中断 */
    INTCONbits.INT0IF = 0;      /* 使能前先清标志 */
    INTCONbits.INT0IE = 1;
    INTCONbits.GIEL = 1;        /* 先开低优先级全局 */
    INTCONbits.GIEH = 1;        /* 再开高优先级全局 */

初始化顺序不要反过来。先开 GIEH 再配 PIE 和标志,初始化过程中只要有一个旧标志没清,程序就会立刻跳进 000008h,而那时 ISR 依赖的变量还没准备好。手册的通用例程也是先清 PIR1、装 PIE1、清 INTCON2/3,最后才写全局使能。

八、六个现场排查

现象根因改法
低优先级 ISR 从来不进IPR 没重配,复位值全是高优先级把该中断的 IPRx 位清 0,并开 GIEL
高优先级 ISR 返回后变量乱低优先级 ISR 也用了影子寄存器两级都开时改为软件保存 WREG/BSR/STATUS
中断进一次就卡死标志位没清,重复进入ISR 入口先清对应 PIR/INTCON 标志
初始化时莫名跳中断先开了 GIEH,旧标志还在先清 PIR、装 PIE,再开 GIEH/GIEL
返回地址偶发错误用 MOVFF 改 PCL/TOS 时没关中断这几条指令前后关中断
EEPROM 写一半失效长写期间被其他中断提前终止只保留一个定时器中断作为终止源

一句话总结:PIC18 的双向量不难配,难的是把优先级、现场保护和初始化顺序当成一套来设计;只用高优先级可以吃影子寄存器的红利,一旦开两级,就老老实实软件保存,并让高优先级 ISR 足够短。

还想接着看:PIC16C74A 体选切换与中断现场保护、Cortex-M3 异常模型与 NVIC 低延迟中断、dsPIC30F 输出比较与定时器中断。

本文基于 Microchip《PICmicro 高档单片机系列参考手册》DS39510A_CN 第 10 章“中断”技术资料整理优化。

需要定制开发?

沧州艾诺威电子 — 国家高新技术企业,20+项国家专利
嵌入式系统开发 · 物联网方案 · AI智能硬件 · 一站式交付

立即微信咨询

电话:13930711029 | 邮箱:tech@czinv.com | 24小时内响应