视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
C8051F040的CAN中断
2025-10-03 14:40:43 责编:小OO
文档
有个疑问想请教一下,该单片机的CAN中断的产生是不是不依赖于接收滤波的结果?就是说无论报文是否符合该节点的滤波要求,CAN中断都会发生?非常感谢您的帮助

/*******************************************************************

** 函数名称 init_msg_object_RX

** 函数功能:接收初始化函数

** 输入参数:MsgNum:消息对象号

** 输出参数:无

********************************************************************/

void init_msg_object_RX(char MsgNum,unsigned char id)

{

unsigned char SFRPAGE_SAVE;

unsigned int temp;

SFRPAGE_SAVE = SFRPAGE;

SFRPAGE = CAN0_PAGE;

CAN0ADR = IF2CMDMSK; //指向IF2命令掩码寄存器

// CAN0DAT = 0x00bb;

CAN0DAT = 0x00fb;

/*IF2 Command Mask Registers =0x00bb

WR/RD=1,Mask=0,Arb=1,Control=1,ClrIntPnd=1,TxRqst=0,DataA=1,DataB=1,一次发送8字节数据*/

CAN0ADR = IF2MSK1; //指向IF2掩码寄存器1

CAN0DAT = 0x0000;

CAN0ADR = IF2MSK2; //指向IF2掩码寄存器2

CAN0DAT = 0xffff;

////////////////////////////////////////////////

CAN0ADR = IF2ARB1; //指向IF2仲裁寄存器

CAN0DAT = 0x0000; //仲裁寄存器1

/*IF2 Arbitration Registers1 =0x0000,即ID15-0=0*/

temp=id<<2;//标准id为ID28-ID18,所以要左移2位

temp&=0x1fff;

temp|=0x8000;

CAN0DAT = temp; //设置消息有效位,没有扩展ID,方向为接收

/*IF2 Arbitration Registers2=100(id)00b

MsgVal=1,Xtd=0,为标准模式,扩展ID无效,Dir=0,为接收*/

CAN0DAT = 0x1488; //IF2消息控制寄存器,设置RXIE,禁止远程桢

/*IF2 Message Control Registers=0x0488

NewDat=0,MsgLst=0,IntPnd=0,UMask=1,TxIE=0,RxIE=1,接收中断使能;RmtEn=0,TxRqst=0

EoB=1,DLC3-0=1000,即数据长度为8*/

CAN0ADR = IF2CMDRQST; //指向命令请求寄存器

CAN0DATL = MsgNum; //写消息对象号,即对哪个消息对象进行操作

/*IF2 Command Request Registers=MsgNum,将以上配置写入MsgNum号消息*/

//3-6个CAN时钟周期后,IF寄存器中的内容被移到CAN存储器的消息对象中

SFRPAGE = SFRPAGE_SAVE;

}

/*************************************************************************

** 函数名称:init_msg_object_TX

** 函数功能:发送初始化函数

** 输入参数:MsgNum:消息对象号

** 输出参数:无

***************************************************************************/

void init_msg_object_TX(char MsgNum,unsigned char id)

{

unsigned char SFRPAGE_SAVE = SFRPAGE;

unsigned int temp;

SFRPAGE = CAN0_PAGE;

CAN0ADR = IF1CMDMSK; //指向命令掩码寄存器

CAN0DAT = 0x00b3; //设为写,改变所有的消息对象除了标识掩码位,将数据字节0-7发送到消息对象

/*IF1 Command Mask Registers =0x00b3

WR/RD=1,Mask=0,Arb=1,Control=1,ClrIntPnd=0,TxRqst=0,DataA=1,

DataB=1,一次发送8字节数据*/

CAN0ADR = IF1ARB1; //指向IF1仲裁寄存器1

CAN0DAT = 0x0000; //ID15-0:0000;将仲裁ID设为最高优先级

/*IF1 Arbitration Registers1 =0x0000,即ID15-0=0*/

temp=id<<2;//标准id为ID28-ID18,所以要左移2位

temp&=0x1fff;

temp|=0xa000;

CAN0DAT = temp; //自动增加地址到IF1仲裁寄存器2

/*IF1 Arbitration Registers2=101(id)00b

MsgVal=1,Xtd=0,为标准模式,扩展ID无效,Dir=1,为发送*/

//设置消息有效位,没有扩展ID,方向为写

CAN0DAT = 0x0088; //IF1消息控制寄存器:DLC = 1,禁止远程桢

/*IF1 Message Control Registers=0x0088

NewDat=0,MsgLst=0,IntPnd=0,UMask=0,TxIE=0,RxIE=0,RmtEn=0,TxRqst=0

EoB=1,DLC3-0=1000,即数据长度为8*/

CAN0ADR = IF1CMDRQST; //指向IF1命令请求寄存器

CAN0DAT = MsgNum; //写消息对象号,即对哪个消息对象操作

/*IF1 Command Request Registers=MsgNum,将以上配置写入MsgNum号消息*/

//3-6个CAN时钟后期后,IF寄存器中的内容将被移到CAN存储器的消息对象中

SFRPAGE = SFRPAGE_SAVE;

}

