找回密码
 立即注册
查看: 226|回复: 4

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

[复制链接]
  • 打卡等级:偶尔看看I
  • 打卡总天数:11
  • 最近打卡:2025-03-21 11:14:28

13

主题

21

回帖

211

积分

中级会员

积分
211
发表于 2025-2-20 14:55:43 | 显示全部楼层 |阅读模式
CAN和LIN 的中断标志位 CANIF、LINIF工作原理?
看数据手册,在13.4.2中断请求寄存器这节介绍,CANIF、CAN2IF、LINIF  三个中断标志位是只读。我理解就是只能读,不能修改;
但是在31.2.2 CAN总线中断控制寄存器介绍中,CANIF 和 CAN2IF 是CAN 总线中断请求标志位,需软件清零。但在实例程序中没有看到对CANIF 软件清零的程序。
32.2.2 LIN 总线中断控制寄存器(LINICR)介绍中,LINIFLIN 总线中断请求标志位,硬件清零(读取 LSR 清零)
所有想让大佬们帮忙给我权威的解释。


实例程序中:
开启CAN中断
  1. CANICR = 0x02; //CAN 中断使能
  2. AUXR2 |= 0x02; //CAN 模块被使能
复制代码



CAN中断中断程序
  1. void CANBUS_Interrupt(void) interrupt 28
  2. {
  3. u8 isr;
  4. isr = CanReadReg(ISR);
  5. if((isr & 0x04) == 0x04)
  6. {
  7. CANAR = 0x03;
  8. CANDR = 0x04; //CLR FLAG
  9. }
  10. if((isr & 0x08) == 0x08)
  11. {
  12. CANAR = 0x03;
  13. CANDR = 0x08; //CLR FLAG
  14. CAN_ID = CanReadMsg(RX_BUF); //接收 CAN 总线数据
  15. CanSendMsg(CAN_ID+1,RX_BUF); //CANID 加 1,原样发送 CAN 总线数据
  16. }
  17. }
复制代码

LIN中断初始化程序
  1. LINICR = 0x02; //LIN 模块中断使能
  2. AUXR2 |= 0x01; //LIN 模块被使能
复制代码
LIN中断程序
  1. void LinBUS_Interrupt(void) interrupt LIN_VECTOR
  2. {
  3. u8 isr;
  4. isr = LinReadReg(LSR);
  5. if((isr & 0x03) == 0x03) //接收到 Header, 处于 Ready 状态
  6. {
  7. isr = LinReadReg(LER);
  8. if(isr == 0x00) //没有产生错误
  9. {
  10. P46 = ~P46;
  11. isr = LinReadReg(LID);
  12. if(isr == 0x12) //判断是否从机响应 ID
  13. {
  14. LinTxResponse(TX_BUF); //返回响应数据
  15. }
  16. else
  17. {
  18. RxFlag = 1;
  19. }
  20. }
  21. }
  22. else
  23. {
  24. isr = LinReadReg(LER); //读取清除错误寄存器
  25. }
  26. }
复制代码




截图202406182206166244.jpg
回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:415
  • 最近打卡:2025-04-30 09:58:34
已绑定手机

39

主题

2006

回帖

6841

积分

论坛元老

积分
6841
发表于 2025-2-20 16:55:23 | 显示全部楼层
CANIF/CAN2IF跟CAN中断/应答寄存器是联动的,只要清除了ISR寄存器里面的中断标志,CANIF/CAN2IF也会一起清除。
ISR寄存器是写"1"清除:
截图202502201642027067.jpg
而LINIF是通过读取LSR寄存器清除的:
截图202502201652126000.jpg

