|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
本文介绍DSP高效接收和发送不定长度的数据,该方法减小cpu的中断次数,经过长时间检验,该方法安全可靠效率最大。我使用的是28034只有4级FIFO,在优化前中断深度设置为1,cpu频繁中断,导致正常程序受影响。经过改进,设置发送中断深度为0级,接收中断为4级,只有在数据发送完成和接收满4个字节中断。
* W( N. n! b% V: G 接收流程为:等待接收中断—》读取4个fifo数据—》超时检查—》读取fifo剩余数据。这样就会接收完整的一帧数据。
7 M" p: [# a5 i* j: s1 X 发送流程:触发中断开始发送数据—》写入4个数据到发送fifo----》等到fifo为空中断–》写入下4个数据到fifo----》写入最后剩余数据。
9 b* K( V& S4 S具体如下:
* _' f0 S3 V% q& V(1)初始化配置
+ ?8 t ]' ~, l+ r0 l; c% ~void scia_init()
. J0 }( H; N; ]1 z2 i0 y4 H{5 w; A7 ]. n- J0 Q# }# y7 r
// Note: clocks were turned on to the SCIA peripheral( f& f7 H! |# h/ ~
// in the InitSysCtrl() function) S+ q8 }) s7 h
SciaRegs.SCICCR.all =0x0007; // 1 stop bit, No loopback6 z8 L p8 W7 m7 x+ S
// No parity,8 char bits,
- f) T7 K; k( c6 j! w# V$ k3 C0 O // async mode, idle-line protocol8 w; ^+ l! }& X
SciaRegs.SCICTL1.all =0x0003; // enable TX, RX, internal SCICLK,
5 U' q# n/ r% ~) _ // Disable RX ERR, SLEEP, TXWAKE
1 M2 Z7 T9 a, F: l SciaRegs.SCICTL2.bit.TXINTENA = 1;//使能发送中断7 [: w) }) f: _( x+ U" n2 I5 T
) r: ?! B8 ]6 T& l, w 0 @: ?; t# E1 T. n& ?
SciaRegs.SCICTL2.bit.RXBKINTENA = 1;//使能接收中断6 p8 H6 M$ X0 Z1 \$ e
# v4 E, \' }: s$ _7 B, C' {& u
//BRR = (LSPCLK / (SCI Asynchronous Baud * 8)) - 1 ,LSPCLK=30M,
' Y% s: H6 l t+ q+ b+ f //BRR = 0x0020, baud=115200; @7 B1 _. k" v! P
//BRR = 0x0007, baud=460800: U: A: d& n W" S; }) _
//BRR = 0x0061, baud=38400
9 b2 O) \) \% M, Y. N) z# Y4 s SciaRegs.SCIHBAUD =0x0000;
0 s4 g* ^8 n8 X! {7 a- E) ^2 z SciaRegs.SCILBAUD =0x0020;//
7 i+ h' J7 \* g( |+ u4 p9 Z SciaRegs.SCICCR.bit.LOOPBKENA =0; // Enable loop back) `/ C% f4 H3 u3 f; u Y# u/ d
SciaRegs.SCICCR.bit.STOPBITS = 2; //, z6 a! V6 \+ y- v% I% [2 Z- r
SciaRegs.SCIFFTX.all=0xC020;//设置发送中断为0级
* R5 |$ k& l% M4 L SciaRegs.SCIFFRX.all=0x0024;//设置接收中断为4级
3 R" M$ k- s( {. t r; y( e SciaRegs.SCIFFCT.all=0x0;
3 F2 ]; L) _# b2 u& J3 c* Y SciaRegs.SCIPRI.bit.FREE = 0;//仿真模式下是否自由运行
. X. U8 h5 t0 {' j9 U L, c' d; V2 e SciaRegs.SCICTL1.all =0x0023; // Relinquish SCI from Reset. U8 V4 B" v3 G- l& |. ^1 ~4 ^
SciaRegs.SCIFFTX.bit.TXFIFOXRESET=1; //发送FIFO复位+ a5 M! j# U+ N& V$ n* S$ m
SciaRegs.SCIFFRX.bit.RXFIFORESET=1; //接收FIFO复位 F- P& e) \5 U! y; `1 r
}9 { ~) H& Z6 t: N0 q
7 X8 w- R; N/ q; ~# A5 P
(2)接收中断和发送中断
: ~- j( p& \0 v4 ?$ z6 z( h( v9 ^8 q
interrupt void SCI1_RXD_isr(void)# Y" C% i5 u9 \) ~
{3 S; f5 ~: p! ?! `
UINT16 RxData;
' {* J& F. s1 S$ u6 N" N! m2 K0 m //RxData = SciaRegs.SCIRXBUF.all;. E' b( F, Q) E. I* J( S9 P' Y6 U7 T( b
//上一个数据帧应用层未取走,数据丢弃( V! E, l- G3 z! e2 U4 ]& U# ^
if ((KeyBoardRxFrame.status == UART_FRAME_RX_END) || (KeyBoardRxFrame.index >= 40))! M- `% a# v) s3 k/ Y
{8 o3 ]7 q# }2 G$ B5 Y3 b7 i
KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;
/ k# ]7 p# \/ |6 _$ H+ I* N7 b KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;
/ B" k ]/ A' _( E4 d! y9 o KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;
! h/ N' _7 U5 o( M& w) s* t- ?' X KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;+ N1 ?9 @+ L3 ~
}else
& C8 g- i' d. s! G1 ~3 {3 C {) O; I# R- P. E: _- l a0 c( c# F1 s
KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;+ T3 T( d! h0 F9 f* Y4 G- K& o
KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;! [: T. k. Y( i0 |6 h7 |
KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;
( J) f9 m$ I3 Q( r; r, O KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;
; q. ?9 u3 D/ [3 r$ _0 Z1 O KeyBoardRxFrame.ticker = KeyBoardRxFrame.spacetime;
5 g' O2 l" d& S }
9 M6 p, y. \9 K* V5 L , S( j! L3 S* u w$ k+ m
SciaRegs.SCIFFRX.bit.RXFFOVRCLR=1; // Clear OveRFlow flag$ |2 {. q- U. b* t; C# ]
SciaRegs.SCIFFRX.bit.RXFFINTCLR=1; // Clear Interrupt flag) M& k; y) t' n! P
3 \+ l+ p) n6 E6 X9 i# }$ i PieCtrlRegs.PIEACK.all|=0x100; // Issue PIE ack# f' H3 m B* A0 a
}) _4 _* |+ b% R! d, f
interrupt void SCI1_TXD_isr(void)8 ?( a" C- j5 @# v. P' p9 Q
{
6 { S7 b A' y0 o Uint16 i;
$ V( R; m k6 k* _, C+ V Uint16 len;
8 `: @& {" I( w$ | |0 V1 W- I2 Z // 发送一帧数据没有完成! A5 O( t% E: ^' m0 N4 w6 L
if(KeyBoardTxFrame.index + 4 < KeyBoardTxFrame.len) 7 f2 X2 l& P% }' v2 J0 ?* S; `4 P) @
{7 R8 X0 R8 u* U5 l+ S
SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];' U8 Q& g: i. k( k
SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];
2 a2 ^* l' \% O# Z% i7 r' L0 m SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];6 V7 X5 L2 D3 y4 Q% ?
SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++]; Q0 h* e8 y& |: v' h
3 [$ Z7 \* T( q, h5 t8 E# [8 V7 f SciaRegs.SCIFFTX.bit.TXFFINTCLR=1; // Clear SCI Interrupt flag清除后产生中断
* U' j1 U* E6 F# b( f1 m8 D }9 }8 e# l! d! r
else
6 V7 C" b; G' o# m% L3 Y& O! } {
$ v- `, k4 B& j, t3 P9 f+ K' ?, H //发送剩下的数据6 |3 K0 M% f r5 h
len = KeyBoardTxFrame.len - KeyBoardTxFrame.index;
: X. j d3 V" Y( r. o. u* i for(i = 0; (len <= 40) && (i < len); i++)6 k" ~: N' E& F& I# W
{
V" j# |& K! C4 d: o SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];8 `9 A" J+ J3 V8 k, z7 V3 C' D4 z
}' N& i/ {2 {' j2 q' O; ]2 s: c
2 F5 t& F1 _: \: ]6 _ //一帧数据结束/ w* D( l; ^, L2 z
if(KeyBoardTxFrame.len)+ F' `+ p7 B! {: a5 v( p& w
{5 }! v& U6 S; V9 o, S
KeyBoardTxFrame.status = UART_FRAME_TX_IT_END;2 E. m* t0 h* ]) Q+ o4 x
}% v8 |$ k1 _8 I6 k8 C
}
% ?4 g- _4 c. z' z8 D; ^5 H PieCtrlRegs.PIEACK.all|=0x100; // Issue PIE ACK: r3 R# Y. c- ]% z7 a
}7 e2 X7 S: W8 d6 o. E
+ _" L0 L) `. n0 o% w9 l
(3)读取不到4个字节的数据: \ Z. t' w o0 c. g- Z
, O1 A7 g! m, k7 _void SCI1_RX_FIFO(UART_FRAME *pFrame)9 E) ~2 A/ ~8 e1 C. F6 v) F5 ~
{( m! [+ _6 ` x) d* ]. h
Uint16 maxNum = 0;5 H5 z* H" Y+ Y1 p
while(SciaRegs.SCIFFRX.bit.RXFFST && maxNum < 4)
& A! \, p2 Q/ `, J {
$ W8 i6 F: L2 a2 w, o pFrame->pdata[pFrame->index++] = SciaRegs.SCIRXBUF.all;
( a" d. j8 H+ U. \/ x maxNum++;+ X, y3 d. l" E3 K4 N7 z3 ]8 e
}5 r7 ~" G8 K8 \
}
/ W0 D, F# A( L, _6 ~/ z9 ~- {. c/ R6 s1 J9 C
(4)在应用程序需要2ms周期查询接收数据是否结束
# y; G" `2 }9 Y3 R" X" [2 R0 e5 nstatic void KeyboardJudgeRxFinish(void)5 x$ B2 h3 |0 I& S$ a& T _
{
; ~2 ]7 ]5 @+ _ //超时或数据长度大于40一帧接收完成 h! W: v& F; I7 \7 a
if(((KeyBoardRxFrame.ticker <= 0)&&(KeyBoardRxFrame.index > 0)) || KeyBoardRxFrame.index >= 40)
( {! R0 D- ?) F0 Z# j O {' H3 g7 Y' k4 a) m; {1 F
SCI1_RX_FIFO(&KeyBoardRxFrame);% E+ t: G8 f3 l8 f9 J
KeyBoardRxFrame.len = KeyBoardRxFrame.index;
7 x' H- O' I3 p' C# s KeyBoardRxFrame.status = UART_FRAME_RX_END;//数据接收完成,应用可以取走数据% M5 a3 M1 i' u5 l v! y- M, m
}
9 i1 h1 w6 d E0 E if(KeyBoardRxFrame.ticker > 0)2 d5 z2 M" E2 ^$ U2 F% z
{: ?) A! y6 _( k8 F" Y# r+ L+ O
KeyBoardRxFrame.ticker--;
: ` R8 g V" o, P( u( S; b9 |3 C }
3 f$ y5 o9 C2 E; X+ J' Q: M}
0 g: W* N& @" e' J9 p K' |! H- V$ _% E! G) T0 e! b |
(6)发送' y# e- \0 o3 l: q
void Keyboardrs485TxFrame(void)+ g& c! [1 s5 h; Z
{7 b L4 B/ i- [: ^' A) v! J
SCI1SetTxMode();' z+ `2 i- a( ?8 g2 h' m8 l
//如果当前帧正在发送,又重新请求发送一帧数据,则请求的数据丢弃
$ s' T- g9 i) `7 O if(KeyBoardTxFrame.status == UART_FRAME_TX_ING)7 n0 l7 P! }( D ?: q( v6 W1 c
{
8 b: l# _- B6 Q# G. S7 w return ;( ?1 |& r- s- T7 t9 z2 j
}
: z3 K0 M9 l5 c# G$ o @; H/ \ //启动发送第一个字节后,产生中断,接着数据在中断中发送完成0 r* B2 p+ o: ?3 I' ~. v
KeyBoardTxFrame.index = 0;
: s1 U3 Z t2 u SciaRegs.SCIFFTX.bit.TXFFINTCLR=1;//启动发送中断
9 W1 ?! x1 H$ R F KeyBoardTxFrame.status = UART_FRAME_TX_ING;& \+ |+ _7 n4 X! O# L8 ~5 L/ U
}3 W. @% \ [" y
|
|