DSP CAN总线无法进如中断的解决办法
一个项目要用到TMS320LF2407 DSP,之前没用过,花了一天时间了解了一下基本操作,就开始调试CAN控制器。
使用CAN自测模式,设置邮箱3发送、邮箱2接收,并使能邮箱2的接收中断、高优先级,main.c如下:
#include "global.c"
void SystemInit();
void Timer1Init();
void KickDog();
void CANMBX_ISR();
void CAN_INIT();
unsigned int numled=0;
unsigned int CAN_FLAG; // 定义标志寄存
main()
{
unsigned int i=0;
unsigned int RCA0=0,RCB0=0,RCC0=0,RCD0=0,RCA1=0,RCB1=0,RCC1=0,RCD1=0;
SystemInit(); //系统初始化
MCRC=MCRC & 0xFF00; //IOE0-7设为IO口模式
PEDATDIR=0xFF00; //所有LED=0,
asm(" CLRC INTM "); // 中断使能
CAN_FLAG=0X00; // 清CAN用户标志,CAN_FLAG=01表示接收到数据
CAN_INIT(); // CAN初始化程序
while(1)
{
CANTCR=0X20; // MBX3请求发送
while(CANTCR&0X2000==0) // 等待发送应答
continue;
CANTCR=0X2000; // 清 TA3 和MIF3标志位
while(CAN_FLAG==0)
//while(CANRCR&0x0040!=0x0040)
continue; // 等待接收数据
CANRCR=0x0040; //清接收悬挂位
CAN_FLAG=0;
i++; // 清接收到标志
CANMDER=0X0000; // 邮箱不使能
CANMCR=0X0140; // CDR=1,数据改变请求
CANBX3A=CANBX3A+1; // 邮箱2中数据加1用来更新邮箱3中的数据
CANBX3B=CANBX3B+1;
CANBX3C=CANBX3C+1;
CANBX3D=CANBX3D+1;
CANMCR=0X04C0; // DBO=1,CDR=0,ABO=1,STM=1
CANMDER=0X04C; // ME2=ME3=1,MBX2接收, MBX3发送
RCA1=CANBX2A;
RCB1=CANBX2B;
RCC1=CANBX2C;
RCD1=CANBX2D;
}
}
void SystemInit()
{
asm(" SETC INTM ");
asm(" CLRC SXM ");
asm(" CLRC CNF ");
asm(" CLRC OVM ");
SCSR1=0x02FC;
WDCR=0x006F;
KickDog();
IFR=0xFFFF;
IMR=0x0003;
}
void Timer1Init()
{
EVAIMRA=0x0080; // 定时器1周期中断使能
EVAIFRA=0xFFFF; // 清除中断标志
GPTCONA=0x0000;
T1PR=2500; // 定时器1初值,定时0.4us*2500=1ms
T1CNT=0;
T1CON=0x144E; //增模式, TPS系数40M/16=2.5M,T1使能
}
void CAN_INIT()
{
MCRB=MCRB|0X0C0; // 设置IOPC6、IOPC7 为 CANRX,CANTX
CANIFR=0XFFFF; // 清所有CAN中断标志
CANLAM0H=0X7FFF; // 设置邮箱2、3的屏蔽ID寄存器
CANLAM0L=0XFFFF; // 0则ID必须匹配
CANMCR=0X1040; // CCR=1 改变配置请求
while(CANGSR&0X0010==0)continue; // 当CCE=1 时即可配置 BCR2,BCR1 寄存器
CANBCR2=0x01;
CANBCR1=0x0033;
CANMCR=CANMCR&0XEFFF; // CCR=0 改变配置结束请求
while(CANGSR&0X0010!=0)continue; // 只有当CEE=0时,BCR2,BCR1 寄存器配置成功
CANMDER=0X040; // 不使能邮箱,邮箱2设为接收方式
CANMCR=0X0143; // CDR=1,数据区改变请求
CANID2H=0X2447; // 设置邮箱2的控制字及ID
// IDE=0, AME=0, AAM=0
// 标准方式为MSGID2H[12-2]
CANID2L=0XFFFF;
CANCTRL2=0X08; // 设置控制域
// 数据长度DCL = 8,RTR=0 数据帧
CANBX2A=0X0000; // 邮箱2信息初始化
CANBX2B=0X0000;
CANBX2C=0X0000;
CANBX2D=0X0000;
CANID3H=0X2447; // 设置邮箱3的标识符
CANID3L=0XFFFF;
CANCTRL3=0X08; // RTR=0,DCL=8
CANBX3A=0X10; // 邮箱3信息初始化
CANBX3B=0X10;
CANBX3C=0X10;
CANBX3D=0X10;
CANMCR=0X04C0; // DBO=1,ABO=1,STM=1设置为自测试模式
CANMDER=0X4C; // ME3=1,MBX3 发送, ME2=1 接收
CANIMR=0X0400; // 中断MBX3 不使能 ,MBX2使能, 高中断优先级
CANIFR=0XFFFF; // 清全部中断标志
}
void interrupt c_int2()
{
if(PIVR!=0x27)
{ asm(" CLRC INTM ");
return;
}
T1CNT=0;
numled++;
EVAIFRA=0x80;
asm(" CLRC INTM ");
}
void interrupt c_int1() // 中断入口程序
{
switch(PIVR)
{
case 0x40:
CANRCR=0X040; // 复位 RMP2 和 MIF2
CAN_FLAG=1; // 置用户接收标志
break;
}
}
void KickDog()
{
WDKEY=0x5555;
WDKEY=0xAAAA;
}
但是调试发现,邮箱能正常发送和接受,就是进不去中断,查了一上午才解决问题。对于DSP的外设中断,INT1到INT6,在Define.asm中有相应的中断向量表与之对应,如下:
;建立中断向量表
.sect ".vectors"
RSVECT B _c_int0
INT1 B _c_int1
INT2 B _c_int2
INT3 B PHANTOM
INT4 B PHANTOM
INT5 B PHANTOM
INT6 B PHANTOM
对于邮箱2 的高优先级中断c_int2,一开始并没有在此定义,因此无法进入相应的中断,将原先的PHANTOM改为_c_int1就行了,即为其建立中断入口地址。_c_int与C语言的c_int是一样的。
PIVR是外设中断向量寄存器,用于存储最近一次被应答的外设中断的地址向量,其具体值可在中断源优先级和中断向量表中查的,对于每一个外设都有一个唯一的中断向量入口地址与之对应。
使用CAN自测模式,设置邮箱3发送、邮箱2接收,并使能邮箱2的接收中断、高优先级,main.c如下:
#include "global.c"
void SystemInit();
void Timer1Init();
void KickDog();
void CANMBX_ISR();
void CAN_INIT();
unsigned int numled=0;
unsigned int CAN_FLAG;
main()
{
}
void SystemInit()
{
}
void Timer1Init()
{
}
void CAN_INIT()
{
}
void interrupt
{
}
void interrupt
{
}
}
void KickDog()
{
}
但是调试发现,邮箱能正常发送和接受,就是进不去中断,查了一上午才解决问题。对于DSP的外设中断,INT1到INT6,在Define.asm中有相应的中断向量表与之对应,如下:
;建立中断向量表
RSVECT
INT1
INT2
INT3
INT4
INT5
INT6
PIVR是外设中断向量寄存器,用于存储最近一次被应答的外设中断的地址向量,其具体值可在中断源优先级和中断向量表中查的,对于每一个外设都有一个唯一的中断向量入口地址与之对应。
关键词: DSPCAN总线中

加入微信
获取电子行业最新资讯
搜索微信公众号:EEPW
或用微信扫描左侧二维码