/*****************************************************************************

** 函数名称:start_CAN

** 函数功能:CAN初始化设置函数

** 输入参数:无

** 输出参数:无

*****************************************************************************/

void start_CAN(void)

{

/************************************************************************/

/*以下给出CAN位定时的计算过程:

System clock f_sys = 11.0592Mhz

System clock period t_sys = 1/f_sys = 90.422454 ns

CAN time quantum tq = t_sys*8 (at BRP = 7)

Desired bit rate is 125Kbit/s,desired bit rate + 0.5381%

CAN bus length = 10m, with 5 ns/m signal delay time

propagation delay time : 2*(transceiver loop delay + bus line delay ) = 400ns(CAN节点间传输的最大往返延迟)

prop_seg = 5 tq = 3616.8ns(>=400ns)

Sync_Seg = 1 tq

Phase_seg1 + Phase-seg2 = (11-6) tq = 5 tq

Phase_seg1 <= Phase_Seg2, => Phase_seg1 = 2 tq and Phase_Seg2 = 3 tq

SJW = (min(Phase_Seg1, 4) tq = 2 tq

TSEG1 = (Prop_Seg + Phase_Seg1 - 1) = 6

TSEG2 = (Phase_Seg2 - 1) = 2

SJW_p = (SJW - 1) = 1

Bit Timing Register = BRP + SJW_p*0x0040 = TSEG1*0x0100 + TSEG2*0x1000 = 20

Clock tolerance df :

A: df < min(Phase_Seg1, Phase_Seg2) / (2 * (13*bit_time - Phase_Seg2))

B: df < SJW / (20 * bit_time)

A: df < 2/(2*(13*11-3)) = 1/(141-3) = 1/138 = 0.7246%

B: df < 2/(20*11) = 1/110 = 0.9091%

Actual clock tolerance is 0.7246% - 0.5381% = 0.1865% (no problem for quartz)

*/

/*************************************************************************************/

unsigned char SFRPAGE_SAVE = SFRPAGE;

SFRPAGE = CAN0_PAGE;

CAN0CN |=

0x41; //使能CCE位和INIT位

CAN0ADR = BITREG; //指向位定时寄存器

CAN0DAT = 0x27; //给位定时器赋值

CAN0ADR = IF1CMDMSK; //指向命令掩码寄存器1

//设置CAN RAM为写,写数据字节,置位TXrqst/NewDat, Clr IntPnd,将数据字节0-7发送到消息对象

CAN0DAT = 0x0087;

CAN0ADR = IF2CMDMSK; //指向命令掩码器2

//设置CAN RAM为读,发送控制位到IF2消息缓冲寄存器,清除消息对象中的IntPnd,消除消息对象中的NewDat位,访问数据字节0-7

CAN0DATL = 0x1f; //设置接收;读CAN RAM,读数据字节

CAN0CN |= 0x06; //全局初始化IE和SIE,使能中断

CAN0CN &= ~0x41; //清除CCE和INIT位,正常运行CAN

SFRPAGE = SFRPAGE_SAVE;

}

/************************************************************************

** 函数名称:ISRname

** 函数功能:CAN中断服务程序

** 输入参数:

** 输出参数:

*************************************************************************/

void ISRname(void) interrupt 19

{

char SFRPAGE_SAVE = SFRPAGE;

SFRPAGE = CAN0_PAGE;

status = CAN0STA;

if((status & 0x10) != 0)

{

//Rxok位为1,则是由于接收引起的中断

CAN0STA = (CAN0STA & 0xef) | 0x07; //复位Txok,设置LEC无变化

/*read message number from CAN INTREG*/

RX_FLAG = 1;

}

if((status & 0x08) != 0)

{

//Txok位为1,则是由于发送引起的中断

CAN0STA = (CAN0STA & 0xf7) | 0x07; //复位Txok,设置LEC无变化

TX_FLAG = 0; //发送完成

}

if(((status & 0x07) != 0) && ((status & 0x07) != 7))

{

//错误中断,改变LEC

CAN0STA = CAN0STA | 0x07; //设置LEC无变化

}

SFRPAGE = SFRPAGE_SAVE;

}

这是CAN中断服务子程序,我发现只要收到数据就进入中断,不管接收滤波什么要求,下载本文

显示全文
专题