|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
本文介绍DSP高效接收和发送不定长度的数据,该方法减小cpu的中断次数,经过长时间检验,该方法安全可靠效率最大。我使用的是28034只有4级FIFO,在优化前中断深度设置为1,cpu频繁中断,导致正常程序受影响。经过改进,设置发送中断深度为0级,接收中断为4级,只有在数据发送完成和接收满4个字节中断。: W0 j9 U! b2 `( I9 |
接收流程为:等待接收中断—》读取4个fifo数据—》超时检查—》读取fifo剩余数据。这样就会接收完整的一帧数据。! S7 O# H$ e: | K/ p
发送流程:触发中断开始发送数据—》写入4个数据到发送fifo----》等到fifo为空中断–》写入下4个数据到fifo----》写入最后剩余数据。
3 N1 I1 _# i! ^8 d, \0 O具体如下:) b- d- x. U- k/ y$ X& R8 [
(1)初始化配置
- g5 c- K& q, @- F; q9 t% B$ ]( jvoid scia_init()- O3 p; o* ~1 w* I. w
{
+ }3 W% v6 H: g* T- J // Note: clocks were turned on to the SCIA peripheral
6 d/ c8 A! E/ Z& W5 z, _ // in the InitSysCtrl() function
% j" k) [2 l2 K$ v* s& t1 s. T SciaRegs.SCICCR.all =0x0007; // 1 stop bit, No loopback% T1 m7 u$ t8 @" x# P: G
// No parity,8 char bits,, w' r7 Y5 W' ?8 }& m: B9 r- c
// async mode, idle-line protocol" f# [- g8 O1 Q, ~% A# n! h! ~
SciaRegs.SCICTL1.all =0x0003; // enable TX, RX, internal SCICLK,
0 ^/ P" I+ L/ L* G M3 r5 B // Disable RX ERR, SLEEP, TXWAKE3 i5 n/ R# U. n, p
SciaRegs.SCICTL2.bit.TXINTENA = 1;//使能发送中断
4 i0 \8 Q I7 n7 M
( T: E. n5 _% W' ~# P4 W) U ; z1 J7 r' n, y2 A7 `3 L
SciaRegs.SCICTL2.bit.RXBKINTENA = 1;//使能接收中断% x; {- i* ^$ H p1 D5 Q' Q4 E) c
; b( m9 L( B7 z
//BRR = (LSPCLK / (SCI Asynchronous Baud * 8)) - 1 ,LSPCLK=30M,
# q8 B( _0 ~- l4 }; ^ //BRR = 0x0020, baud=1152002 L* w x6 K* r- g
//BRR = 0x0007, baud=460800
7 y) t- @9 x+ \' C //BRR = 0x0061, baud=38400
: y( H! @! O7 ~! Q" B6 D SciaRegs.SCIHBAUD =0x0000;! L4 |4 ?' g- ~
SciaRegs.SCILBAUD =0x0020;//
3 L; Q: t( n- Q4 [) Q" E SciaRegs.SCICCR.bit.LOOPBKENA =0; // Enable loop back
, X; Z2 u9 C% i# m SciaRegs.SCICCR.bit.STOPBITS = 2; //
0 f" ?1 d7 d" d3 d3 G SciaRegs.SCIFFTX.all=0xC020;//设置发送中断为0级 C% ?$ R$ s- h% H& B0 t7 b: t
SciaRegs.SCIFFRX.all=0x0024;//设置接收中断为4级
! |" X+ s+ q0 }9 X$ m' I SciaRegs.SCIFFCT.all=0x0;
( B# s {$ L; {: W5 S. }& U9 R SciaRegs.SCIPRI.bit.FREE = 0;//仿真模式下是否自由运行
$ ]* P" ^+ R2 A. U" F* w SciaRegs.SCICTL1.all =0x0023; // Relinquish SCI from Reset3 ?+ ]' R4 Q* J' p
SciaRegs.SCIFFTX.bit.TXFIFOXRESET=1; //发送FIFO复位1 K, N0 M# a9 i7 t0 L! N
SciaRegs.SCIFFRX.bit.RXFIFORESET=1; //接收FIFO复位
; K1 a! T7 {5 d/ y$ s}- i" H- U( {7 {6 n W D2 E
3 T1 V. S4 B& B! c
(2)接收中断和发送中断3 c1 `& A4 ?0 h P! U
7 P" o' ?" p4 q1 A2 y7 z" }
interrupt void SCI1_RXD_isr(void)7 q+ W2 W" i. M0 n$ O
{; B i1 ]" t# _7 O$ F
UINT16 RxData;* o2 x* x5 H' ]) @8 ]3 v
//RxData = SciaRegs.SCIRXBUF.all;/ z% w9 m+ }" h/ f$ a3 b4 W
//上一个数据帧应用层未取走,数据丢弃
$ C, f4 u/ i* w" c0 n: @" R if ((KeyBoardRxFrame.status == UART_FRAME_RX_END) || (KeyBoardRxFrame.index >= 40))0 \# t$ \+ @0 g( ~
{: h/ F5 N5 A! r9 T
KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;
2 s6 H* R6 W/ B; B1 u7 V KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;* ^! Q, q; I4 m. L }
KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;
% u$ m @) m6 d KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;
: n9 n! _3 H! e6 K8 ?* f }else, _* w2 _& S* x+ E
{
+ ~5 g+ K0 a! N% i( ] KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;
$ [+ `! Y5 i4 V9 W, f5 w KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;
, R% y+ t, q& o1 h- p* n$ X: v KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;% b: i4 [! f( R1 [1 w5 z, l4 S
KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;
0 C" U( s3 h" c/ j3 R5 i: {+ n KeyBoardRxFrame.ticker = KeyBoardRxFrame.spacetime;, ^/ [% G# s/ `, x- H# M/ c# ^
}
7 o* m2 N2 [ f; y 1 @$ W% m0 e$ G9 p8 U
SciaRegs.SCIFFRX.bit.RXFFOVRCLR=1; // Clear OveRFlow flag! l. T( |8 {$ v4 Q0 w3 }
SciaRegs.SCIFFRX.bit.RXFFINTCLR=1; // Clear Interrupt flag- t' t0 k" f4 L; W$ U
: w2 y m- ]# K3 h C6 F9 E3 d
PieCtrlRegs.PIEACK.all|=0x100; // Issue PIE ack
( Y" ^- M( }: r) l% p0 W0 j# m}) b; F3 U1 _5 ]* {( ?2 c
interrupt void SCI1_TXD_isr(void)
7 h3 T% w' g& [- ?! N% j{) d u+ y) A, u- Y
Uint16 i;
4 g" i! l$ R- W: w# c- m: D Uint16 len;4 m; c* |9 E" \# ]! J3 c$ N
// 发送一帧数据没有完成4 o/ |. S* ^3 C- w9 q
if(KeyBoardTxFrame.index + 4 < KeyBoardTxFrame.len) 2 X7 n) N! n% P: w
{
) g8 \4 ~+ u1 P SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];
9 L# d& }6 ]& t SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];
9 r! F3 E' _* B7 V! | SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];0 N9 h3 D& F3 d1 X& R
SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];! B/ C" E( w H$ R- }: |2 E9 v7 k& E
2 N3 Y2 h" n% f/ w. y2 E
SciaRegs.SCIFFTX.bit.TXFFINTCLR=1; // Clear SCI Interrupt flag清除后产生中断
: @2 c! o3 y. d9 s7 ~7 f }
2 Y \0 \$ @5 ?; t else
, m/ I3 g+ k& [ {6 d4 X7 Y7 H5 t5 ?3 \9 p4 j
//发送剩下的数据
7 G1 v+ @% v/ O: m' f; m# A! _7 [ len = KeyBoardTxFrame.len - KeyBoardTxFrame.index;
. Y3 P" f! D7 \4 V! N' @+ D for(i = 0; (len <= 40) && (i < len); i++)
& R; b/ W+ @6 o+ l8 x {# O2 V, ^5 R, [. f& |- j+ C
SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];
3 Y, W# C4 |# s2 v+ ^ c# U, p, Z5 N }
! B. p. [, B* ]# ?/ j( ?
2 P0 u9 }9 M" d' w. T% p //一帧数据结束
% r' t( l4 T1 I6 s Q# ^ } if(KeyBoardTxFrame.len)
+ B/ {. p, M9 ^) r7 d5 H. c {+ f* i6 |7 C. ]- [/ Y
KeyBoardTxFrame.status = UART_FRAME_TX_IT_END;
4 R4 F( P/ ?1 I0 W }' [: l5 s; o5 v! X! P/ j
}
- N, J$ A( i/ v; Q6 a$ G2 K PieCtrlRegs.PIEACK.all|=0x100; // Issue PIE ACK
/ d8 p6 D/ f9 ^8 p}. ^$ r6 W- z; Z& J6 s. P$ w& U. x
2 P+ c( F+ b; V0 V) F1 g
(3)读取不到4个字节的数据2 O- U; l' L/ a3 i$ \6 l
( w) q! J* ^, q; [void SCI1_RX_FIFO(UART_FRAME *pFrame)
H# [$ b# ]0 D# G8 [$ B; t6 {! @& M{, O4 U" @& R5 h% f6 M& ?7 }) o
Uint16 maxNum = 0;
$ q6 Y8 n% j, m p while(SciaRegs.SCIFFRX.bit.RXFFST && maxNum < 4)
9 ~0 L" B b! L: b7 E4 p" d& t {
6 m: b/ u4 X+ j- b& s pFrame->pdata[pFrame->index++] = SciaRegs.SCIRXBUF.all;/ o6 y6 j0 a( C' [9 q
maxNum++;
K+ s( e# i( x# c- J' }* Y0 k }. L( ?# w& l- |9 P0 `5 |, _" c
}
4 V z/ Q; h/ b; W; s) N& _* h; g6 B! ~ d- G1 L6 [; z7 J4 i
(4)在应用程序需要2ms周期查询接收数据是否结束: X9 N# J8 G3 e2 ]" C
static void KeyboardJudgeRxFinish(void)
3 R2 \: D, b) R{
8 {( J3 N" L" [ O! R$ i. _ //超时或数据长度大于40一帧接收完成
4 L6 @ L/ C6 w+ e. W$ P9 E: ] if(((KeyBoardRxFrame.ticker <= 0)&&(KeyBoardRxFrame.index > 0)) || KeyBoardRxFrame.index >= 40)
& h/ l8 r2 E4 }, P" N B' H& } {6 s0 |% P( X/ M+ r) B! z3 e; }1 @
SCI1_RX_FIFO(&KeyBoardRxFrame);! a; T. U) Y7 d) P2 L2 \
KeyBoardRxFrame.len = KeyBoardRxFrame.index;: R. |+ a+ J P+ |
KeyBoardRxFrame.status = UART_FRAME_RX_END;//数据接收完成,应用可以取走数据2 E0 f2 Z, a% p; K) ?7 H
}
6 U5 Z( Z9 p1 i8 ? if(KeyBoardRxFrame.ticker > 0)
3 [& J4 z) c1 W {
7 l; h, u: F$ X1 Q: U+ v KeyBoardRxFrame.ticker--;
. e7 F8 P# ~4 p0 z" ^ }
( x. W6 G& Y; i! v}
# {+ ~& N; X4 x; @2 N5 a
4 R# B$ M/ ^+ w4 |5 M(6)发送! Y& K# t1 C9 n4 s3 q; d$ J
void Keyboardrs485TxFrame(void); E7 ]) ]! V% o$ R" [0 @
{6 Z. Q6 V* H8 q5 q; X* S
SCI1SetTxMode();+ j" |0 p, p2 k. q
//如果当前帧正在发送,又重新请求发送一帧数据,则请求的数据丢弃
7 I8 ]( r9 `" H. L! _+ M$ H7 ` if(KeyBoardTxFrame.status == UART_FRAME_TX_ING)$ D4 [6 M$ k3 `8 Q# e
{
' A8 _. K; [7 n# u3 [+ |3 l* g return ;
: a; g. o+ f4 H! Q. H0 J }
9 r' ]" G7 N+ \) |2 q: u9 a //启动发送第一个字节后,产生中断,接着数据在中断中发送完成
$ ]4 P: v5 I) t# o: p& A KeyBoardTxFrame.index = 0;' ?0 p3 G8 e; |3 N
SciaRegs.SCIFFTX.bit.TXFFINTCLR=1;//启动发送中断
5 F7 V# ]3 J$ L; j+ m KeyBoardTxFrame.status = UART_FRAME_TX_ING;2 p& @# f# X8 d, h4 x& J
}5 ~3 `2 G2 X" X4 D3 k/ p
|
|