|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
本文介绍DSP高效接收和发送不定长度的数据,该方法减小cpu的中断次数,经过长时间检验,该方法安全可靠效率最大。我使用的是28034只有4级FIFO,在优化前中断深度设置为1,cpu频繁中断,导致正常程序受影响。经过改进,设置发送中断深度为0级,接收中断为4级,只有在数据发送完成和接收满4个字节中断。
4 U0 F7 e1 I6 I: t3 Y 接收流程为:等待接收中断—》读取4个fifo数据—》超时检查—》读取fifo剩余数据。这样就会接收完整的一帧数据。
. j1 N) p1 Z. o6 r: W 发送流程:触发中断开始发送数据—》写入4个数据到发送fifo----》等到fifo为空中断–》写入下4个数据到fifo----》写入最后剩余数据。
]; p" x+ r! a3 d8 [4 o Q具体如下:
0 \8 o; C$ ~! M( w& ?! c(1)初始化配置
' I+ ^8 T: V& \! G4 o: Fvoid scia_init()) \/ y( _8 c a3 r9 Q
{
0 e% ^+ S# S7 ?1 }7 d, m. {. k // Note: clocks were turned on to the SCIA peripheral
% ~( v- r' |8 ~# {5 a& } // in the InitSysCtrl() function
! c$ i, j \5 e SciaRegs.SCICCR.all =0x0007; // 1 stop bit, No loopback+ P: ^1 |6 f; e: x- i
// No parity,8 char bits,3 z8 s# f: A8 W$ k1 Z1 x
// async mode, idle-line protocol
: `- R6 }) A8 C' ], Q1 V) o SciaRegs.SCICTL1.all =0x0003; // enable TX, RX, internal SCICLK,* a' L* B' [" r6 G# t
// Disable RX ERR, SLEEP, TXWAKE& T. ~0 \# [7 V6 P
SciaRegs.SCICTL2.bit.TXINTENA = 1;//使能发送中断% [# n9 @ h( n; S1 n: D
5 L( _8 P' V4 `
0 Z: }" b% M" `- l: E+ [+ o7 o0 H SciaRegs.SCICTL2.bit.RXBKINTENA = 1;//使能接收中断
( N, A# t5 g# F$ i, [ . q1 B, x3 I( o6 |
//BRR = (LSPCLK / (SCI Asynchronous Baud * 8)) - 1 ,LSPCLK=30M,1 E! a% r, x& q; j
//BRR = 0x0020, baud=115200* u/ U% [# n& D0 W0 b) r
//BRR = 0x0007, baud=460800
7 {6 c2 @/ E9 x5 b w w //BRR = 0x0061, baud=38400
* l6 _- X5 G1 `" o$ N SciaRegs.SCIHBAUD =0x0000;# \4 T/ D9 W) W6 Z& J
SciaRegs.SCILBAUD =0x0020;//2 g& Q+ M' ~, M5 Y: N, f% E6 u" }
SciaRegs.SCICCR.bit.LOOPBKENA =0; // Enable loop back/ V$ k+ N8 d& E% s
SciaRegs.SCICCR.bit.STOPBITS = 2; //
. x$ U1 t1 e* U; F" H1 v( Y SciaRegs.SCIFFTX.all=0xC020;//设置发送中断为0级
r3 t* q# }) q& R5 m8 I/ l4 n2 p. v SciaRegs.SCIFFRX.all=0x0024;//设置接收中断为4级1 B) y) o1 ~5 X+ t: e0 ~7 _
SciaRegs.SCIFFCT.all=0x0;' f* g5 R- a. o- C) Y! t
SciaRegs.SCIPRI.bit.FREE = 0;//仿真模式下是否自由运行
, @" m( R5 j, p7 G SciaRegs.SCICTL1.all =0x0023; // Relinquish SCI from Reset
0 L( A0 u$ c8 V v4 Q1 I) t# c" F SciaRegs.SCIFFTX.bit.TXFIFOXRESET=1; //发送FIFO复位
' M0 l. A) E+ R SciaRegs.SCIFFRX.bit.RXFIFORESET=1; //接收FIFO复位
/ V/ P, n' K; y! P a}7 b: n P }4 F* J" P6 C3 J
4 T- c' Q+ y* }9 r(2)接收中断和发送中断
( V7 N9 T* T' d+ I/ ~2 u. t5 f4 R& |+ [. F, X, m/ `
interrupt void SCI1_RXD_isr(void), g+ Y b2 N6 ]8 A8 T( H( \
{
2 P8 |8 p# w9 e9 q; S UINT16 RxData;
. Z8 g" `# u2 r2 E //RxData = SciaRegs.SCIRXBUF.all;
# `9 _0 g+ l( s8 x //上一个数据帧应用层未取走,数据丢弃
6 @( H8 l& q! a. i# W) a if ((KeyBoardRxFrame.status == UART_FRAME_RX_END) || (KeyBoardRxFrame.index >= 40)). C9 X3 c m$ b0 O
{5 K5 E) z" U% f- d/ G
KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;- v1 X+ r! C" \0 d6 l; D
KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;
7 s) {2 `3 _8 _ KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;6 h* g) C3 {, h3 A- i# g8 ~! B
KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;# m O2 Z, j: B$ z5 Y9 M
}else
) y7 ^9 ]" E/ T% _" ]' l {& t0 w& `4 {& J' Y q+ J
KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;
1 D+ F3 _+ O6 G' A! m KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;
* u0 A0 O: p7 F: Q KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;
% Z n; A% P7 J! N8 V* z y& g: n& ? KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;1 C. c- _6 r) h% q3 l
KeyBoardRxFrame.ticker = KeyBoardRxFrame.spacetime;
) I- X( S: y% K% q }
7 `* ^3 \) W: h4 d/ e2 P0 L ; i4 H: j k) D
SciaRegs.SCIFFRX.bit.RXFFOVRCLR=1; // Clear OveRFlow flag
" T' V4 y; U, B2 T4 Z SciaRegs.SCIFFRX.bit.RXFFINTCLR=1; // Clear Interrupt flag+ C4 R7 R! k1 Q- c
% E; Z7 b! q3 q& |* v) D PieCtrlRegs.PIEACK.all|=0x100; // Issue PIE ack
5 a! w; _8 ?. `' ^8 W# ~! D}
. Q4 i: ?( N5 d7 ^% q @4 jinterrupt void SCI1_TXD_isr(void)8 U' G& p; m# u- h$ n
{
# _5 H# B Q5 {% g Uint16 i;
' [& V# y* ?* Z8 b Uint16 len;
$ Z0 @# o# B: n9 f5 m" Q% V // 发送一帧数据没有完成/ v1 p+ }& f: s8 ~
if(KeyBoardTxFrame.index + 4 < KeyBoardTxFrame.len) . {0 K2 V3 t" W. D
{
& R$ t1 q: y" P0 c+ U) \7 p2 y% g& Q SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];
# C5 N( k; y4 o( w1 O1 ] SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];
- x, w8 {4 l) n' r5 \" u9 [ SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];: X* D0 H: _2 S5 X# w6 Z5 F
SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];
& O' u# \, |2 V' w# [1 t* X # E! s1 s2 w8 I
SciaRegs.SCIFFTX.bit.TXFFINTCLR=1; // Clear SCI Interrupt flag清除后产生中断" o7 g1 u) N5 u4 Z8 A
}
9 M5 s6 N1 f. P: ]7 b i6 P else! r( G, s8 I. K0 ?; Y& |1 c! ^
{" l- k5 _/ g6 f
//发送剩下的数据
# O6 X. \+ _1 H3 M3 G. A len = KeyBoardTxFrame.len - KeyBoardTxFrame.index;3 r) P+ d6 b, ?# T+ C9 x/ }
for(i = 0; (len <= 40) && (i < len); i++)2 I5 d" ~3 l" |6 h7 S/ D
{# P9 J. {0 I) S( K4 ^5 M$ ^" B( a
SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];
- K9 s6 y+ i3 [8 ] }' y% |6 W- u" _ g7 z' R3 S) g
( n H; l* H( I* e0 a
//一帧数据结束2 J: {* u) R5 I% O: W/ d4 o
if(KeyBoardTxFrame.len)
# n# n( U3 [+ t {
' [9 ?1 d) G0 [& ~ KeyBoardTxFrame.status = UART_FRAME_TX_IT_END;
- d0 p. D# ?- L% D2 v }
+ U4 G1 w ]% K: v8 n! B }
' w2 p9 t! V# n4 D1 M# s* ^ PieCtrlRegs.PIEACK.all|=0x100; // Issue PIE ACK# I+ @* y- B9 }* u9 K( o8 M
}
5 r" \7 B. n/ P" F1 Z
4 q9 [# c0 O+ ]1 |(3)读取不到4个字节的数据0 v1 u" F/ M* k, C( o
' V7 a- s+ {9 B2 g% O% F" p
void SCI1_RX_FIFO(UART_FRAME *pFrame)# _" R7 o2 X# a" B
{
8 Z4 T9 o6 X& @ Uint16 maxNum = 0;
6 s! D9 u0 C- ?" T1 h1 o while(SciaRegs.SCIFFRX.bit.RXFFST && maxNum < 4)
* T' k; I. p! R% ]; D" ?) b% m {# s1 r* p& b5 h, Z9 _# A
pFrame->pdata[pFrame->index++] = SciaRegs.SCIRXBUF.all;
1 [$ J3 M* B& W8 M0 i8 { maxNum++;1 S: W `( A, `2 B- ?$ J
}* D, y! g5 U+ D; Z5 W
}9 x) ~8 K/ l% m8 t5 v
' B4 w3 q$ U' J. \+ q0 P" i
(4)在应用程序需要2ms周期查询接收数据是否结束/ x( i- y3 p' D3 E
static void KeyboardJudgeRxFinish(void)+ ~* M* h1 d/ `; D8 @' Y3 g: C8 ^1 b
{: [" ^1 t( B& C0 }
//超时或数据长度大于40一帧接收完成3 f" q( A0 Y1 n4 H! t
if(((KeyBoardRxFrame.ticker <= 0)&&(KeyBoardRxFrame.index > 0)) || KeyBoardRxFrame.index >= 40)1 A5 J& U( i" I& R
{# @: K/ K# c$ h* Z6 n4 a: ~& K( c
SCI1_RX_FIFO(&KeyBoardRxFrame);
) P0 v! X% O1 I+ N KeyBoardRxFrame.len = KeyBoardRxFrame.index;( | s( L& \9 v; m
KeyBoardRxFrame.status = UART_FRAME_RX_END;//数据接收完成,应用可以取走数据1 D- R. p8 f6 H# M$ n0 ?
}, p$ a+ l- h# `9 u5 a4 v
if(KeyBoardRxFrame.ticker > 0)
5 D, K( i. w* ^" b6 Z; h d {" h" ]. Y3 z- s7 H* x$ V
KeyBoardRxFrame.ticker--;1 @! M, q$ R1 t* d8 P
}
. A: ?) p4 L% n5 B7 R5 ~} e) L; M9 T1 B' D8 ]( G
5 C& u* t! X! M(6)发送$ b' s% B5 L1 n4 G* t/ z
void Keyboardrs485TxFrame(void)
Z0 |& P' M2 a" S9 y{4 j2 O6 n) a7 l0 i5 N5 b
SCI1SetTxMode();
& _7 p* S4 s4 U, G9 f9 X //如果当前帧正在发送,又重新请求发送一帧数据,则请求的数据丢弃( d) }' z! }; e0 z5 [% n
if(KeyBoardTxFrame.status == UART_FRAME_TX_ING)
3 y7 ? u# ~& b! ]/ U2 m, B {! _! o& A3 H6 L6 p6 s W. I$ }
return ;
& @' p! B. J, Y8 }3 `* U& v }
* D3 J4 E0 ~: g //启动发送第一个字节后,产生中断,接着数据在中断中发送完成
+ S2 M+ k+ a9 \2 T- |$ x0 l KeyBoardTxFrame.index = 0;' P% e# R$ y" y
SciaRegs.SCIFFTX.bit.TXFFINTCLR=1;//启动发送中断
& l) e* |+ `6 o0 t3 ?4 i" F KeyBoardTxFrame.status = UART_FRAME_TX_ING;
* u7 `% I ^. r; m W0 j}
2 r7 ?+ ]+ P( Z) U' p |
|