|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
本文介绍DSP高效接收和发送不定长度的数据,该方法减小cpu的中断次数,经过长时间检验,该方法安全可靠效率最大。我使用的是28034只有4级FIFO,在优化前中断深度设置为1,cpu频繁中断,导致正常程序受影响。经过改进,设置发送中断深度为0级,接收中断为4级,只有在数据发送完成和接收满4个字节中断。
# Z! a: a7 m* r5 z) L m2 k 接收流程为:等待接收中断—》读取4个fifo数据—》超时检查—》读取fifo剩余数据。这样就会接收完整的一帧数据。
6 c. [( [& W0 I! K 发送流程:触发中断开始发送数据—》写入4个数据到发送fifo----》等到fifo为空中断–》写入下4个数据到fifo----》写入最后剩余数据。& I- k. {- `8 G2 z4 \) U0 Z
具体如下:/ E4 j' z5 z9 y8 h9 U8 I
(1)初始化配置& f. a6 K# D, ?5 C7 J' y( l m
void scia_init()
4 R' ?% y, Z3 B1 B! h" T{4 E3 n) v+ _' | C) d
// Note: clocks were turned on to the SCIA peripheral
# t# F8 | v T+ W5 N // in the InitSysCtrl() function5 O6 H1 K7 B8 V* \% R
SciaRegs.SCICCR.all =0x0007; // 1 stop bit, No loopback
; Q3 p! K6 I8 n& a // No parity,8 char bits,
" D* ~) {/ o+ Y7 B! U$ S // async mode, idle-line protocol# \$ r4 D/ s8 H: E% R7 Q
SciaRegs.SCICTL1.all =0x0003; // enable TX, RX, internal SCICLK,
0 A8 F9 p2 W0 q& t( @6 E // Disable RX ERR, SLEEP, TXWAKE% J# q& e9 G; v O3 n" [1 u
SciaRegs.SCICTL2.bit.TXINTENA = 1;//使能发送中断
0 C/ Y, [) U9 Y+ O3 H7 J( h; l
% e+ h- \% C( E
4 W; r+ q- h, y$ X6 c2 k& [ SciaRegs.SCICTL2.bit.RXBKINTENA = 1;//使能接收中断# z, y- B& i6 ~: e5 e
' ]) n+ a/ ^* _2 {) F0 c //BRR = (LSPCLK / (SCI Asynchronous Baud * 8)) - 1 ,LSPCLK=30M,# P- h. }5 O# Y& U
//BRR = 0x0020, baud=115200
3 n1 h, U2 h# @: q5 M //BRR = 0x0007, baud=460800" E. {5 Y$ E# V9 ~6 q. Q- e
//BRR = 0x0061, baud=384007 ]! x5 e, t( {
SciaRegs.SCIHBAUD =0x0000;6 w8 P5 r3 J& l
SciaRegs.SCILBAUD =0x0020;//, [7 C7 V# q; Y B: G, J" H/ E/ y
SciaRegs.SCICCR.bit.LOOPBKENA =0; // Enable loop back3 U9 E# v2 U6 A/ y$ x3 L
SciaRegs.SCICCR.bit.STOPBITS = 2; //6 y" }9 Z+ K. u) U5 S
SciaRegs.SCIFFTX.all=0xC020;//设置发送中断为0级3 S9 z( i( B9 R5 `) k* `
SciaRegs.SCIFFRX.all=0x0024;//设置接收中断为4级5 O; n/ x( p/ h' F1 }# u8 B
SciaRegs.SCIFFCT.all=0x0;
7 j$ M" f/ q& _, F- C1 @ SciaRegs.SCIPRI.bit.FREE = 0;//仿真模式下是否自由运行2 u) \, W; N( W$ G7 y
SciaRegs.SCICTL1.all =0x0023; // Relinquish SCI from Reset, k5 L( d: C9 e% K! S+ p
SciaRegs.SCIFFTX.bit.TXFIFOXRESET=1; //发送FIFO复位
$ ]6 e6 i5 r" N* a# | SciaRegs.SCIFFRX.bit.RXFIFORESET=1; //接收FIFO复位
$ i$ |/ {% I* O% y" e9 U! u}( a# D% i3 @: j2 F7 Z U+ s
; N% k# f- o1 ~, z1 Z(2)接收中断和发送中断
" T. }- `: r- ?! B2 m" A+ o* F; N
+ ^! p4 R `5 D8 ~2 r0 ginterrupt void SCI1_RXD_isr(void)
0 `+ ~) u2 \, o3 K6 L1 i/ V{6 `. C& B! y' T
UINT16 RxData;: M. |* x. ~3 M
//RxData = SciaRegs.SCIRXBUF.all;) p( i: T2 s/ g' P4 ]. H% E' z
//上一个数据帧应用层未取走,数据丢弃
6 u0 t3 c3 `8 p6 \5 ? T7 G. ^ if ((KeyBoardRxFrame.status == UART_FRAME_RX_END) || (KeyBoardRxFrame.index >= 40))
9 Z( R2 a( ~8 w. } {' y7 ^! M# E: i% c+ t$ o
KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;1 Y* P# f4 K7 g, c0 p9 R
KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;
2 ]# A, H- U# [' D" i KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;" r3 m1 h6 | }4 P+ ]
KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;% Z! X$ l# q" p: S9 k! H
}else6 o! C9 D& n9 }3 r" Q
{0 v4 H! L T- G4 ?9 {" w; ~+ Z) R
KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;
{7 h- U3 T$ m4 M9 c KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;
! V& d, E$ W5 m0 O# x+ d KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;6 h* T, Y' m6 N$ ]& D/ P
KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;
7 a2 ]9 i+ ]5 F KeyBoardRxFrame.ticker = KeyBoardRxFrame.spacetime;3 k" p% S. A* C& Q, q
}. N' i) _+ P/ q. @3 @. n* O
" u; X; V! s* w; @" P SciaRegs.SCIFFRX.bit.RXFFOVRCLR=1; // Clear OveRFlow flag
4 i+ f, T" b8 y) a5 t s SciaRegs.SCIFFRX.bit.RXFFINTCLR=1; // Clear Interrupt flag
& s* I- b9 `8 k3 f) e( Q! K" |# G. ?; r, D
PieCtrlRegs.PIEACK.all|=0x100; // Issue PIE ack
: @: g+ \" C7 Q+ U$ B. m}1 j( @6 G+ f2 l( n+ k- i
interrupt void SCI1_TXD_isr(void)
# b& }) A8 U! i7 r8 D{, s1 l4 v( n) v& n6 P
Uint16 i;7 p& ]4 w* N$ j* \. d" v
Uint16 len;) r, m& D: J" F5 o/ V
// 发送一帧数据没有完成2 a0 ^( p5 H1 s
if(KeyBoardTxFrame.index + 4 < KeyBoardTxFrame.len) ( s7 r+ J2 T9 x" W1 a; k
{ c, o" x, b0 T5 _; D: }
SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];. W( j( B) t/ J, }% j
SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];1 d) @; n) j p4 Q) @
SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];0 G3 K: F' @) d3 t) o8 Z9 z
SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];0 i4 I1 j4 G- h6 {
1 s* B$ [0 N* ^5 t+ {" X% }6 n0 D
SciaRegs.SCIFFTX.bit.TXFFINTCLR=1; // Clear SCI Interrupt flag清除后产生中断, }3 ~& ?) D1 ~9 Y
}* `. R1 I' ^: Z0 |
else* [6 F5 {& \, o
{
( Y' E- _$ ]% k //发送剩下的数据
: I$ k: T, j& D/ F; h: u len = KeyBoardTxFrame.len - KeyBoardTxFrame.index;
+ t7 V" v) m5 d9 U* H7 Z0 R for(i = 0; (len <= 40) && (i < len); i++)
3 H8 ~) Z/ B( U9 A {' A, j' x( E( w* N }2 x
SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];( O4 L/ w) W# v6 l, ]8 K
}
{$ Q' f% Z2 }- |$ a' A
6 M8 }# S/ z0 E; y //一帧数据结束
' J; P( n4 G% a& s5 b- E3 J" S5 ^ if(KeyBoardTxFrame.len)
; g+ O8 I1 \" l- Q {
7 k0 k9 O# J3 Q! i/ B KeyBoardTxFrame.status = UART_FRAME_TX_IT_END;4 m5 v! ? A2 U
}% j5 X# T. M+ m
}. K* Q" y) X Q* y
PieCtrlRegs.PIEACK.all|=0x100; // Issue PIE ACK1 h% q* V, ]1 W0 Y9 \% ]* U
}* O4 e8 D9 p7 V! m3 @9 H
% w9 d2 s7 s j, Q$ e" R
(3)读取不到4个字节的数据2 H, I# Z: E9 @% F$ w. ~( E: D
+ S% r: L, D* k' l: r% qvoid SCI1_RX_FIFO(UART_FRAME *pFrame)
! u7 C+ c8 D2 }% m) V/ b{
W2 y- B3 f+ Y Uint16 maxNum = 0;
- Q9 p8 U7 \9 c7 O while(SciaRegs.SCIFFRX.bit.RXFFST && maxNum < 4)( Y0 y: [# p- G) i" G) P
{* ] V! C, A6 M+ y& \! V! Q
pFrame->pdata[pFrame->index++] = SciaRegs.SCIRXBUF.all;& \) G* P6 Y5 B
maxNum++;7 @0 t! g& l9 q" t
}
/ A2 H v1 R' \8 }}+ {, B* I0 M2 K: B5 w
0 u( K9 W0 d+ _3 Y$ R& h. y(4)在应用程序需要2ms周期查询接收数据是否结束
+ _" W' \) S- u1 e: L9 {6 {static void KeyboardJudgeRxFinish(void)
0 H7 N* o2 F% W7 V( w{
0 E U8 E9 x9 V% J# G //超时或数据长度大于40一帧接收完成
0 O% w1 o; R2 F j' ^& p L$ z7 N if(((KeyBoardRxFrame.ticker <= 0)&&(KeyBoardRxFrame.index > 0)) || KeyBoardRxFrame.index >= 40)8 t" B6 `0 X/ D5 t: J
{. N2 Z; X/ F! f( e/ v" Q
SCI1_RX_FIFO(&KeyBoardRxFrame);
8 v0 d9 g$ U0 K KeyBoardRxFrame.len = KeyBoardRxFrame.index;
M( |& X" ]" z, `" t" M+ a& x KeyBoardRxFrame.status = UART_FRAME_RX_END;//数据接收完成,应用可以取走数据
2 d, q* k. {7 T }7 ~/ z4 r) Q a' p) Z
if(KeyBoardRxFrame.ticker > 0)4 Z7 ^ L& F7 m7 W* Z/ a9 i, s
{, I7 u1 \; |! ~( b, T
KeyBoardRxFrame.ticker--;
( p9 b/ {8 T' h6 W6 ]) x5 p) c/ O0 | }
! |, d- p# t- Y% y}
, J' `9 ^7 Q$ I* a
5 n' P6 `5 f+ y' E0 o2 x(6)发送. J* [( d$ J6 b5 |* l
void Keyboardrs485TxFrame(void)3 ^: R: m; D/ ~9 o
{
) j8 K x) }2 p7 [ SCI1SetTxMode();
0 L* b7 T8 P4 u& ?! j: U //如果当前帧正在发送,又重新请求发送一帧数据,则请求的数据丢弃
b) E8 c, p: J& k$ c7 v if(KeyBoardTxFrame.status == UART_FRAME_TX_ING)' e; Y# r" [* Z4 `4 \/ I0 n! Q
{2 s+ J& G+ B( j9 F0 p. F
return ;
6 {2 q6 M% J. f: [ }
# \# m3 a. o2 \# o //启动发送第一个字节后,产生中断,接着数据在中断中发送完成4 t! @2 R+ l4 q6 i- P
KeyBoardTxFrame.index = 0;0 M3 C2 y2 y2 ~# D
SciaRegs.SCIFFTX.bit.TXFFINTCLR=1;//启动发送中断, q& Q4 }! ?* m
KeyBoardTxFrame.status = UART_FRAME_TX_ING;3 m8 `* z# x# b& g: |" @
}
! P. b+ Q/ B. {/ p: L; W" a |
|