fxg2024 发表于 2025-2-20 14:55:43

CAN和LIN 的中断标志位 CANIF、LINIF工作原理?

CAN和LIN 的中断标志位 CANIF、LINIF工作原理?
看数据手册,在13.4.2中断请求寄存器这节介绍,CANIF、CAN2IF、LINIF三个中断标志位是只读。我理解就是只能读,不能修改;
但是在31.2.2 CAN总线中断控制寄存器介绍中,CANIF 和 CAN2IF 是CAN 总线中断请求标志位,需软件清零。但在实例程序中没有看到对CANIF 软件清零的程序。
32.2.2 LIN 总线中断控制寄存器(LINICR)介绍中,LINIF:LIN 总线中断请求标志位,硬件清零(读取 LSR 清零)。
所有想让大佬们帮忙给我权威的解释。


实例程序中:
开启CAN中断
CANICR = 0x02; //CAN 中断使能
AUXR2 |= 0x02; //CAN 模块被使能


CAN中断中断程序void CANBUS_Interrupt(void) interrupt 28
{
u8 isr;
isr = CanReadReg(ISR);
if((isr & 0x04) == 0x04)
{
CANAR = 0x03;
CANDR = 0x04; //CLR FLAG
}
if((isr & 0x08) == 0x08)
{
CANAR = 0x03;
CANDR = 0x08; //CLR FLAG
CAN_ID = CanReadMsg(RX_BUF); //接收 CAN 总线数据
CanSendMsg(CAN_ID+1,RX_BUF); //CANID 加 1,原样发送 CAN 总线数据
}
}
LIN中断初始化程序LINICR = 0x02; //LIN 模块中断使能
AUXR2 |= 0x01; //LIN 模块被使能LIN中断程序
void LinBUS_Interrupt(void) interrupt LIN_VECTOR
{
u8 isr;
isr = LinReadReg(LSR);
if((isr & 0x03) == 0x03) //接收到 Header, 处于 Ready 状态
{
isr = LinReadReg(LER);
if(isr == 0x00) //没有产生错误
{
P46 = ~P46;
isr = LinReadReg(LID);
if(isr == 0x12) //判断是否从机响应 ID
{
LinTxResponse(TX_BUF); //返回响应数据
}
else
{
RxFlag = 1;
}
}
}
else
{
isr = LinReadReg(LER); //读取清除错误寄存器
}
}



乘风飞扬 发表于 2025-2-20 16:55:23

CANIF/CAN2IF跟CAN中断/应答寄存器是联动的,只要清除了ISR寄存器里面的中断标志,CANIF/CAN2IF也会一起清除。
ISR寄存器是写"1"清除:

而LINIF是通过读取LSR寄存器清除的:


参考官方32G实验箱或者屠龙刀例程包里面的CAN/LIN总线例子编程即可。
void CANBUS1_Interrupt(void) interrupt CAN1_VECTOR
{
        u8 isr;
        u8 store;
        u8 arTemp;

        arTemp = CANAR;   //先CANAR现场保存,避免主循环里写完 CANAR 后产生中断,在中断里修改了 CANAR 内容
        store = AUXR2;      //后AUXR2现场保存
       
        AUXR2 &= ~0x08;                //选择CAN1模块
        isr = CanReadReg(ISR);

        if((isr & 0x04) == 0x04)//TI
        {
                CANAR = ISR;
                CANDR = 0x04;    //CLR FLAG
               
                B_Can1Send = 0;
        }       
        if((isr & 0x08) == 0x08)//RI
        {
                CANAR = ISR;
                CANDR = 0x08;    //CLR FLAG
       
                B_Can1Read = 1;
        }

        if((isr & 0x40) == 0x40)//ALI
        {
                CANAR = ISR;
                CANDR = 0x40;    //CLR FLAG
        }       

        if((isr & 0x20) == 0x20)//EWI
        {
                CANAR = MR;
                CANDR &= ~0x04;//清除 Reset Mode, 从BUS-OFF状态退出
               
                CANAR = ISR;
                CANDR = 0x20;    //CLR FLAG
        }       

        if((isr & 0x10) == 0x10)//EPI
        {
                CANAR = ISR;
                CANDR = 0x10;    //CLR FLAG
        }       

        if((isr & 0x02) == 0x02)//BEI
        {
                CANAR = ISR;
                CANDR = 0x02;    //CLR FLAG
        }       

        if((isr & 0x01) == 0x01)//DOI
        {
                CANAR = ISR;
                CANDR = 0x01;    //CLR FLAG
        }       

        AUXR2 = store;   //先AUXR2现场恢复
        CANAR = arTemp;    //后CANAR现场恢复
}

void LinBUS_Interrupt(void) interrupt LIN_VECTOR
{
        u8 isr;
        u8 arTemp;
        arTemp = LINAR;   //LINAR 现场保存,避免主循环里写完 LINAR 后产生中断,在中断里修改了 LINAR 内容
       
        isr = LinReadReg(LSR);
        if((isr & 0x03) == 0x03)
        {
                isr = LinReadReg(LER);
                if(isr == 0x00)                //No Error
                {
                        RxFlag = 1;
                }
        }
        else
        {
                isr = LinReadReg(LER);        //读取清除错误寄存器
        }

        LINAR = arTemp;    //LINAR 现场恢复
}

fxg2024 发表于 2025-3-4 09:31:03

乘风飞扬 发表于 2025-2-20 16:55
CANIF/CAN2IF跟CAN中断/应答寄存器是联动的,只要清除了ISR寄存器里面的中断标志,CANIF/CAN2IF也会一起清 ...

ISR寄存器中由多个标志位,是不是清除其任意一个标志位,CANIF/CAN2IF标志位都会清零

乘风飞扬 发表于 2025-3-4 09:39:01

fxg2024 发表于 2025-3-4 09:31
ISR寄存器中由多个标志位,是不是清除其任意一个标志位,CANIF/CAN2IF标志位都会清零 ...

CAN1/CAN2的ISR寄存器全部被清除时,对应的CANIF/CAN2IF也会被清除。
ISR寄存器只要有标志位没有清除,CANIF/CAN2IF就不会清除。
所以其实可以不用管CANIF/CAN2IF,只要处理好ISR寄存器就行。

fxg2024 发表于 2025-3-4 11:00:32

乘风飞扬 发表于 2025-3-4 09:39
CAN1/CAN2的ISR寄存器全部被清除时,对应的CANIF/CAN2IF也会被清除。
ISR寄存器只要有标志位没有清除,CA ...

好的
页: [1]
查看完整版本: CAN和LIN 的中断标志位 CANIF、LINIF工作原理?