|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
本文介绍DSP高效接收和发送不定长度的数据,该方法减小cpu的中断次数,经过长时间检验,该方法安全可靠效率最大。我使用的是28034只有4级FIFO,在优化前中断深度设置为1,cpu频繁中断,导致正常程序受影响。经过改进,设置发送中断深度为0级,接收中断为4级,只有在数据发送完成和接收满4个字节中断。
7 g5 I9 x, _3 h1 ^6 Q( W 接收流程为:等待接收中断—》读取4个fifo数据—》超时检查—》读取fifo剩余数据。这样就会接收完整的一帧数据。# N/ |/ P' y0 g) t" P9 A6 ]
发送流程:触发中断开始发送数据—》写入4个数据到发送fifo----》等到fifo为空中断–》写入下4个数据到fifo----》写入最后剩余数据。) t6 w; u7 r1 l6 f& R
具体如下:. {$ i Q, C, F. o3 U3 F
(1)初始化配置) p: W* _9 m' H6 h$ o+ j3 T) e$ n
void scia_init()! e0 W+ x. U* W6 K3 S- O
{+ _+ m/ |; E5 J9 e2 g( b2 K2 Y, P
// Note: clocks were turned on to the SCIA peripheral
" t4 O. T! a6 ], k$ T; j5 j // in the InitSysCtrl() function# o/ d9 S' b/ k& `5 o; j" T
SciaRegs.SCICCR.all =0x0007; // 1 stop bit, No loopback" b$ ~( Q; p- ?: l/ z" o) e
// No parity,8 char bits,
2 ~0 X- S0 I3 D- S // async mode, idle-line protocol; X8 S. f3 p. ?# f, {
SciaRegs.SCICTL1.all =0x0003; // enable TX, RX, internal SCICLK,
& Z8 Q- g# R2 `7 q3 F // Disable RX ERR, SLEEP, TXWAKE2 F' m2 v' A7 r) k1 v6 ?
SciaRegs.SCICTL2.bit.TXINTENA = 1;//使能发送中断# E4 ?/ A1 Q6 L4 \
4 A$ L# ]2 X' E/ n0 |; ~$ m
9 d, E/ d5 K7 x6 ?( t% B; ` SciaRegs.SCICTL2.bit.RXBKINTENA = 1;//使能接收中断
# t& Z: ~: p. }' F7 } 7 M4 t3 ~5 W7 h4 q/ L
//BRR = (LSPCLK / (SCI Asynchronous Baud * 8)) - 1 ,LSPCLK=30M,
& h' R& U2 O* g7 U: J* h8 e //BRR = 0x0020, baud=115200
% c0 M2 D8 E- U2 f1 N6 E5 m //BRR = 0x0007, baud=460800+ ?& g4 i# d( g: T$ v# X! u
//BRR = 0x0061, baud=38400% @) R' [+ Z7 x' n
SciaRegs.SCIHBAUD =0x0000;
p- s7 W* b; B3 T& i SciaRegs.SCILBAUD =0x0020;//
, \9 g" ?: a- b/ d1 o3 ~3 l SciaRegs.SCICCR.bit.LOOPBKENA =0; // Enable loop back5 x. ]; d, W5 e: _8 }; Y
SciaRegs.SCICCR.bit.STOPBITS = 2; //2 a1 ^5 G- \0 h2 n* y: r6 B* N, M8 I
SciaRegs.SCIFFTX.all=0xC020;//设置发送中断为0级& `, h6 e. b1 ]! W
SciaRegs.SCIFFRX.all=0x0024;//设置接收中断为4级
O3 g; n$ n! v, ~3 ]) ~ SciaRegs.SCIFFCT.all=0x0;* T: A! j# n* {
SciaRegs.SCIPRI.bit.FREE = 0;//仿真模式下是否自由运行
5 z0 m8 O& R5 ?3 O9 R, S/ w SciaRegs.SCICTL1.all =0x0023; // Relinquish SCI from Reset& ~$ c" B0 s# Y: Z5 S1 Q6 h3 T0 E
SciaRegs.SCIFFTX.bit.TXFIFOXRESET=1; //发送FIFO复位
0 C: @. v: G2 Z# @6 T$ u& | SciaRegs.SCIFFRX.bit.RXFIFORESET=1; //接收FIFO复位
, V+ b. o" O# c+ [}
' D! {; e3 j6 f5 i" P, [+ {' _! ~; R" m( ~0 r% _. W
(2)接收中断和发送中断& j0 q, y7 I9 I' f
9 N* z& c$ F$ _ `* e# H! ~interrupt void SCI1_RXD_isr(void)
. W+ H: _7 A: D2 i- O{
6 K$ }0 z# R3 F, \ Y# F UINT16 RxData;4 w E% ~3 S) N
//RxData = SciaRegs.SCIRXBUF.all;6 N/ N5 b' K# ^! b( L; h( R; G! j
//上一个数据帧应用层未取走,数据丢弃; J7 R. p1 r, V) v
if ((KeyBoardRxFrame.status == UART_FRAME_RX_END) || (KeyBoardRxFrame.index >= 40))
5 p# ?1 J- m, R$ G5 s5 _ {6 a L/ c: h' ?1 G
KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;
8 u1 Y9 z) z# Y' v& \8 [6 x KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;
! h) `" D# O) u KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;' B5 K7 O: `% d ?. a! o
KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;
! [. G O9 R& ?" x. `) F }else' z1 p9 S& _0 l& Y2 V2 M* {
{1 q7 q0 B k a* o- S2 i
KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;; b9 j8 H6 k" i3 i' l8 O
KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;
7 X' ^ o; I$ U: U g" ` KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;' K) c E' L1 h! }
KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;
3 \6 A4 N- d" o9 q! |1 X! ~ KeyBoardRxFrame.ticker = KeyBoardRxFrame.spacetime;: L3 t. g2 {1 N" f! W# f
}
4 r$ H' F/ @0 O1 |+ P% N
# g1 P- X; [, N& |- Y4 `# B& a SciaRegs.SCIFFRX.bit.RXFFOVRCLR=1; // Clear OveRFlow flag
% l9 D# c6 o2 G; l SciaRegs.SCIFFRX.bit.RXFFINTCLR=1; // Clear Interrupt flag
8 m7 N9 L- f! o2 ]- X2 ]6 E+ ?0 T( t+ _1 a
PieCtrlRegs.PIEACK.all|=0x100; // Issue PIE ack
# I% s1 O8 E7 c+ C}( S: _! A0 a7 {. ?% X* y9 \
interrupt void SCI1_TXD_isr(void)$ e; j5 ^" ^5 L/ L: e6 b6 ?% r
{: ~2 y: ~6 a* A8 v) C
Uint16 i;
5 x- K4 S; w, K D7 Y6 k Uint16 len;
9 p+ O4 V8 C: G // 发送一帧数据没有完成
3 Y5 ?" j6 P* G; V) ] if(KeyBoardTxFrame.index + 4 < KeyBoardTxFrame.len)
6 Q# |0 t0 j, ` D% n {
7 C: {' c9 M8 V5 t SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];" m6 t( O, S5 w+ k" V
SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];
. ~8 F, C# y. m' Z$ p& U SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];
& J. a9 y$ l3 L, i$ n SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];
8 U' p8 G- j1 j 0 |8 B- P5 l1 l- D! ]" B
SciaRegs.SCIFFTX.bit.TXFFINTCLR=1; // Clear SCI Interrupt flag清除后产生中断, c; M) A0 B% \. J, S6 d) G$ G
}
% s1 J7 i- r3 Z7 _ else8 z" ~6 j( Q/ a# [8 Q5 r* K
{$ Y- V* m" j7 ]9 U
//发送剩下的数据
7 D% G% y3 G) x* ~* z9 ` len = KeyBoardTxFrame.len - KeyBoardTxFrame.index;
4 D+ q7 f* I& C' u4 u) q for(i = 0; (len <= 40) && (i < len); i++)
3 Y/ s, A4 o( w3 v6 ? {) L3 N4 ~3 o$ e) [7 V
SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];
. X* |& M2 _. H }
" T# X, f1 x2 I. f5 a9 N" k& m5 Y
% f* x2 k+ x/ p! } //一帧数据结束
9 R. k8 E( _( X: ^( k) D if(KeyBoardTxFrame.len) O; a1 X! h( z. o5 v
{
; i( V, y, z- Y KeyBoardTxFrame.status = UART_FRAME_TX_IT_END;
5 I# x) M8 T) `4 M. c; p/ b4 r9 M( W }# {9 n$ m# y- e$ N, q8 w
}; v) [& \8 s: i3 H% ~9 Q' ]# b0 U
PieCtrlRegs.PIEACK.all|=0x100; // Issue PIE ACK8 {8 m! y) R/ V: Y# H
}
3 J. F+ S% W- ^4 d7 ~( x. R
S6 K, f$ C2 l; V; R$ @& ?2 [9 ]& [(3)读取不到4个字节的数据" F% u8 e9 w& ]: \
" E# r6 E3 s9 A; b
void SCI1_RX_FIFO(UART_FRAME *pFrame)% k n+ H( E# j) E4 ]
{
1 O9 z! h+ o0 i7 u1 {* b3 U5 B Uint16 maxNum = 0;
) B! V' V( F' r( w4 o while(SciaRegs.SCIFFRX.bit.RXFFST && maxNum < 4)
( P1 c n: ^5 N% O {
$ b& o# r+ I7 Q% t0 }8 Z! Q+ C pFrame->pdata[pFrame->index++] = SciaRegs.SCIRXBUF.all;. Z7 S5 {2 V. |' ~$ Q
maxNum++;* n0 c6 L# p7 Z& A
}
/ d- c F4 a* H+ r u}# m+ N" i9 h8 D* c/ G% p) G
% A* J2 Q! Q0 D1 j$ V# ](4)在应用程序需要2ms周期查询接收数据是否结束% {# {# n2 M) I
static void KeyboardJudgeRxFinish(void)3 Q/ o3 N! \3 @; E2 K4 ]) u
{
2 X% j7 P# Z2 m) M4 P2 Z- u0 ] //超时或数据长度大于40一帧接收完成
: R5 A# Z) B3 X$ @) x6 @) j4 H if(((KeyBoardRxFrame.ticker <= 0)&&(KeyBoardRxFrame.index > 0)) || KeyBoardRxFrame.index >= 40)
- z3 ?8 ^" F! n) J: j' x {
5 |2 f3 M+ q: s8 o. f SCI1_RX_FIFO(&KeyBoardRxFrame);+ s- n+ l# e# l) A8 U7 @
KeyBoardRxFrame.len = KeyBoardRxFrame.index;
/ Q8 I7 m( l# y8 z+ D: z3 C) d e KeyBoardRxFrame.status = UART_FRAME_RX_END;//数据接收完成,应用可以取走数据, `1 b3 O' o. \$ A3 W4 J O: x
}3 a% w+ i( n5 C0 a) t4 R8 O/ A6 Q
if(KeyBoardRxFrame.ticker > 0). G3 w8 h; f' t% }2 j/ k
{
# P5 m" |2 K; ~" i- E( n% _ KeyBoardRxFrame.ticker--;
( p& z; l/ T5 P4 ?( ]! N }. ]( L3 h% _- {# f( G; x! B
}, l" C3 t' ?6 y# c
- j, Z0 I& H9 E: A/ _(6)发送
4 A7 A' m8 _- e2 R1 [void Keyboardrs485TxFrame(void)
9 }: r. ~# d3 T9 f! W: i7 R; \{# ?6 G! V! ]) F8 L: Y* M, X
SCI1SetTxMode();+ X/ c: f2 U O/ o
//如果当前帧正在发送,又重新请求发送一帧数据,则请求的数据丢弃
r6 ]9 Y7 \5 G( x: ]( u* R if(KeyBoardTxFrame.status == UART_FRAME_TX_ING)- R3 p; Z) }" w4 G) ~
{$ t2 A7 N% o9 b8 }0 B5 ]* f/ h
return ;
8 l% W$ h3 ]6 A3 ]! r }
' }1 r" i1 d N& R% o& i* k. q* x! q //启动发送第一个字节后,产生中断,接着数据在中断中发送完成( e0 {; K7 C/ H# ~: r% X
KeyBoardTxFrame.index = 0;
$ ]; F6 I8 D& T SciaRegs.SCIFFTX.bit.TXFFINTCLR=1;//启动发送中断
: {" p8 @, X% L! y! U! t KeyBoardTxFrame.status = UART_FRAME_TX_ING;
) v5 a5 T E# ]0 p+ {}
; S( g! }; Y8 o$ r |
|