参考官方32G实验箱或者屠龙刀例程包里面的CAN/LIN总线例子编程即可。
  1. void CANBUS1_Interrupt(void) interrupt CAN1_VECTOR
  2. {
  3.         u8 isr;
  4.         u8 store;
  5.         u8 arTemp;
  6.         arTemp = CANAR;     //先CANAR现场保存,避免主循环里写完 CANAR 后产生中断,在中断里修改了 CANAR 内容
  7.         store = AUXR2;      //后AUXR2现场保存
  8.        
  9.         AUXR2 &= ~0x08;                //选择CAN1模块
  10.         isr = CanReadReg(ISR);
  11.         if((isr & 0x04) == 0x04)  //TI
  12.         {
  13.                 CANAR = ISR;
  14.                 CANDR = 0x04;    //CLR FLAG
  15.                
  16.                 B_Can1Send = 0;
  17.         }       
  18.         if((isr & 0x08) == 0x08)  //RI
  19.         {
  20.                 CANAR = ISR;
  21.                 CANDR = 0x08;    //CLR FLAG
  22.        
  23.                 B_Can1Read = 1;
  24.         }
  25.         if((isr & 0x40) == 0x40)  //ALI
  26.         {
  27.                 CANAR = ISR;
  28.                 CANDR = 0x40;    //CLR FLAG
  29.         }       
  30.         if((isr & 0x20) == 0x20)  //EWI
  31.         {
  32.                 CANAR = MR;
  33.                 CANDR &= ~0x04;  //清除 Reset Mode, 从BUS-OFF状态退出
  34.                
  35.                 CANAR = ISR;
  36.                 CANDR = 0x20;    //CLR FLAG
  37.         }       
  38.         if((isr & 0x10) == 0x10)  //EPI
  39.         {
  40.                 CANAR = ISR;
  41.                 CANDR = 0x10;    //CLR FLAG
  42.         }       
  43.         if((isr & 0x02) == 0x02)  //BEI
  44.         {
  45.                 CANAR = ISR;
  46.                 CANDR = 0x02;    //CLR FLAG
  47.         }       
  48.         if((isr & 0x01) == 0x01)  //DOI
  49.         {
  50.                 CANAR = ISR;
  51.                 CANDR = 0x01;    //CLR FLAG
  52.         }       
  53.         AUXR2 = store;     //先AUXR2现场恢复
  54.         CANAR = arTemp;    //后CANAR现场恢复
  55. }
复制代码
  1. void LinBUS_Interrupt(void) interrupt LIN_VECTOR
  2. {
  3.         u8 isr;
  4.         u8 arTemp;
  5.         arTemp = LINAR;     //LINAR 现场保存,避免主循环里写完 LINAR 后产生中断,在中断里修改了 LINAR 内容
  6.        
  7.         isr = LinReadReg(LSR);
  8.         if((isr & 0x03) == 0x03)
  9.         {
  10.                 isr = LinReadReg(LER);
  11.                 if(isr == 0x00)                //No Error
  12.                 {
  13.                         RxFlag = 1;
  14.                 }
  15.         }
  16.         else
  17.         {
  18.                 isr = LinReadReg(LER);        //读取清除错误寄存器
  19.         }
  20.         LINAR = arTemp;    //LINAR 现场恢复
  21. }
复制代码
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:11
  • 最近打卡:2025-03-21 11:14:28

13

主题

21

回帖

211

积分

中级会员

积分
211
发表于 2025-3-4 09:31:03 | 显示全部楼层
乘风*** 发表于 2025-2-20 16:55
CANIF/CAN2IF跟CAN中断/应答寄存器是联动的,只要清除了ISR寄存器里面的中断标志,CANIF/CAN2IF也会一起清 ...

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

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:415
  • 最近打卡:2025-04-30 09:58:34
已绑定手机

39

主题

2006

回帖

6841

积分

论坛元老

积分
6841
发表于 2025-3-4 09:39:01 | 显示全部楼层
fxg2*** 发表于 2025-3-4 09:31
ISR寄存器中由多个标志位,是不是清除其任意一个标志位,CANIF/CAN2IF标志位都会清零 ...

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

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:11
  • 最近打卡:2025-03-21 11:14:28

13

主题

21

回帖

211

积分

中级会员

积分
211
发表于 2025-3-4 11:00:32 | 显示全部楼层
乘风*** 发表于 2025-3-4 09:39
CAN1/CAN2的ISR寄存器全部被清除时,对应的CANIF/CAN2IF也会被清除。
ISR寄存器只要有标志位没有清除,CA ...

好的
回复 支持 反对

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-5-2 09:04 , Processed in 0.150903 second(s), 77 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表