|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
本文介绍DSP高效接收和发送不定长度的数据,该方法减小cpu的中断次数,经过长时间检验,该方法安全可靠效率最大。我使用的是28034只有4级FIFO,在优化前中断深度设置为1,cpu频繁中断,导致正常程序受影响。经过改进,设置发送中断深度为0级,接收中断为4级,只有在数据发送完成和接收满4个字节中断。
3 ]7 G i( G+ b) v3 W* O% h接收流程为:等待接收中断—》读取4个fifo数据—》超时检查—》读取fifo剩余数据。这样就会接收完整的一帧数据。
% F! p! e+ O% p/ D& ?- i发送流程:触发中断开始发送数据—》写入4个数据到发送fifo----》等到fifo为空中断–》写入下4个数据到fifo----》写入最后剩余数据。
9 M0 u% l$ a( `' V具体如下:
$ a$ u8 i- L% j; H+ T! m- i(1)初始化配置6 X" `1 k) j' ~" X- r5 Q0 E
void scia_init()
" \) C) h9 `. o: _/ d{2 s0 \( m0 U/ F" @$ G) @! n1 ^
// Note: clocks were turned on to the SCIA peripheral
1 }' J% ]3 Q, z p! x7 v // in the InitSysCtrl() function
/ n- w( x" Y5 r6 ]( f( p) D% J0 I SciaRegs.SCICCR.all =0x0007; // 1 stop bit, No loopback, c. e( Y, T, _# [* p3 U) F
// No parity,8 char bits,6 d& w6 z; l+ q& o
// async mode, idle-line protocol
) ]( s$ a+ D* e* T5 G% ~* z% u SciaRegs.SCICTL1.all =0x0003; // enable TX, RX, internal SCICLK,8 P+ ]: w1 ]/ n
// Disable RX ERR, SLEEP, TXWAKE
+ d2 @ @3 X. S, X4 K" v SciaRegs.SCICTL2.bit.TXINTENA = 1;//使能发送中断
+ h& F) D7 B! p. @' Q4 \8 C
3 q [1 A7 {+ g( {( x
/ [3 h0 W F+ K/ I7 ] SciaRegs.SCICTL2.bit.RXBKINTENA = 1;//使能接收中断3 _/ f# m7 l+ L; K, P! K8 b+ y
! N/ ]* H5 n1 T //BRR = (LSPCLK / (SCI Asynchronous Baud * 8)) - 1 ,LSPCLK=30M,0 A* Z% o W d) y, p
//BRR = 0x0020, baud=115200* @2 ~' j8 T B5 B6 P/ ^- G
//BRR = 0x0007, baud=460800
0 ^2 B$ ?9 V ^' I //BRR = 0x0061, baud=38400( r% L, v5 m- T3 M
SciaRegs.SCIHBAUD =0x0000;* F2 _! g: Y/ ?1 U0 ~! v% P
SciaRegs.SCILBAUD =0x0020;//
F6 F& s/ e) p. C2 ` SciaRegs.SCICCR.bit.LOOPBKENA =0; // Enable loop back
. |6 S0 v& e" h* T d+ z SciaRegs.SCICCR.bit.STOPBITS = 2; //8 Y; H: J; u% H9 W9 P
SciaRegs.SCIFFTX.all=0xC020;//设置发送中断为0级
# Q# G& Z7 [2 q( n/ G SciaRegs.SCIFFRX.all=0x0024;//设置接收中断为4级
4 [5 d. ^# y8 `5 @+ X! o SciaRegs.SCIFFCT.all=0x0;' P+ j2 x$ b" C: P% D& D
SciaRegs.SCIPRI.bit.FREE = 0;//仿真模式下是否自由运行: q+ l, [, r3 x; t8 A
SciaRegs.SCICTL1.all =0x0023; // Relinquish SCI from Reset& n6 x( v+ c. n4 V! b; x
SciaRegs.SCIFFTX.bit.TXFIFOXRESET=1; //发送FIFO复位) V @' m+ i5 Z. g: @! \
SciaRegs.SCIFFRX.bit.RXFIFORESET=1; //接收FIFO复位
: |" q, J U# C, ~$ y' _}: Z7 X% k6 i2 Z( P% H
5 T/ l! x8 J- n! \3 a5 c& F(2)接收中断和发送中断% ]. O$ R* T& O( Z) T, g
2 ?) D9 P( |% n+ h5 h7 P
interrupt void SCI1_RXD_isr(void)
g- j2 H1 U1 H{
& i1 `' a9 L) h. K# C% L1 t UINT16 RxData;* h6 m; r: P) ?3 f
//RxData = SciaRegs.SCIRXBUF.all;% C$ R% U9 ~: o7 G8 [$ U
//上一个数据帧应用层未取走,数据丢弃
# ]! G0 C% k) m# _% w if ((KeyBoardRxFrame.status == UART_FRAME_RX_END) || (KeyBoardRxFrame.index >= 40))
* L0 R, s4 B; _$ f$ s8 I& } {' C4 H) U4 O/ T/ ?! ~
KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;7 R% A$ m- ~/ Q5 ~, j! a6 i9 V$ M
KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;& S4 e! s. p! m+ z% A, B5 @
KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;6 K, e/ w! p, D+ g3 a' \' v0 H
KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;! C0 p3 Q2 r, g$ n5 |" s! u
}else, X5 i0 K- U3 c/ L$ q2 y/ q
{
! A- @8 ?4 c0 i5 E! x KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;9 C. o& h( Y% f# y7 z
KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;. {2 S2 u$ h" G8 @/ @& ^4 q* X
KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all; d+ A7 G% }+ Z; G/ j9 F4 J- t% \9 Q
KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;5 [( }5 I# s3 O
KeyBoardRxFrame.ticker = KeyBoardRxFrame.spacetime;/ ^3 I$ ^0 }# p w2 T) i
}
9 n4 T. V( }% X4 W1 N0 k8 m
) f- U9 v0 F& D- t3 o3 G! w" s SciaRegs.SCIFFRX.bit.RXFFOVRCLR=1; // Clear OveRFlow flag
* k& \; D2 l6 P% ]$ u! n! n* T SciaRegs.SCIFFRX.bit.RXFFINTCLR=1; // Clear Interrupt flag, ?+ J% L$ Z9 Z; o1 z
# S6 K5 r# p! x, K9 X- {4 A+ ` PieCtrlRegs.PIEACK.all|=0x100; // Issue PIE ack
" p5 m8 f. B4 U1 r5 O}
$ j2 Y) t7 m0 z% |, j* R3 pinterrupt void SCI1_TXD_isr(void)
7 U2 a& g6 \$ P- A{
5 \. n0 T* {& ?/ J" u Uint16 i;
2 P6 T# T% z$ s+ M8 H Uint16 len;
/ r3 Y$ k T+ |3 X8 K9 Z1 t! q // 发送一帧数据没有完成
; [9 n2 c2 q. Y$ r* i* z if(KeyBoardTxFrame.index + 4 < KeyBoardTxFrame.len) 8 m$ i" H+ ~. |, ~$ o; z% o( W, m
{
. y. c% d* O( n" e+ E2 T4 p1 j SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];
9 a/ f5 F; X) U4 G+ I SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];% c; u1 X0 Q1 @/ H9 x4 |" Q, \
SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];6 f* |4 K: S/ z) b
SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];+ k- z& x$ ~) m* t9 ]
3 c* p/ e- L- \; I" ?/ a2 n# m
SciaRegs.SCIFFTX.bit.TXFFINTCLR=1; // Clear SCI Interrupt flag清除后产生中断
; I9 E# e% O Y, `* K }
: o8 k0 q- g$ D! U: j4 O else$ L4 X5 k8 W* q1 `9 p" A
{! v' F( {: K, s; r$ t
//发送剩下的数据
( R' s( T$ `8 ?, C len = KeyBoardTxFrame.len - KeyBoardTxFrame.index;
, h. m7 P6 }& {) w6 n, { for(i = 0; (len <= 40) && (i < len); i++)
+ w T8 ]/ P' Y. Q2 I' ~- j* v { n) ~( J; t3 m: z/ D0 k
SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];
. e' c. }% \+ r P }/ q, B# ?0 w- K( h- [
3 M2 C/ R& [6 I6 _9 y //一帧数据结束' k2 n" m2 z- l9 V; n- e5 K
if(KeyBoardTxFrame.len)9 K! B* _) _, ?3 |( j
{
# [$ t( v3 d) G( x, m/ a8 r2 t KeyBoardTxFrame.status = UART_FRAME_TX_IT_END;
0 R$ U9 U" `& y7 \5 ~ }9 M! B/ a- [ `- d' H7 L! v0 p! }
}
! K% @8 F, ^1 G( I# V* ]) ]# F PieCtrlRegs.PIEACK.all|=0x100; // Issue PIE ACK; D2 n( ^- p) [3 l# ~* q
}/ T) X; x) ~5 Q9 h( y6 v3 l5 d
( B5 T: G( }, [(3)读取不到4个字节的数据
( q6 r% {' k! q% _% T
( c3 M3 q! G# j" {) ]' Xvoid SCI1_RX_FIFO(UART_FRAME *pFrame)
' l/ ~1 Q% G) _: {3 P6 ~* L{
9 U8 i& d! @% \2 C9 o/ [ Uint16 maxNum = 0;7 H! j4 L* c: M) E: o. q
while(SciaRegs.SCIFFRX.bit.RXFFST && maxNum < 4)
/ p' T0 O0 K! j7 I5 ^$ X {9 A r9 Z7 Z/ m1 L% _9 l. q$ L
pFrame->pdata[pFrame->index++] = SciaRegs.SCIRXBUF.all;0 h# H; g6 r0 ?8 N6 ~% R; R
maxNum++;! Z9 ^8 L: |; } s/ P' i
}" `, W; j& y% }# m8 ^% D
}
5 G/ @9 |. W0 j; E( c, p* @6 p: ?# G: _( M2 ]
(4)在应用程序需要2ms周期查询接收数据是否结束# |, {/ M7 Z# u
static void KeyboardJudgeRxFinish(void)
7 \( ?8 b$ p5 S{- t+ c' X7 y1 E7 L4 p% {1 r' w k
//超时或数据长度大于40一帧接收完成4 P( h7 e. J9 @, _
if(((KeyBoardRxFrame.ticker <= 0)&&(KeyBoardRxFrame.index > 0)) || KeyBoardRxFrame.index >= 40). `1 B7 K, u4 i8 r0 |
{
) s! ]2 x8 ^: C4 Q5 N: X. J# C SCI1_RX_FIFO(&KeyBoardRxFrame);
) X2 {# ]9 ? E: Z T$ u* V! P KeyBoardRxFrame.len = KeyBoardRxFrame.index;
& K( ^4 V6 q. I KeyBoardRxFrame.status = UART_FRAME_RX_END;//数据接收完成,应用可以取走数据. \% j- ~7 z# x8 L5 K
}
8 W, Y% a6 R; D1 E if(KeyBoardRxFrame.ticker > 0)
2 A% _' b% n" G$ @" b0 p! X {. {! G+ I' G& f+ E& v: ?
KeyBoardRxFrame.ticker--;
8 A$ V+ [2 O. R" w! x) i* q. D }" n9 q/ _- M+ T4 z0 Q
}0 [, v7 o+ L7 k* \* R- Q$ {
0 i. L4 } t. ](6)发送
4 P# u3 H. z! K/ `( O: L- x; Tvoid Keyboardrs485TxFrame(void)' E+ L4 ^7 V1 t& j2 U8 j& n
{; `- ]( E0 D, l2 }. i; `
SCI1SetTxMode();9 ~! w2 t' c& @0 Z5 i( f
//如果当前帧正在发送,又重新请求发送一帧数据,则请求的数据丢弃; o0 `5 S/ u6 U. z& t9 |
if(KeyBoardTxFrame.status == UART_FRAME_TX_ING). O% y# O8 V4 y5 {& E
{
9 c1 n; r# n3 m# k; | return ;
5 q; `! \; M5 e; k5 l: z! s" z& h }
+ n* {1 |, Y3 V: i# G //启动发送第一个字节后,产生中断,接着数据在中断中发送完成, P `3 ?$ G5 Z) }& R
KeyBoardTxFrame.index = 0;8 s! Y, g+ K6 O( V& Q
SciaRegs.SCIFFTX.bit.TXFFINTCLR=1;//启动发送中断) W7 a; D5 u; ~: X
KeyBoardTxFrame.status = UART_FRAME_TX_ING;3 l2 Q- h1 l' ?# V2 p& d
}
& Z( N8 j& H. w! k |
|