|
有个疑问想请教一下,该单片机的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.898ns(>=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 = 2640
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 = 0x2647; //给位定时器赋值
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中断服务子程序,我发现只要收到数据就进入中断,不管接收滤波什么要求, |
阿莫论坛20周年了!感谢大家的支持与爱护!!
曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……
|