EDA365电子论坛网
标题:
DSP CAN总线无法进入中断的解决办法
[打印本页]
作者:
geronimo123
时间:
2021-5-12 15:28
标题:
DSP CAN总线无法进入中断的解决办法
一个项目要用到TMS320LF2407
DSP
,之前没用过,花了一天时间了解了一下基本操作,就开始调试CAN控制器。
4 U: U% I$ p0 L- M7 @. B
使用CAN自测模式,设置邮箱3发送、邮箱2接收,并使能邮箱2的接收
中断
、高优先级,main.c如下:
( D2 J2 m9 I3 ^) F
+ \/ N" `: k+ B5 p4 }$ Y
#include "global.c"
* [8 L' u- [4 h( D/ v* E9 Y- t" |" u& `
void SystemInit();
* m& F' O; O+ V( k& T7 }7 Y
void Timer1Init();
3 v* ^; J9 Q& Y
void KickDog();
* o$ U3 `# l" Y+ x* i0 g
void CANMBX_ISR();
5 F! G x# ?' ]- i, D
void CAN_INIT();
( @ D$ T5 u' I$ @
unsigned int num
led
=0;
+ }( X4 p% n3 f' n3 j# `7 V
unsigned int CAN_FLAG;
// 定义标志寄存
/ S) V8 P* M4 T. D
" {2 K2 J) |5 z7 h
: w0 ^# i( V6 h9 Z
main()
* P* H4 \# J1 [3 ^# k
{
- u& _: `5 ]8 [+ ~* c. D4 y6 F# U
unsigned int i=0;
1 m1 D5 t$ B) I6 |8 Y1 C3 ]& o
unsigned int RCA0=0,RCB0=0,RCC0=0,RCD0=0,RCA1=0,RCB1=0,RCC1=0,RCD1=0;
& z$ k. V' T( A! `
SystemInit();
//系统初始化
4 [3 n" a" b0 f6 h
' B( O7 R- A4 ^8 R6 _- H4 [
MCRC=MCRC & 0xFF00;
//IOE0-7设为IO口模式
6 O5 ?- M2 P' K+ Z( P. G6 q
PEDATDIR=0xFF00;
//所有
LED
=0,
9 K: e: R: C! c& b9 Y
asm(" CLRC INTM ");
// 中断使能
0 T' X2 U" U }; V, D
CAN_FLAG=0X00;
// 清CAN用户标志,CAN_FLAG=01表示接收到数据
; o' e8 ^6 H2 H" r( A
CAN_INIT();
// CAN初始化程序
+ N3 C7 Z% S ^* K+ T0 x1 ^& u
while(1)
& \ t9 q7 f: O' h5 | O4 U0 y' n* C: b
{
7 v9 @+ k" r1 S; y3 q1 N2 d7 y
CANTCR=0X20;
// MBX3请求发送
0 a# H* `9 B. [. f
while(CANTCR&0X2000==0)
// 等待发送应答
+ S$ [4 r, W+ M0 p y% T+ A! }. U
continue;
+ r7 Y0 m. r# `4 H, W+ G
CANTCR=0X2000;
// 清 TA3 和MIF3标志位
8 N. Z) W! M" R# B5 [" G/ T
while(CAN_FLAG==0)
2 E, o0 A* g& @9 A0 h% X
//while(CANRCR&0x0040!=0x0040)
1 A% @/ o& t' J: W
continue;
// 等待接收数据
% j( J- r2 E7 Q. o; d2 o
CANRCR=0x0040;
//清接收悬挂位
' J: V; w' ]8 r, I
CAN_FLAG=0;
% K9 E) M6 x! A6 ?7 [; L6 D
i++;
// 清接收到标志
& G/ ~4 E) }+ P* y! b2 w
CANMDER=0X0000;
// 邮箱不使能
- l% k- Z# `8 ~* r! B# ?6 ?
CANMCR=0X0140;
//
CDR=1,数据改变请求
, k; M4 l3 }9 x3 m2 f
9 F. R9 p6 y7 d6 B
CANBX3A=CANBX3A+1;
// 邮箱2中数据加1用来更新邮箱3中的数据
& V6 G3 \/ i6 Z& T
CANBX3B=CANBX3B+1;
! I! F4 ], E) S
CANBX3C=CANBX3C+1;
! c. g3 }$ h$ Q. ^" n; x
CANBX3D=CANBX3D+1;
7 m+ \* G: j* T5 X; n
CANMCR=0X04C0;
//
DBO=1,CDR=0,ABO=1,STM=1
0 l0 I! _* d, \# w
CANMDER=0X04C;
//
ME2=ME3=1,MBX2接收, MBX3发送
+ M' F y) D- Y
8 u1 m8 F. C; N5 J2 X
RCA1=CANBX2A;
?" s/ z1 g2 ]! y$ j O
RCB1=CANBX2B;
: j, C- |0 {1 u6 g$ T4 F; i+ v
RCC1=CANBX2C;
3 t# ]) E$ p7 b3 `7 o$ Y
RCD1=CANBX2D;
0 P( b# S8 {/ ^5 C
. ?. U% D$ H2 T1 Q% Q$ [
f W3 N' p F6 f6 f- J
}
7 D1 M8 J9 J5 Y' [! O: x$ e) Z
}
( N; ^ I/ E4 p" R% _# E$ D0 k; C: j
void SystemInit()
) T2 @7 d) o# Z+ M+ M/ d
{
7 e. b- S$ l! t2 [# P
. K" Q) }2 R8 ~
asm(" SETC
INTM ");
2 ^+ m( Q; S M. i* r8 I0 z& q
asm(" CLRC
SXM
");
1 Z. G. H8 V M& L
asm(" CLRC
CNF
");
$ `% s9 g* D# `' O) p* y. {0 {
asm(" CLRC
OVM
");
9 Q) O( @+ s- u9 B( V3 G7 D
SCSR1=0x02FC;
1 l4 {# F7 `$ k4 z" {$ x9 Y
WDCR=0x006F;
5 k5 _8 Y. y+ q
KickDog();
" w3 J$ R5 [( v& _$ M7 W, K
IFR=0xFFFF;
) F# C. K+ u+ E/ d% n) R- I2 B! M
IMR=0x0003;
) S4 q& j9 r9 ?/ a8 d. B% s+ U
- M) X( ]- P! g0 \" I7 c3 g
}
0 X( |/ s3 Q# v6 @8 z3 V7 _
, Q0 O# y1 W! S" s+ [3 o
void Timer1Init()
* \0 d4 F+ R/ m% z, p
{
5 I8 D- W+ V( m# A Y5 Q( G
" v6 u' v" k/ M6 i1 H% g7 \, {
EVAIMRA=0x0080;
//
定时器1周期中断使能
& |+ e, u3 l6 c+ I7 Y; e: H
EVAIFRA=0xFFFF;
//
清除中断标志
& k' i4 l" r! g/ [4 Q4 z
GPTCONA=0x0000;
0 _- U. g$ V1 e0 ~3 m
T1PR=2500;
//
定时器1初值,定时0.4us*2500=1ms
0 _! R9 y- u# u* w1 `! P. c- V6 k6 v
T1CNT=0;
: e1 V# S- V1 K% W- U+ O
T1CON=0x144E;
//增模式, TPS系数40M/16=2.5M,T1使能
# g) c% A" F- P0 M) W
w0 V& E( `' {, ~
}
4 I, v8 ]6 @* }
void CAN_INIT()
! U2 L! M2 G0 N3 K# u: U( W' e
{
/ x7 C$ L; h m5 Y9 L0 r, X7 a
MCRB=MCRB|0X0C0;
// 设置IOPC6、IOPC7 为 CANRX,CANTX
' I; `) O+ A. h N- q, w8 Z
CANIFR=0XFFFF;
// 清所有CAN中断标志
: f$ y+ u0 Q/ i6 U3 w
CANLAM0H=0X7FFF;
// 设置邮箱2、3的屏蔽ID寄存器
1 q8 G$ ]1 D2 n6 }, |- w
CANLAM0L=0XFFFF;
// 0则ID必须匹配
1 @) U0 d. U/ a% \/ ]7 l3 L
CANMCR=0X1040;
//
CCR=1 改变配置请求
6 h5 C1 b2 X6 t! U0 P
while(CANGSR&0X0010==0)continue;
// 当CCE=1 时即可配置 BCR2,BCR1 寄存器
1 J' Y+ ]7 l- Z; @/ f
CANBCR2=0x01;
5 H B$ B9 o% J* U0 u( p
CANBCR1=0x0033;
' H4 L, ^0 _6 I# {0 @; u5 c; H
CANMCR=CANMCR&0XEFFF;
//
CCR=0 改变配置结束请求
# r% D* x/ A: B
while(CANGSR&0X0010!=0)continue;
// 只有当CEE=0时,BCR2,BCR1 寄存器配置成功
, o: s) U: D' J4 o4 d0 O( W: E. r0 \
CANMDER=0X040;
// 不使能邮箱,邮箱2设为接收方式
. b! @' Y' U, ]7 L$ h% z
CANMCR=0X0143;
//
CDR=1,数据区改变请求
' Q$ j3 p8 }3 R) r+ O
CANID2H=0X2447;
// 设置邮箱2的控制字及ID
# Z6 |- y0 |. d) D
//
IDE=0, AME=0, AAM=0
; c* G' I/ h7 T" }
// 标准方式为MSGID2H[12-2]
7 h( o+ u2 \0 E
CANID2L=0XFFFF;
5 K# Y+ ?; ]; W+ ~3 u" f
CANCTRL2=0X08;
// 设置控制域
5 }% x& v0 D4 {$ [: C; d
// 数据长度DCL = 8,RTR=0 数据帧
1 c8 X/ Q1 a) r
CANBX2A=0X0000;
// 邮箱2信息初始化
5 x5 b9 z3 h) ^7 R
CANBX2B=0X0000;
& \' {' u. K9 R% h [
CANBX2C=0X0000;
* l: j+ D7 g; k. M8 L; {. W! I
CANBX2D=0X0000;
: S% \$ {6 v3 I+ K4 O/ O
CANID3H=0X2447;
// 设置邮箱3的标识符
; D; d0 W# x! b( k2 \
CANID3L=0XFFFF;
! n8 X- ~/ m, z0 R0 x$ T0 @
CANCTRL3=0X08;
//
RTR=0,DCL=8
6 b; d2 K w5 A6 u6 [2 K
CANBX3A=0X10;
// 邮箱3信息初始化
: }3 ?2 s: X+ S- T* z Z5 {
CANBX3B=0X10;
& C0 k7 G* g: J9 I- u. q8 r
CANBX3C=0X10;
: |* m, x/ r( \* `' w
CANBX3D=0X10;
0 n$ Z) [8 Z( O, t
CANMCR=0X04C0;
//
DBO=1,ABO=1,STM=1设置为自测试模式
- T9 t7 P2 u7 e- I) t& Z5 l
CANMDER=0X4C;
//
ME3=1,MBX3 发送, ME2=1 接收
. h1 o8 \3 t) @; n9 J
CANIMR=0X0400;
// 中断MBX3 不使能 ,MBX2使能, 高中断优先级
: ^' h5 x: g; k! F Z4 P7 W+ Z
CANIFR=0XFFFF;
// 清全部中断标志
9 ~: R7 g0 f5 `
}
' a2 U+ r4 h( X7 d7 Q
& d* } H6 R% [7 r( X: D. W! }
8 |7 Z0 [: R0 c" n/ _
void
interrupt
c_int2()
- S T+ k& @4 y
{
2 c: H- u8 W) }* u5 V8 A% F- y
4 O1 R( x: k9 }2 }! u
if(PIVR!=0x27)
. L ]+ v% Y9 E1 g/ w: c; |1 F
{
asm(" CLRC INTM ");
$ I! h0 A; g9 `1 V! e
return;
5 Y* X# V9 X% H: w) j
}
$ e; Z* M4 k9 h- C9 ?% L. `
T1CNT=0;
9 T) E. e6 L2 w) X9 v5 N
numled++;
3 g. i5 @: o* R3 s( t. g% U
& j" U3 i. Y$ u# X! z# F# T
EVAIFRA=0x80;
% n# O+ G2 l; H7 o, Q; n8 h" s/ \% Y
asm(" CLRC
INTM ");
6 l8 e. ^$ Y* T5 T: ~; L2 t
, R, u. ^* M; c: }& s
}
& j2 N+ x+ N$ n0 V# O; I, {8 S; d
void interrupt
c_int1()
// 中断入口程序
7 H4 W, w. Z9 ?1 K9 @
{
9 c3 U) h C3 z' U5 T
switch(PIVR)
% Y' O6 h, t0 F9 l( z: n
{
+ [6 o2 z# c( R- V8 n- _
case 0x40:
. g; i5 J" m/ ^1 B
CANRCR=0X040;
// 复位 RMP2 和 MIF2
. q9 h. J% l9 L& R2 j
CAN_FLAG=1;
// 置用户接收标志
" m3 g W4 H* J0 | @5 l% w ~
: }* [2 z* ~# D* { P/ O8 H
break;
D" g P4 S. q7 b i% a! D: B0 W
}
7 R$ T0 ]# N: V. f/ O
}
8 [5 z. a; P9 P
/ b* c, w! K( n+ }* m5 y. p
void KickDog()
$ t' V) F% N# C# c
{
- A' c( c& W" N
WDKEY=0x5555;
7 g! W8 }" j; I! P/ g3 \* e) t8 O" }
WDKEY=0xAAAA;
. U; K2 o- L7 \* I9 [
}
1 Z7 }6 e$ d+ _" G$ O) }+ J( [
但是调试发现,邮箱能正常发送和接受,就是进不去中断,查了一上午才解决问题。对于DSP的外设中断,INT1到INT6,在Define.asm中有相应的中断向量表与之对应,如下:
: D0 T g5 U2 Z5 [
;建立中断向量表
) [5 ~! z, r! m% I( ^
.sect
".vectors"
4 @) f6 _5 h$ _' W" ^: q
RSVECT
B
_c_int0
0 e5 G9 t1 d. s. r) I* u) R/ J
INT1
B
_c_int1
; Z3 ^5 q. l1 {2 O. [
INT2
B
_c_int2
8 c4 }1 L1 a% N5 T
INT3
B
PHANTOM
" G( z+ z. Z2 j8 M: M; K
INT4
B
PHANTOM
& ~$ }+ D( ~# X8 v& R, ?4 Y$ W
INT5
B
PHANTOM
- m1 ?3 t/ F6 w+ y
INT6
B
PHANTOM
- f: q, |+ h% H* ^8 d4 m
对于邮箱2 的高优先级中断c_int2,一开始并没有在此定义,因此无法进入相应的中断,将原先的PHANTOM改为_c_int1就行了,即为其建立中断入口地址。_c_int与C语言的c_int是一样的。
; ~# |- a7 F5 T3 J3 k
PIVR是外设中断向量寄存器,用于存储最近一次被应答的外设中断的地址向量,其具体值可在中断源优先级和中断向量表中查的,对于每一个外设都有一个唯一的中断向量入口地址与之对应。
: ?3 v% c% K( i& _: T9 Y( D$ R
作者:
nevadaooo
时间:
2021-5-12 15:50
PIVR是外设中断向量寄存器,用于存储最近一次被应答的外设中断的地址向量
作者:
modengxian111
时间:
2021-5-12 17:42
学习了
作者:
nevadaooo
时间:
2021-5-12 18:34
先收藏了,省的后面找不到
作者:
shapeofyou888
时间:
2021-6-10 18:11
实用的分享
欢迎光临 EDA365电子论坛网 (https://bbs.eda365.com/)
Powered by Discuz! X3.2