|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
本文介绍DSP高效接收和发送不定长度的数据,该方法减小cpu的中断次数,经过长时间检验,该方法安全可靠效率最大。我使用的是28034只有4级FIFO,在优化前中断深度设置为1,cpu频繁中断,导致正常程序受影响。经过改进,设置发送中断深度为0级,接收中断为4级,只有在数据发送完成和接收满4个字节中断。 N! z' j3 l1 f& ]" Y; _9 _7 d, N9 ^
接收流程为:等待接收中断—》读取4个fifo数据—》超时检查—》读取fifo剩余数据。这样就会接收完整的一帧数据。
# T, J* r$ r$ h- l! R8 f 发送流程:触发中断开始发送数据—》写入4个数据到发送fifo----》等到fifo为空中断–》写入下4个数据到fifo----》写入最后剩余数据。0 h3 z0 d. H( t9 G
具体如下:
+ P2 v( u9 B0 n( P(1)初始化配置5 {; |" t' y1 I
void scia_init()
6 w0 O4 n% m; ^{
! o& C+ z* o8 i; M // Note: clocks were turned on to the SCIA peripheral X% x( a4 d9 r+ z
// in the InitSysCtrl() function/ ~, q( `% D' ^8 I Z0 b) _) v
SciaRegs.SCICCR.all =0x0007; // 1 stop bit, No loopback
, A1 M3 ^8 C% S) J) F/ D // No parity,8 char bits,
6 v' T; |* Z8 K9 x9 ?* r% `1 e // async mode, idle-line protocol
3 ^! J7 r1 @ Q6 l6 G7 s SciaRegs.SCICTL1.all =0x0003; // enable TX, RX, internal SCICLK,
; j! e9 m% D3 y; V7 {3 ~ // Disable RX ERR, SLEEP, TXWAKE0 \4 s5 F! V H8 @' r7 O8 }! ^
SciaRegs.SCICTL2.bit.TXINTENA = 1;//使能发送中断
0 R" w4 x# O2 Q( Y1 L( B; `/ x- \- `! c5 c! J! B
, B* S; A7 V7 w) ?
SciaRegs.SCICTL2.bit.RXBKINTENA = 1;//使能接收中断
( N: j( y' D- j2 H5 K # B2 t; Q& j8 k9 t* }
//BRR = (LSPCLK / (SCI Asynchronous Baud * 8)) - 1 ,LSPCLK=30M,( g+ n+ u; w8 r) O! |
//BRR = 0x0020, baud=115200
+ _* y* R2 |* C9 W* I5 D( W //BRR = 0x0007, baud=460800, W5 {' q' H S/ n
//BRR = 0x0061, baud=38400' g% B5 P$ v7 @$ L. F1 r& x: I. r
SciaRegs.SCIHBAUD =0x0000;
# {4 q' {5 P4 ?% |7 N: S SciaRegs.SCILBAUD =0x0020;//: [" ]8 Q/ I7 X; {
SciaRegs.SCICCR.bit.LOOPBKENA =0; // Enable loop back
; q0 ?3 ?* D' n% K! } SciaRegs.SCICCR.bit.STOPBITS = 2; //7 e3 D2 w, G2 _ @
SciaRegs.SCIFFTX.all=0xC020;//设置发送中断为0级$ q/ |0 f/ N5 _; j! o! r/ U0 X
SciaRegs.SCIFFRX.all=0x0024;//设置接收中断为4级& _4 F5 g1 K, D m% _# ^$ o/ X
SciaRegs.SCIFFCT.all=0x0;
, P( s; w9 {% _ SciaRegs.SCIPRI.bit.FREE = 0;//仿真模式下是否自由运行
# }2 l. m( l+ D( c% f% z9 a SciaRegs.SCICTL1.all =0x0023; // Relinquish SCI from Reset
; f$ c- F ~" a SciaRegs.SCIFFTX.bit.TXFIFOXRESET=1; //发送FIFO复位
( t. ~) F3 Q2 t) Q W5 G+ O SciaRegs.SCIFFRX.bit.RXFIFORESET=1; //接收FIFO复位
8 ?8 B5 i. A; O8 l) n+ y}0 p H9 n2 e/ F
Y& `" I& ^0 P8 L(2)接收中断和发送中断* c0 n. h7 f0 t, U. q1 M1 _
( ~" p# I/ b1 a, @ r: Qinterrupt void SCI1_RXD_isr(void)/ F/ U7 x+ L& a, p) w: @% a
{/ W# J1 Z: P4 R
UINT16 RxData;
" S1 Z0 _! C8 L1 ~6 o/ n8 ] //RxData = SciaRegs.SCIRXBUF.all;+ R, Z- @8 D4 Z1 F& q
//上一个数据帧应用层未取走,数据丢弃
- k5 I9 Z6 k% Z2 a& U if ((KeyBoardRxFrame.status == UART_FRAME_RX_END) || (KeyBoardRxFrame.index >= 40))
' E8 v6 l% d' Q( T$ I" F {) u3 L& C% u* k3 \
KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;
! q3 n- L% g; t5 N: I @5 v; L KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;; o' T8 E! H- j
KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;" u9 A( Z4 N0 }9 ^9 ~
KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;9 x3 A& K* L9 I* G, \
}else3 z+ N3 f/ P- c) |
{2 ^! p" h9 p8 j
KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;& G k( g* x- J, C2 C0 X
KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;+ h" a3 {" @7 o1 {: C1 R
KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;
# Z- k* b( n2 ?. F; c KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;% o7 C/ ~( ~4 R) Z- N
KeyBoardRxFrame.ticker = KeyBoardRxFrame.spacetime;
# G4 h( {2 @* a3 V }
s+ e0 O* M$ }; U, A0 B
' t2 R& Z1 \ l3 I" u f SciaRegs.SCIFFRX.bit.RXFFOVRCLR=1; // Clear OveRFlow flag
/ B2 L J* V9 M9 H SciaRegs.SCIFFRX.bit.RXFFINTCLR=1; // Clear Interrupt flag
+ p- ^+ C* \( B8 z
2 d2 W6 T1 _- Y+ o PieCtrlRegs.PIEACK.all|=0x100; // Issue PIE ack
/ d) a9 A3 j0 z( K) @}
5 J& a# t) U& `9 S% f7 {4 einterrupt void SCI1_TXD_isr(void)
3 o- }, l, I" ~0 I; d{
4 Y, x& \7 [& d Uint16 i;
$ ^. f. ^% i0 Y" N# p* d2 ` Uint16 len;
6 i3 M7 u n. b( s. m" O$ ] // 发送一帧数据没有完成
1 a L; Z8 l& e' I4 ~ if(KeyBoardTxFrame.index + 4 < KeyBoardTxFrame.len) 3 n- F+ d3 W+ t% i
{
% Q! a% j/ H' e2 v# r SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];5 @8 w! u$ j% C2 }$ ?2 C
SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];
* [/ h0 [! f# j/ C SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];( W3 u4 k9 e2 t- M2 n4 t* \4 b
SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];$ b0 U4 k$ d" ?2 l
Z# ]% ~* e6 E z3 P SciaRegs.SCIFFTX.bit.TXFFINTCLR=1; // Clear SCI Interrupt flag清除后产生中断
k; E; t6 U# a. e6 M1 w, e p }, f8 P( v6 B8 ^' ~
else
/ V, u& m; [3 K: \" G. E( b {
& Y0 ^1 M$ b% V! F( w) N+ J //发送剩下的数据
0 ` W& ]( O0 H9 W0 J len = KeyBoardTxFrame.len - KeyBoardTxFrame.index;
/ H* L" E$ U5 b* K# |, r' p for(i = 0; (len <= 40) && (i < len); i++)6 X# j9 I2 l" J C% |+ y# o6 Y6 A' I
{% s" s8 a( B6 V0 i/ @) u8 o% p
SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];
! f" J5 D$ B* ^) `) u }
1 S7 Y B: J2 |$ O; X# R
. `6 ~0 m* Y' K. g4 q //一帧数据结束
' }. ~: F- j4 h+ E7 @ if(KeyBoardTxFrame.len)) G2 Q( r3 U+ p
{1 j# Y# `- n. a# N
KeyBoardTxFrame.status = UART_FRAME_TX_IT_END;4 {2 y* u' n* J0 ?1 `% u( @; `1 K
}
# f; _ v0 p) k1 @7 g: i4 U, z' r }# l9 E w$ @& b0 }1 }9 Y
PieCtrlRegs.PIEACK.all|=0x100; // Issue PIE ACK
/ I, c( M6 J! z5 {}; b& z0 `% U5 }4 y' p
) j+ d$ U$ S* c ?$ C) L0 j9 A
(3)读取不到4个字节的数据- ~& D7 d9 I) H+ u6 I5 `7 D
. X- t* }1 c! y4 s$ \
void SCI1_RX_FIFO(UART_FRAME *pFrame) s' i3 `/ @0 z2 J/ Z5 g3 S! n
{
2 V# M" n* M& |9 a s Uint16 maxNum = 0;; ]/ o2 y! a" u9 B; {3 d O0 Z
while(SciaRegs.SCIFFRX.bit.RXFFST && maxNum < 4)
) @8 h8 L; j+ h6 ~' B, p! W' A+ @ {
, E; @0 U! c) [+ G. c$ A9 ? pFrame->pdata[pFrame->index++] = SciaRegs.SCIRXBUF.all;5 N) j1 E" U9 O0 C6 W/ C K; K3 }) e
maxNum++;0 s2 K8 ~7 s* Q5 ]$ o
}5 t0 r* }8 X0 c
}
6 H# x/ B n9 X( G7 L6 X+ F1 l# g9 p! C/ g5 a$ ?* x. @# R
(4)在应用程序需要2ms周期查询接收数据是否结束. f. Z$ K9 d# o) w; l! u6 i5 r- t
static void KeyboardJudgeRxFinish(void)
, p; G( A: `1 X& g3 F/ A: u8 u{
1 R' u4 h! E( K S9 b; b //超时或数据长度大于40一帧接收完成
7 S h U3 Q1 e' A2 w if(((KeyBoardRxFrame.ticker <= 0)&&(KeyBoardRxFrame.index > 0)) || KeyBoardRxFrame.index >= 40)
0 \7 W. O) A: E6 D$ d% R$ N {
6 ^7 n6 L* f; \: h( }8 t& Y8 h SCI1_RX_FIFO(&KeyBoardRxFrame);
+ N& r+ f% ]) S6 ~' E5 L( o4 e0 T KeyBoardRxFrame.len = KeyBoardRxFrame.index;
8 E7 O4 V- D5 c1 p, s1 | KeyBoardRxFrame.status = UART_FRAME_RX_END;//数据接收完成,应用可以取走数据
' ? e: [9 H, p, B: ?+ ` }
' J: I) K5 b" Q: V6 a6 F a) K if(KeyBoardRxFrame.ticker > 0)
* X/ ]( q0 P% j/ M$ r { r8 Q$ ~0 Y# ]$ _" f- _
KeyBoardRxFrame.ticker--;: T) p. X- N# Q' I
}; Q: B8 c8 s& [. l* f3 G% M$ Q1 \
}
+ C6 ^9 K$ h1 x4 Y& \' U7 ^1 _4 ]" l6 K. S4 {5 D3 g1 }
(6)发送
) `5 f- T0 g# `8 q3 g* Ivoid Keyboardrs485TxFrame(void)4 ~& n+ V& w& M0 s3 ]8 ~& `6 S
{! X2 R4 d3 _: u4 M/ V, S& D
SCI1SetTxMode();& m% ~1 `# E, `; w' k. B
//如果当前帧正在发送,又重新请求发送一帧数据,则请求的数据丢弃
+ R' D9 J3 m6 s6 K) C if(KeyBoardTxFrame.status == UART_FRAME_TX_ING)3 x$ i% z. D* T& _! m
{
1 B7 S' q+ _4 f: e! w return ;$ d9 [& Q( k( t
}
; c0 Z8 r! ?: r. m9 u //启动发送第一个字节后,产生中断,接着数据在中断中发送完成
5 T# t2 z5 a% s8 w3 _ KeyBoardTxFrame.index = 0;3 Z* c4 S- K. L. `) d$ h1 C0 L
SciaRegs.SCIFFTX.bit.TXFFINTCLR=1;//启动发送中断( y' Y8 g; @; W8 V- U+ z( N; v0 F5 F
KeyBoardTxFrame.status = UART_FRAME_TX_ING;! |$ Y8 G7 R9 l' I
}
8 F3 `# B5 C! n8 p! A! M |
|