|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
本文介绍DSP高效接收和发送不定长度的数据,该方法减小cpu的中断次数,经过长时间检验,该方法安全可靠效率最大。我使用的是28034只有4级FIFO,在优化前中断深度设置为1,cpu频繁中断,导致正常程序受影响。经过改进,设置发送中断深度为0级,接收中断为4级,只有在数据发送完成和接收满4个字节中断。
9 J( \0 |+ c% }- I接收流程为:等待接收中断—》读取4个fifo数据—》超时检查—》读取fifo剩余数据。这样就会接收完整的一帧数据。: e0 A, ]+ S' `! @" w7 @
发送流程:触发中断开始发送数据—》写入4个数据到发送fifo----》等到fifo为空中断–》写入下4个数据到fifo----》写入最后剩余数据。- V: M% m! J% R
具体如下:6 I1 @6 R' N) C$ Y2 B( X
(1)初始化配置
! |; C* `; }* D) f( \void scia_init()$ o' O0 ]' E. c$ ~
{
8 b! j% C6 G4 A$ J // Note: clocks were turned on to the SCIA peripheral/ O+ |3 z% `% z7 \& u4 \
// in the InitSysCtrl() function/ F- ^6 j+ `$ J$ R
SciaRegs.SCICCR.all =0x0007; // 1 stop bit, No loopback
% o4 n% i; i+ j( T; W3 h$ S' a v // No parity,8 char bits,9 s* `' R/ p, T2 F% Q4 v2 H; d3 J M
// async mode, idle-line protocol
4 ]6 K# F) s r Z# o5 f* K" v SciaRegs.SCICTL1.all =0x0003; // enable TX, RX, internal SCICLK,1 C! b6 \' E/ r. Q; w
// Disable RX ERR, SLEEP, TXWAKE
- ?3 n9 A( I; V) }! B- I7 [) ~ SciaRegs.SCICTL2.bit.TXINTENA = 1;//使能发送中断( B$ |( Q& f [1 `. Z
. ~& Q1 }- [$ q* i, K5 n- | D) S % j4 n/ M) ~; U6 ]. ]! B
SciaRegs.SCICTL2.bit.RXBKINTENA = 1;//使能接收中断
' r7 q5 L+ O6 P 9 C- j; l4 }! m2 @7 F9 X) C1 ^2 E: L
//BRR = (LSPCLK / (SCI Asynchronous Baud * 8)) - 1 ,LSPCLK=30M,% Q0 {' X" n' G# h! R' Y z' i+ Z
//BRR = 0x0020, baud=115200
! G% m% N/ C! o- Z //BRR = 0x0007, baud=4608002 K5 Q+ b7 j# V6 Z
//BRR = 0x0061, baud=384001 i" N3 Y9 K& [0 R
SciaRegs.SCIHBAUD =0x0000;7 G# {9 V2 i8 X1 G& V
SciaRegs.SCILBAUD =0x0020;//
1 a0 Z& f& l4 D* B# d3 H1 Z SciaRegs.SCICCR.bit.LOOPBKENA =0; // Enable loop back
4 F/ Q) D% v7 D% \* E SciaRegs.SCICCR.bit.STOPBITS = 2; //4 Q0 j/ _* F3 Q0 _3 T
SciaRegs.SCIFFTX.all=0xC020;//设置发送中断为0级" y' {, W+ o- A" |. A- y
SciaRegs.SCIFFRX.all=0x0024;//设置接收中断为4级
/ C/ `. f8 h8 E; r' `8 U SciaRegs.SCIFFCT.all=0x0;
1 Y8 I2 j8 \+ K; { SciaRegs.SCIPRI.bit.FREE = 0;//仿真模式下是否自由运行
) P8 S5 d( n0 h6 E SciaRegs.SCICTL1.all =0x0023; // Relinquish SCI from Reset8 b8 Q* }1 G& [& [) a) i( ^) h
SciaRegs.SCIFFTX.bit.TXFIFOXRESET=1; //发送FIFO复位
7 w$ _7 {9 v0 a5 v$ g N7 j3 ? SciaRegs.SCIFFRX.bit.RXFIFORESET=1; //接收FIFO复位 6 p9 _* Y* o" E" D1 h. [! z
}
, n2 c$ ^9 Z8 E4 w
' v3 ^! \2 a0 A8 Q1 @/ ^(2)接收中断和发送中断
& S3 f- O5 D6 w. i/ P. ]( n# N
6 U' W/ v% u8 O/ x: C' kinterrupt void SCI1_RXD_isr(void)- {' E( ?5 U3 w. O
{) k$ S" u1 T) G' ]8 v$ I. k: b
UINT16 RxData;
. z/ F! K+ V3 i. i+ d5 k; t //RxData = SciaRegs.SCIRXBUF.all;; |) ~, b2 O! C, A1 d: |
//上一个数据帧应用层未取走,数据丢弃, a5 n9 k0 A) ?7 W: j
if ((KeyBoardRxFrame.status == UART_FRAME_RX_END) || (KeyBoardRxFrame.index >= 40))& J$ e* n M6 d* L0 }6 q$ n5 p7 q
{
4 q7 p; Q4 _# f, o# @0 n7 f KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;
/ Z W" f7 \- m9 e( s% O( r KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;3 H3 j9 _- o+ J1 y
KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;
) f& @3 R1 O+ T& E$ u2 r2 N$ @+ z KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;
. @% K, H$ D0 k0 @4 Q* z' T B }else
7 i! E# E Q1 V/ v2 H {7 m2 W# \4 `) P( C. ]7 z/ u
KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;
) T8 b' v1 b( k( X" v KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;
3 ^, g' k5 T! \8 d; u KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;
3 d1 o4 e" Z3 R7 M# ^ KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;
9 Q k; }' ~8 B/ y1 c5 y5 U KeyBoardRxFrame.ticker = KeyBoardRxFrame.spacetime;4 a( I7 _+ N$ Q: @6 r" m9 ^9 X2 p
}
; ?( S- O/ y7 P
& `+ z$ F5 B4 o9 Z- }. c SciaRegs.SCIFFRX.bit.RXFFOVRCLR=1; // Clear OveRFlow flag/ _1 T" R! D9 u: }: t$ ?
SciaRegs.SCIFFRX.bit.RXFFINTCLR=1; // Clear Interrupt flag1 t" `, M, u6 L$ K/ X% @2 r
" x2 x5 ]/ b: N" o
PieCtrlRegs.PIEACK.all|=0x100; // Issue PIE ack
& `' A3 l+ q1 s+ J}
, k y; i ~) ~" S; ninterrupt void SCI1_TXD_isr(void)
1 H) l8 f0 g- o7 {8 v{$ t& Z/ Q1 k$ ]0 Z$ R! F8 l) q) m
Uint16 i;
, F+ \2 l; w9 X& D; _% C/ ? Uint16 len;1 a/ X* M* n+ d/ F( u7 k0 O
// 发送一帧数据没有完成
' e) T! z6 D$ X& O if(KeyBoardTxFrame.index + 4 < KeyBoardTxFrame.len)
# K7 @& r* ~6 S6 Z {8 ~0 k B. _( |; R6 I# L
SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];; `. `+ s6 c. z, A
SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];
- Y1 G9 r& t- d, c+ g3 @7 ?3 R SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];
. d b% e5 E9 T SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];. k, E4 @: e9 j, H1 X2 j+ s! D* a+ x
2 E5 M" y' k$ y; i SciaRegs.SCIFFTX.bit.TXFFINTCLR=1; // Clear SCI Interrupt flag清除后产生中断
1 k2 B2 q" \* X# n# ^ }* Y, ~, Q$ k; t8 V; I6 K a2 }
else
* @- ? t: u$ }( r; h( Z {' B6 ?: g3 v8 ?
//发送剩下的数据4 ]$ W2 ]$ q+ w2 J3 `
len = KeyBoardTxFrame.len - KeyBoardTxFrame.index;
9 G/ d3 V) e* }1 y/ o for(i = 0; (len <= 40) && (i < len); i++)
! E% g, V& Y( | {
4 z$ w/ ~& D8 B SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];
9 |' I) x# d$ }1 l+ d5 Z5 z }" L# c c' A$ l% _
; e0 R% `7 z& F, r+ M5 m) k# `0 Z
//一帧数据结束
& @. y5 H# v" H' z if(KeyBoardTxFrame.len)
( L/ M* r1 E* Q& z x {
( W4 s5 e0 T% k, X' Y$ J KeyBoardTxFrame.status = UART_FRAME_TX_IT_END;/ Q$ B9 ?' K- q* z2 [
}) r7 g& q- k% C' c+ _0 k
}
, s$ H: Y: H9 Z2 l PieCtrlRegs.PIEACK.all|=0x100; // Issue PIE ACK2 N2 `7 o' ~, c; w4 S
}+ m& k! q: i* |
- Y) E7 F. f7 D- Y3 _% g% `; V+ k
(3)读取不到4个字节的数据
: T: v, A a2 I, [; R
' F6 H# b3 Y. `& g% \8 Y( hvoid SCI1_RX_FIFO(UART_FRAME *pFrame); s: i) {' {$ ~" E3 C
{5 n% E, u$ H q# y% |
Uint16 maxNum = 0;" i1 U8 y& a# ^( T' z2 V6 S
while(SciaRegs.SCIFFRX.bit.RXFFST && maxNum < 4)
# M/ u% l) z) D! S& N5 J5 l {. e7 W3 P$ c5 v5 j( K
pFrame->pdata[pFrame->index++] = SciaRegs.SCIRXBUF.all;
. v$ b9 Q- A% o* d maxNum++;# y8 P% G/ Y; A- m' C" a
}' c9 M i: @& O7 o) ? a" t
}& {5 e. d8 X/ m" E
0 O7 m5 A: T+ z* T+ N5 P7 @(4)在应用程序需要2ms周期查询接收数据是否结束4 G/ z7 U# K. Z5 o
static void KeyboardJudgeRxFinish(void) R z* ` }2 ~/ Y
{9 O8 R0 J: V4 K0 @* T5 u! I7 P! |
//超时或数据长度大于40一帧接收完成
) l( v& D$ `- `* p' S0 Z$ s' s if(((KeyBoardRxFrame.ticker <= 0)&&(KeyBoardRxFrame.index > 0)) || KeyBoardRxFrame.index >= 40)" L5 W& s' o5 h4 ~# c8 T
{
* w! C; X9 w1 k/ |! w7 {- h6 H SCI1_RX_FIFO(&KeyBoardRxFrame);
, G6 U! Z5 a# F& ^; R. A- S KeyBoardRxFrame.len = KeyBoardRxFrame.index;
; B% J% I' L5 `6 S KeyBoardRxFrame.status = UART_FRAME_RX_END;//数据接收完成,应用可以取走数据
0 Y, w+ s/ E" B7 L( U }: h: R$ y* [# Q! T; E* H
if(KeyBoardRxFrame.ticker > 0)
" n% S' y( W2 {4 A- e A% Y {6 `! O6 z2 m, i! e
KeyBoardRxFrame.ticker--;
?0 w2 t6 l' p3 Z) y: Q, ^# Z$ x }
! ~% l% D% A- |4 ]: S$ P}$ s3 u3 O" m! N
3 V* j' R6 a' A3 @. k(6)发送
+ p$ _1 |& j) V, s uvoid Keyboardrs485TxFrame(void)
8 d' E8 w" _7 p% z% Y9 p{
+ K8 |4 Q) Y, j J1 Y/ s# S SCI1SetTxMode();/ B1 z6 R9 M0 s' Z/ d/ m
//如果当前帧正在发送,又重新请求发送一帧数据,则请求的数据丢弃1 r1 `, U. d* m G
if(KeyBoardTxFrame.status == UART_FRAME_TX_ING)
9 }$ c( s: n5 T; y! M {
7 _8 k" F8 ^7 G5 s! h n/ B return ;
' {$ |! N4 [& \3 s+ r7 s$ D( u/ p }% A- [. r9 `4 p$ q W
//启动发送第一个字节后,产生中断,接着数据在中断中发送完成
) N T" ? \* Q, I8 k2 r7 z6 c" t KeyBoardTxFrame.index = 0;
( I( i5 z; q3 p* [. R- t, C' U SciaRegs.SCIFFTX.bit.TXFFINTCLR=1;//启动发送中断5 j9 p! a- I6 c5 I T* v4 I9 Q- l. F
KeyBoardTxFrame.status = UART_FRAME_TX_ING;- \ i0 `/ Z: s( F
}: E1 O0 U+ s2 _8 u3 g' R
|
|