|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
本文介绍DSP高效接收和发送不定长度的数据,该方法减小cpu的中断次数,经过长时间检验,该方法安全可靠效率最大。我使用的是28034只有4级FIFO,在优化前中断深度设置为1,cpu频繁中断,导致正常程序受影响。经过改进,设置发送中断深度为0级,接收中断为4级,只有在数据发送完成和接收满4个字节中断。# ?4 Z* G. Z( `" a1 W/ [
接收流程为:等待接收中断—》读取4个fifo数据—》超时检查—》读取fifo剩余数据。这样就会接收完整的一帧数据。- T( u1 a, `5 X9 ?" n1 I7 W8 b* f1 p+ _
发送流程:触发中断开始发送数据—》写入4个数据到发送fifo----》等到fifo为空中断–》写入下4个数据到fifo----》写入最后剩余数据。& i$ [6 a! v- `1 h& m/ ?
具体如下:
9 _* e2 @+ V) K1 u(1)初始化配置5 \! l$ L1 S" ^; A
void scia_init()
, t& q0 u" g; X$ H{
3 V# G B1 X8 C# | // Note: clocks were turned on to the SCIA peripheral
* c/ H0 `3 _! Z // in the InitSysCtrl() function
* E4 J _2 t4 L, \$ o SciaRegs.SCICCR.all =0x0007; // 1 stop bit, No loopback
" E) }6 e* z. p2 j& r# D // No parity,8 char bits,: C+ K6 W4 F1 f# B
// async mode, idle-line protocol
1 F G5 j& J: f5 f SciaRegs.SCICTL1.all =0x0003; // enable TX, RX, internal SCICLK,6 [1 G6 y+ V2 }. M2 M3 v1 ]
// Disable RX ERR, SLEEP, TXWAKE. o; R) b, ]; x- R+ q
SciaRegs.SCICTL2.bit.TXINTENA = 1;//使能发送中断
1 c) @/ B J% S
+ X9 \" z# t, |; f7 X
* a B+ b1 p! P/ Y D$ x5 X" N SciaRegs.SCICTL2.bit.RXBKINTENA = 1;//使能接收中断% o1 x& ~! b5 S8 _
% Q' \1 I( y1 a6 I. p% o- x; ` //BRR = (LSPCLK / (SCI Asynchronous Baud * 8)) - 1 ,LSPCLK=30M,
4 [+ y u) y! ~% q. Y: Z //BRR = 0x0020, baud=115200
+ p, |) m( v9 t5 P* H7 I //BRR = 0x0007, baud=460800
/ T' j- U; k2 n1 E5 s //BRR = 0x0061, baud=38400
! t% l) V; Z" N8 H$ V SciaRegs.SCIHBAUD =0x0000;8 e9 f: I8 O4 a! j: t1 G0 R
SciaRegs.SCILBAUD =0x0020;//
- T/ y3 Q+ K4 y7 C SciaRegs.SCICCR.bit.LOOPBKENA =0; // Enable loop back7 v' t2 J& s6 J! i& c' k
SciaRegs.SCICCR.bit.STOPBITS = 2; //2 q1 D0 _1 h7 O& G5 r: ?4 x7 g; W
SciaRegs.SCIFFTX.all=0xC020;//设置发送中断为0级2 R% O/ Q* F& N1 }
SciaRegs.SCIFFRX.all=0x0024;//设置接收中断为4级0 S. E }! _3 s6 D* K
SciaRegs.SCIFFCT.all=0x0;1 a$ d( \7 c2 `( N$ c3 W* ~
SciaRegs.SCIPRI.bit.FREE = 0;//仿真模式下是否自由运行" P# p: ]2 ^1 w2 p0 ^/ u
SciaRegs.SCICTL1.all =0x0023; // Relinquish SCI from Reset: z, S; X2 B K6 J; S2 d
SciaRegs.SCIFFTX.bit.TXFIFOXRESET=1; //发送FIFO复位
^* L3 Y, {2 R( u! S SciaRegs.SCIFFRX.bit.RXFIFORESET=1; //接收FIFO复位 . Y; ?8 c( o6 N6 @8 r, F. [9 _' S" f: Q
}! ?6 H3 n, X, _. R8 Y! G, `' }+ q
$ @% g6 U2 F2 Y- o' c& X! w& x
(2)接收中断和发送中断
- J% [! ?$ z8 \0 R
9 K2 T# o+ a7 W1 w/ Ninterrupt void SCI1_RXD_isr(void)
, v" h% X( N5 z( R: m! N6 Y{
/ R0 S3 X+ o' Z1 m9 i' J( J1 a, Z UINT16 RxData;' t! P. j1 J4 V
//RxData = SciaRegs.SCIRXBUF.all;
1 b1 D! i& e. H, j. J$ a //上一个数据帧应用层未取走,数据丢弃6 q! C# l/ R, p* R% d/ {
if ((KeyBoardRxFrame.status == UART_FRAME_RX_END) || (KeyBoardRxFrame.index >= 40))
8 N" s! M3 ?; \' E {
; O H0 t6 w3 i7 I" I3 f. z KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;3 b* R0 r8 k. s8 U7 G+ i0 m5 T
KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;
$ a5 B# E ` s3 t; ?, S KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;
7 Q( G9 C6 ^: t4 g8 r KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;! W0 `3 H3 U" \3 q3 @
}else
1 v4 {1 [. y( x% u6 E; t {
7 p+ y3 J) |$ y: y3 c KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;
2 `, P: m$ }; Q0 \+ n KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;! J/ ~# z- p8 t" G/ O- P" D
KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;
" O) W2 x( L% n) h) i$ z. C# p! Z KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;8 y! j/ H9 {) Y4 D
KeyBoardRxFrame.ticker = KeyBoardRxFrame.spacetime;
* o: v) e/ o9 Y* y7 p" Q" z& V3 ] }% e: X; a, e" B1 \0 Y# _
/ l9 u& B" p. X3 P3 I- q( {3 }; ^
SciaRegs.SCIFFRX.bit.RXFFOVRCLR=1; // Clear OveRFlow flag
/ b& x1 C9 ^) y' r9 G2 n. e( ~. L SciaRegs.SCIFFRX.bit.RXFFINTCLR=1; // Clear Interrupt flag/ [. p0 m" ]9 m
5 c" G% L9 G' j/ C8 S7 ?! d
PieCtrlRegs.PIEACK.all|=0x100; // Issue PIE ack8 A G) ]8 i+ f. Y2 | u+ `
}
- r2 c8 R; o! i5 v) D6 E0 ?interrupt void SCI1_TXD_isr(void)
9 H6 T3 ?" T6 {5 [8 D, x{: x/ @) H, e5 s2 S! U
Uint16 i;( X+ t, T( l1 y3 U+ X) X) |* ~
Uint16 len;5 A& g4 Y6 s4 h- Y
// 发送一帧数据没有完成5 _: Q; x) S& |2 b4 n2 m9 K
if(KeyBoardTxFrame.index + 4 < KeyBoardTxFrame.len) . R8 ~5 b2 ^0 e- ~% s) J
{, F$ A( a0 }8 r! J+ r# G
SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];
v1 U" ]& P2 H; | SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];+ J( }1 y5 D) q
SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];
l- Q3 i1 Y ~- B0 J% c; X SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];
6 E! _" P- G& Y+ }
1 N9 C# F, U4 v4 i. A* c( Y SciaRegs.SCIFFTX.bit.TXFFINTCLR=1; // Clear SCI Interrupt flag清除后产生中断
: q& ?2 u1 l/ W }
3 Y+ T( K$ H) D9 S else0 Z* K: n% t) K+ T' @, O; b- Q
{
1 b( P. N" F$ a) z) D3 J //发送剩下的数据
" d" D9 X1 U( ~7 H! s len = KeyBoardTxFrame.len - KeyBoardTxFrame.index;
. g5 j) w7 P, W W for(i = 0; (len <= 40) && (i < len); i++)$ p! s" Y+ l6 ?4 F' _, ^/ D3 M
{* Y) w/ H! |9 P) s/ n+ g$ v* z
SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];5 m# F; \: e5 g% u% m
}
' _+ A+ u( J5 Y1 E* ]9 j9 B4 c* j8 \5 L% ?7 b , Y" w% p9 g& p
//一帧数据结束 j, H5 c1 E# x0 q+ h" z+ |
if(KeyBoardTxFrame.len)% h( q6 c& }5 \9 n6 h
{8 f! `& g4 o0 E0 N2 Q
KeyBoardTxFrame.status = UART_FRAME_TX_IT_END;6 E( v$ k7 Q3 T. i
}
1 P3 d! c8 ~ W. K# i5 V9 }/ w4 { } |5 [5 D/ S6 h9 e4 F8 ~
PieCtrlRegs.PIEACK.all|=0x100; // Issue PIE ACK
4 g& p l8 |5 T7 M" K' J* \% N# s}6 }, H" D4 K% y
# `/ k4 M# A4 J" g3 q* k(3)读取不到4个字节的数据
! I1 p; X* F" _7 k! u7 Q" H0 ~& | f
void SCI1_RX_FIFO(UART_FRAME *pFrame)
" J- \& F0 \% o6 ^8 g& e- T{
$ t* d$ H; n7 Y1 f% C( |9 l6 v# w Uint16 maxNum = 0;2 `4 J$ z& o5 D1 Y ] u
while(SciaRegs.SCIFFRX.bit.RXFFST && maxNum < 4); z/ v+ t: j5 q
{3 V" T+ S$ `& P% W) a* W# a/ c
pFrame->pdata[pFrame->index++] = SciaRegs.SCIRXBUF.all;* b! X. ?6 W. S8 f* t
maxNum++;
" C& P8 k- B% |& K$ S, C: k; O }# Q+ I/ X6 b7 k/ S1 y: g Z
}
" h2 o9 ~+ j( T2 y; v6 P: B
! f# u6 P' v% {+ ~6 s8 ?3 }(4)在应用程序需要2ms周期查询接收数据是否结束
a" l0 C# F3 y& Ostatic void KeyboardJudgeRxFinish(void)8 R, c2 X5 Y$ I7 S* V* x
{/ h3 @+ A- `% {* D( {
//超时或数据长度大于40一帧接收完成# f; o w0 o: o7 G! o) a1 q; X
if(((KeyBoardRxFrame.ticker <= 0)&&(KeyBoardRxFrame.index > 0)) || KeyBoardRxFrame.index >= 40). w g; ~ F$ ?' o
{) W. j/ L! {. a- w
SCI1_RX_FIFO(&KeyBoardRxFrame);+ W- u6 f$ O' V3 v9 e! p- m
KeyBoardRxFrame.len = KeyBoardRxFrame.index;4 \# g1 [% M( a% X$ K* Q1 n
KeyBoardRxFrame.status = UART_FRAME_RX_END;//数据接收完成,应用可以取走数据- Y ^6 H7 y" s$ b$ ?% E, m
}
7 S8 s/ q4 d: |- d5 l4 v if(KeyBoardRxFrame.ticker > 0)) h, S1 l* L p- X7 @* x6 y0 D) f
{( z5 o% e! B/ P; o* u. s
KeyBoardRxFrame.ticker--;: d: q: E/ g! i9 p1 _
}: x% A [! b) Z: }/ H$ h! x
}
) s. @7 @! n# o! \7 e! T6 q4 O3 n
$ d3 ?7 ?4 J Y) J9 H" z4 v(6)发送
) Y% @( @2 T; i9 ~" I6 \void Keyboardrs485TxFrame(void)
( [4 B3 `' V0 p{8 r$ a" ^- w( w+ s* P% |3 d& R) [$ i
SCI1SetTxMode();5 {/ @% Y3 j R" y1 h6 Q/ }+ ]0 F& q
//如果当前帧正在发送,又重新请求发送一帧数据,则请求的数据丢弃 i# w& j; M. G* H7 ^0 @
if(KeyBoardTxFrame.status == UART_FRAME_TX_ING)
3 o2 p" e/ U, {0 T% H! f, z {* P W* j) H7 g, R. g
return ;/ r' A8 G- s/ W. _! f' R7 o+ D8 P
}4 W6 n7 W. I( z" f5 n
//启动发送第一个字节后,产生中断,接着数据在中断中发送完成8 S- y; o1 J3 E: v4 u) Z
KeyBoardTxFrame.index = 0;
* I% h6 D5 V7 M+ y" T SciaRegs.SCIFFTX.bit.TXFFINTCLR=1;//启动发送中断
( U- B3 s$ ]0 h4 n/ L/ N- S- l KeyBoardTxFrame.status = UART_FRAME_TX_ING;
1 h0 e' z' U( g}4 z( W, h$ Q! S X
|
|