|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
本文介绍DSP高效接收和发送不定长度的数据,该方法减小cpu的中断次数,经过长时间检验,该方法安全可靠效率最大。我使用的是28034只有4级FIFO,在优化前中断深度设置为1,cpu频繁中断,导致正常程序受影响。经过改进,设置发送中断深度为0级,接收中断为4级,只有在数据发送完成和接收满4个字节中断。
" I. q4 _6 }: N3 U, z接收流程为:等待接收中断—》读取4个fifo数据—》超时检查—》读取fifo剩余数据。这样就会接收完整的一帧数据。/ D8 p4 X( @' ~& F: A, k5 z6 D
发送流程:触发中断开始发送数据—》写入4个数据到发送fifo----》等到fifo为空中断–》写入下4个数据到fifo----》写入最后剩余数据。
5 k7 @4 u7 s$ h7 G4 }. E2 ~具体如下:
. ?2 E4 Q5 N+ |: U8 k( C, u(1)初始化配置/ G6 B1 l$ D$ Y
void scia_init(). L0 O* A7 F* \% @% o) N
{! l# }# z! j( c1 ~8 m) w
// Note: clocks were turned on to the SCIA peripheral8 ~& g0 y7 ?% |0 H/ a
// in the InitSysCtrl() function
V; R2 m; o/ m: v6 R5 k SciaRegs.SCICCR.all =0x0007; // 1 stop bit, No loopback4 G3 A" i- R f
// No parity,8 char bits,# [/ ?- _3 B' o& x6 z
// async mode, idle-line protocol
1 A+ V1 a8 _; C6 w+ E% y% T SciaRegs.SCICTL1.all =0x0003; // enable TX, RX, internal SCICLK,
3 K( n* N- e, X: Y& k // Disable RX ERR, SLEEP, TXWAKE4 U2 t- I9 `: s* g0 z8 ?
SciaRegs.SCICTL2.bit.TXINTENA = 1;//使能发送中断
( k$ H' {7 i6 ^7 q9 D3 g! k* \
9 y, E8 Y9 _. \" H 1 U0 K9 x: H, [8 O) x( d0 [
SciaRegs.SCICTL2.bit.RXBKINTENA = 1;//使能接收中断
5 q3 `6 Y2 O5 V. m$ o# A4 l8 L, ?
; m0 l" C3 c# _; C! d# F //BRR = (LSPCLK / (SCI Asynchronous Baud * 8)) - 1 ,LSPCLK=30M,6 H, \/ L, V$ V
//BRR = 0x0020, baud=115200
8 P% k3 i, H2 z: ?8 z! r //BRR = 0x0007, baud=4608004 R( c, K- c) n4 [5 X
//BRR = 0x0061, baud=38400; s- r& e8 H7 `4 ?
SciaRegs.SCIHBAUD =0x0000;
2 `( H+ i6 ?5 U0 b6 o4 t SciaRegs.SCILBAUD =0x0020;//, L; n5 U- w/ u3 H
SciaRegs.SCICCR.bit.LOOPBKENA =0; // Enable loop back
. x+ x( Z4 Y! l, b& H6 l SciaRegs.SCICCR.bit.STOPBITS = 2; //1 y8 V6 e9 M, z# t
SciaRegs.SCIFFTX.all=0xC020;//设置发送中断为0级4 M- A1 J7 W- y9 t* F0 V
SciaRegs.SCIFFRX.all=0x0024;//设置接收中断为4级/ ~$ V# v0 T- ?: r
SciaRegs.SCIFFCT.all=0x0;
% ]( {3 M! `+ I0 l" G, U SciaRegs.SCIPRI.bit.FREE = 0;//仿真模式下是否自由运行/ H. ], ^) J/ {% H3 {9 a
SciaRegs.SCICTL1.all =0x0023; // Relinquish SCI from Reset. A! m. `9 @7 O* x) \# R
SciaRegs.SCIFFTX.bit.TXFIFOXRESET=1; //发送FIFO复位
5 G* k! |' A, @0 J( d) J* x" Q. G, U SciaRegs.SCIFFRX.bit.RXFIFORESET=1; //接收FIFO复位 5 p! V% H: o3 {+ j4 K4 h
}
2 v! u. U- W% K5 u3 o1 f
3 p" Q8 S+ @% z8 G. T6 }: g(2)接收中断和发送中断& [$ y7 N5 I0 V/ i `2 Z4 \
5 ?+ Z5 M# a: |) Finterrupt void SCI1_RXD_isr(void)* ?$ o, r" _8 n, F2 c
{
- w9 \" V* |5 x j UINT16 RxData; s! q: N* u. w6 R. j0 x
//RxData = SciaRegs.SCIRXBUF.all;
4 B, W% m) p$ d //上一个数据帧应用层未取走,数据丢弃0 S- K/ n4 |$ L4 D: n: t
if ((KeyBoardRxFrame.status == UART_FRAME_RX_END) || (KeyBoardRxFrame.index >= 40))+ ~- N: T- B2 P* O8 L% v8 ^
{
/ t& k: V. D% S9 t KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;( S1 I8 L5 S/ x. a" ^ C
KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;1 r- G2 `5 M6 \6 `9 c# Z
KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all; g' Z" p9 K; G8 n, L, c
KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;; L. j) y2 f/ M
}else
8 M0 Y) ~( X! d8 t0 G {
: q. H8 W, x( R KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;- w, ]* V7 {1 p4 Z
KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;
6 C+ C$ Y3 |- K' R, A KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;! s1 g% S0 Z7 L: I% _3 Y. C
KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;
1 n9 G3 l8 k0 D KeyBoardRxFrame.ticker = KeyBoardRxFrame.spacetime;
) O5 \8 c) Q; M! b a% {5 ]: Y }
- q0 _& Z: y. g
4 m8 G K2 p- c N2 y/ ? SciaRegs.SCIFFRX.bit.RXFFOVRCLR=1; // Clear OveRFlow flag3 X* n% Q; }0 U: o
SciaRegs.SCIFFRX.bit.RXFFINTCLR=1; // Clear Interrupt flag+ K% U3 d! b6 o
" s* o3 Q$ U3 B0 m2 K E
PieCtrlRegs.PIEACK.all|=0x100; // Issue PIE ack
; `4 a: U6 d' f2 m}3 V1 a: D- ^% \% C6 X( n5 F
interrupt void SCI1_TXD_isr(void)8 x. m% J3 I$ E
{9 Y( H, |1 Q0 }
Uint16 i;
( k7 c2 ^9 }& T- F* P4 n Uint16 len;# D w% E, O% }/ Q; D: f8 a
// 发送一帧数据没有完成% Z: ?1 m3 U+ ?! o& |8 \
if(KeyBoardTxFrame.index + 4 < KeyBoardTxFrame.len) 6 W9 I* e, [ I. ~% {/ ^0 g# q
{
p) P6 o' [" c. O SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++]; |7 k1 @& m+ ]( J+ a }# J/ L
SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];& I- y4 [# A0 ?
SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];5 M- e1 a% Q, ]# {* b4 l
SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];# I d" d( F' i% l1 P* W3 H% F) C, `
& u+ n( J- b V9 B! S ^# L6 H+ r( S
SciaRegs.SCIFFTX.bit.TXFFINTCLR=1; // Clear SCI Interrupt flag清除后产生中断/ S4 n+ y( i# t* E
}$ l( X! @% y9 k0 k4 l& ^
else
, ^/ c% B% e" j+ ~ k4 y$ P {/ m' k2 R5 i& j* Q
//发送剩下的数据
' C9 [; U) y: R+ _$ `' y1 L1 L len = KeyBoardTxFrame.len - KeyBoardTxFrame.index;8 O$ v9 X5 l, P8 i9 Z; y2 t
for(i = 0; (len <= 40) && (i < len); i++)
2 y0 e- u" W: P9 B' S9 Y6 K {% s' C" @9 W- S- F2 E
SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];
! B$ T' ~( j2 V9 }- F }
" r" e5 q; @) }! D: A2 B $ w6 J2 Y q2 U8 K( b
//一帧数据结束
/ | v* d/ ], B4 Q- Z# C5 P. Z' N if(KeyBoardTxFrame.len)
7 r$ B- O$ M a% |8 } {, y% }, S$ d e; K& d* O r' _" b7 @
KeyBoardTxFrame.status = UART_FRAME_TX_IT_END;" V k/ _3 Z' y6 W, V7 k
}
* D" b9 @; E E( \ }
# F/ U+ r% Z" B PieCtrlRegs.PIEACK.all|=0x100; // Issue PIE ACK* ?! n( s8 @: g* o3 q" ?0 f' A" w
}' J" o# i3 T% x I
3 o" v% {' U8 f" t# q8 o(3)读取不到4个字节的数据
( @% [7 u# U, {9 s9 J5 G
( D, u! i8 e5 wvoid SCI1_RX_FIFO(UART_FRAME *pFrame)9 h8 s# e8 `7 z" G, ~* K' h
{
' ~& S! u5 U+ A2 Z8 l& X3 {! ]4 R7 E Uint16 maxNum = 0;- I$ j. |: h0 g9 K5 T% B
while(SciaRegs.SCIFFRX.bit.RXFFST && maxNum < 4)
v* f* `- G) }( z3 g7 ` { E& H' N$ u1 i
pFrame->pdata[pFrame->index++] = SciaRegs.SCIRXBUF.all;
" J/ n8 Y. Y) @/ P" Y, Y7 X3 h maxNum++;* i$ G$ G$ p o; A
}" [+ f6 C7 U% h# Y5 O1 Z1 t
}
7 J$ a: {( d' T7 o+ J' L" c3 Z9 t( B U' w
(4)在应用程序需要2ms周期查询接收数据是否结束* n' f* N9 K4 p1 [! k% i& s- w
static void KeyboardJudgeRxFinish(void)# C6 [* |: l- N& t% P
{2 ?: I2 N% ~& ]0 B f7 M$ I" ^
//超时或数据长度大于40一帧接收完成 o( J. A+ }) p! F" q
if(((KeyBoardRxFrame.ticker <= 0)&&(KeyBoardRxFrame.index > 0)) || KeyBoardRxFrame.index >= 40)
6 f/ ?' N7 C z4 w {* O# V5 n4 V) _' b" ^, X
SCI1_RX_FIFO(&KeyBoardRxFrame);* M0 t8 k5 l/ o+ K; f$ D
KeyBoardRxFrame.len = KeyBoardRxFrame.index;, N( z; _4 d/ J
KeyBoardRxFrame.status = UART_FRAME_RX_END;//数据接收完成,应用可以取走数据- G# m( h/ U! t) j. A' ]- e- [* v
}" P8 V+ q0 i9 ?, c$ m8 Y- M* U
if(KeyBoardRxFrame.ticker > 0)0 V& V" |" x f) s$ a# d9 }
{# K/ q% Z- p9 f. X! P: m& p
KeyBoardRxFrame.ticker--;
/ x! Y! I ^; Y* |5 X$ D) L+ j( @ }
% \: s+ _& `: M' G}
$ T4 i( f0 b0 j# z$ W4 @* M$ K
4 J9 |# x" J" J4 n% h) c9 A' x t; F(6)发送
0 O6 k% B6 }2 C4 evoid Keyboardrs485TxFrame(void)
! I0 ~. R* B5 }+ K: s- l( ^& x{
' L, E: N: d- G- E$ L0 P5 J/ s SCI1SetTxMode();2 r' s0 Q" s; [7 S0 k* \
//如果当前帧正在发送,又重新请求发送一帧数据,则请求的数据丢弃. @# F3 w5 r: }; L- y
if(KeyBoardTxFrame.status == UART_FRAME_TX_ING)2 K/ W% E4 U' s# T' t- S5 j
{% F2 N/ j# {8 a2 P
return ;1 H1 z k6 M4 [ V7 N8 B
}$ p! d. G' a/ m9 @
//启动发送第一个字节后,产生中断,接着数据在中断中发送完成6 Y$ _1 D: S% U$ E4 c# g) W
KeyBoardTxFrame.index = 0;
) x V! c( ] |$ m! \% R. V SciaRegs.SCIFFTX.bit.TXFFINTCLR=1;//启动发送中断
: V6 |+ W \' y- `, d4 C KeyBoardTxFrame.status = UART_FRAME_TX_ING;$ C8 N: Z; B3 `/ O# a2 ?
}
( `. m) m7 i1 U6 L. s |
|