|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
本文介绍DSP高效接收和发送不定长度的数据,该方法减小cpu的中断次数,经过长时间检验,该方法安全可靠效率最大。我使用的是28034只有4级FIFO,在优化前中断深度设置为1,cpu频繁中断,导致正常程序受影响。经过改进,设置发送中断深度为0级,接收中断为4级,只有在数据发送完成和接收满4个字节中断。
# @& W' O# ~' x V( d" Q4 Z1 i接收流程为:等待接收中断—》读取4个fifo数据—》超时检查—》读取fifo剩余数据。这样就会接收完整的一帧数据。& c' G. B5 r* j+ F" d
发送流程:触发中断开始发送数据—》写入4个数据到发送fifo----》等到fifo为空中断–》写入下4个数据到fifo----》写入最后剩余数据。
3 t" t0 y, T6 h具体如下:
' H) d3 K v5 ^$ ](1)初始化配置
! K1 @3 [2 X6 P0 ^void scia_init()
5 @) x1 @0 n' f* O% ?. k6 ^{1 ~# f3 k! ` z" H( n) {& P
// Note: clocks were turned on to the SCIA peripheral6 ~9 n! ^" G% u5 w# R2 \7 E
// in the InitSysCtrl() function* x* H/ K5 U) O F/ W" Y
SciaRegs.SCICCR.all =0x0007; // 1 stop bit, No loopback
3 V! y- t' G' O$ o6 C# j7 D( I // No parity,8 char bits,
9 e$ q1 \" ]5 e8 J Q6 s // async mode, idle-line protocol# _" O$ `- v, b; y
SciaRegs.SCICTL1.all =0x0003; // enable TX, RX, internal SCICLK,
* Z4 t% G( L& V4 ^ // Disable RX ERR, SLEEP, TXWAKE1 m. i: e- i& }' a
SciaRegs.SCICTL2.bit.TXINTENA = 1;//使能发送中断 `5 P8 o0 C0 p6 i6 K0 m8 }
5 C9 t7 P! u- x3 f$ X# Y5 V6 Q, z; d1 M
J8 y; E3 k2 t& b' U# g
SciaRegs.SCICTL2.bit.RXBKINTENA = 1;//使能接收中断
: T' A/ V9 i1 n+ A4 L3 x) j / `8 e5 h7 A: v. s. j3 }7 @% N
//BRR = (LSPCLK / (SCI Asynchronous Baud * 8)) - 1 ,LSPCLK=30M,
+ n1 U7 a9 Z+ D5 k. l //BRR = 0x0020, baud=115200
T' }; c5 Z# y3 s! H; k8 W% L //BRR = 0x0007, baud=460800
& i0 W- a3 |; E' d2 W# W% s //BRR = 0x0061, baud=38400
3 [' ?( x6 ~. O, w- o, {6 A SciaRegs.SCIHBAUD =0x0000;
8 l% B; f3 E x( D SciaRegs.SCILBAUD =0x0020;//
1 L* F) k9 G' T! _: z: B SciaRegs.SCICCR.bit.LOOPBKENA =0; // Enable loop back& I3 S$ X' h$ ]- K; A) y2 l& ~+ B
SciaRegs.SCICCR.bit.STOPBITS = 2; //
& H6 P2 V, l* ]# G SciaRegs.SCIFFTX.all=0xC020;//设置发送中断为0级
r5 ~8 H4 a9 Y) ^8 R SciaRegs.SCIFFRX.all=0x0024;//设置接收中断为4级
8 i1 `1 F6 Q! X2 |. F1 }7 g/ U, Y SciaRegs.SCIFFCT.all=0x0;0 a R+ z( A+ W4 y: b
SciaRegs.SCIPRI.bit.FREE = 0;//仿真模式下是否自由运行 n( J P2 M8 N
SciaRegs.SCICTL1.all =0x0023; // Relinquish SCI from Reset7 X$ J1 w1 g- D/ P( d1 ]9 E
SciaRegs.SCIFFTX.bit.TXFIFOXRESET=1; //发送FIFO复位# R) e4 @, K' v; b: F9 G) X" j
SciaRegs.SCIFFRX.bit.RXFIFORESET=1; //接收FIFO复位 % t' P0 M: V2 N4 X1 P
}0 h3 d8 Q" ]6 S* ?& Z
# A! d3 [1 @; L/ V8 \(2)接收中断和发送中断& S5 r- u/ c2 Q# g3 f8 |- g+ |
/ f# U& L2 r H) t: K! xinterrupt void SCI1_RXD_isr(void)
2 G( ]9 ~& k* e, Y1 L) T{
V4 r; S* q: @ UINT16 RxData; W. z! q& F$ ^# n$ N
//RxData = SciaRegs.SCIRXBUF.all;7 I% Y2 F* t3 J/ l5 h: ?9 f2 E
//上一个数据帧应用层未取走,数据丢弃- o! u2 f' A' T' W4 q8 P9 R, _- J
if ((KeyBoardRxFrame.status == UART_FRAME_RX_END) || (KeyBoardRxFrame.index >= 40))
* L4 M% `* e: W { x0 @$ o) O( p, y
KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;1 G8 U8 W4 ?! `) D4 p
KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;4 K8 K! @) h6 E
KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;% A! @ G3 Z) j
KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;+ f+ f' V( W3 t5 ]: P
}else
( T7 }% ^/ x Y) T# U1 a6 S {
4 ? n; F/ P/ j- C$ I8 R' m! F KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;
+ I6 N0 ]7 n# f2 L6 e% S9 F KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;9 @& d ?, G$ T# G+ C2 u' p
KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;
- r; Z/ a# u. S: m; h G( l KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;
" O8 n4 t1 q: K; O* b KeyBoardRxFrame.ticker = KeyBoardRxFrame.spacetime; b& R" }/ M2 f- R. C6 j
}6 p5 W6 {' a A/ L6 a4 ~$ | G
: [' X- x6 U0 X. l' n6 r' d7 Z
SciaRegs.SCIFFRX.bit.RXFFOVRCLR=1; // Clear OveRFlow flag" p- D) B: b4 @* g
SciaRegs.SCIFFRX.bit.RXFFINTCLR=1; // Clear Interrupt flag7 b7 {" ]* ^" w9 ]$ Y
5 Y3 j* L( I3 h) ? PieCtrlRegs.PIEACK.all|=0x100; // Issue PIE ack' z2 o2 G+ w9 R2 b
}
) m* T: R* Q" [3 x/ H3 C/ ointerrupt void SCI1_TXD_isr(void)9 ^+ A4 ~9 a$ F- X6 h
{8 A: j; y. ~. O5 [
Uint16 i;8 |! k; q. g6 D; {) X' I
Uint16 len;
: H9 |8 `6 J# u* `, I // 发送一帧数据没有完成$ R. f: ]: g2 i) ]; d0 S
if(KeyBoardTxFrame.index + 4 < KeyBoardTxFrame.len)
' e' @3 @* p2 D8 }6 g* M1 r {8 Q) F2 J/ _. m U( K& Q
SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];. A7 g* D; _9 J9 @
SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];
' G3 u- ?' Y' B# F5 _4 Y SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];
& G* V$ ?, k: V$ s% o SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];
F C } l! P7 \( t
' A. {9 a6 l4 P0 G! k7 m SciaRegs.SCIFFTX.bit.TXFFINTCLR=1; // Clear SCI Interrupt flag清除后产生中断
; `$ z6 @+ y7 x }
$ @6 {: j( B: Q/ s else6 R& ^: K* d6 E; ~9 r# y a& Y
{# N% V& E5 z, {/ w8 M& h9 a
//发送剩下的数据
1 t e* g$ `7 R- n, p/ I& K len = KeyBoardTxFrame.len - KeyBoardTxFrame.index;
Q- P* t# }5 v1 N: O- U for(i = 0; (len <= 40) && (i < len); i++)% X+ t4 U0 B5 R% ~/ I7 f+ C9 h
{; R9 k5 f- b3 x! V2 j e: s) k
SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];
% D/ X8 P; ]7 q. q8 i }* B) n# f; a* O7 G, j* u
! q6 I5 d+ Y" B
//一帧数据结束
2 k1 F8 }4 M# r, y0 H if(KeyBoardTxFrame.len)* n5 ~* g& b: L; H n- r
{" u" X1 {8 }* }# g% T+ |
KeyBoardTxFrame.status = UART_FRAME_TX_IT_END;9 B9 Q4 z8 w; L* s
}
# x! M3 q7 P O; M }
! L f L3 D) O+ v% ]. H PieCtrlRegs.PIEACK.all|=0x100; // Issue PIE ACK
3 | {8 q- x7 w/ |" D5 m5 k/ |}9 }% \9 v7 E+ u
5 y- O! N5 X( q `1 r4 i, ?4 M(3)读取不到4个字节的数据: p, E1 ?5 m+ R5 h" o2 X
3 N3 C9 s _6 z6 Mvoid SCI1_RX_FIFO(UART_FRAME *pFrame)
, J( F; Y x$ M# a) A3 ?3 M{1 y/ B; B- K, x3 f( k# l2 ^
Uint16 maxNum = 0;
; A$ s" C N7 j% `# C1 c while(SciaRegs.SCIFFRX.bit.RXFFST && maxNum < 4)1 l: \: z( t( e5 Y% Q
{4 t1 U3 h2 \( T8 ^4 U+ c1 r4 [
pFrame->pdata[pFrame->index++] = SciaRegs.SCIRXBUF.all;1 l* s6 ~# K2 z
maxNum++;' j& L* U3 G2 T2 w! i$ q
}0 ]2 q. {) e1 S9 {2 P: @
}- r3 ~0 L U& e5 f7 V
: V* G& t n" j, [) i7 D$ G/ b(4)在应用程序需要2ms周期查询接收数据是否结束
% y# a9 V$ w/ K: i/ W% |static void KeyboardJudgeRxFinish(void)2 {$ L+ U' t! l4 l, |9 |
{
% S- Q; _# [2 x8 ? k; H! w //超时或数据长度大于40一帧接收完成
+ O5 U* G2 G9 S7 a2 V if(((KeyBoardRxFrame.ticker <= 0)&&(KeyBoardRxFrame.index > 0)) || KeyBoardRxFrame.index >= 40)
1 _3 t% n! ]$ \% N$ U3 Y1 @, G' }& V3 c {
! J$ P+ z" h2 Z( b- H" W- s) \" _# Q SCI1_RX_FIFO(&KeyBoardRxFrame);
, U. @! b. m% g" X# Y KeyBoardRxFrame.len = KeyBoardRxFrame.index;
" d# w4 {) g6 s KeyBoardRxFrame.status = UART_FRAME_RX_END;//数据接收完成,应用可以取走数据
* T( J! ?7 F2 m9 V7 y6 r }; I k* E' @9 Z; ]* o
if(KeyBoardRxFrame.ticker > 0)! ], D h% L; j
{( a4 U6 T' o. r5 K5 m$ N7 H
KeyBoardRxFrame.ticker--;3 m& S: P6 _7 s3 p
}& |" Q ]' M9 P
}( T( z) m) @$ [
2 r/ M, r, M% I0 M& K
(6)发送# r1 I) y/ c8 F5 Z' J X+ E
void Keyboardrs485TxFrame(void)
4 d) ?8 z. [. w k. k{
. W' C- \- z p; W! G |6 A& X* J SCI1SetTxMode();
6 T. Y8 {# I8 p/ e) g //如果当前帧正在发送,又重新请求发送一帧数据,则请求的数据丢弃4 v, [# L7 w4 k! R0 m) a; b
if(KeyBoardTxFrame.status == UART_FRAME_TX_ING). L/ e8 I0 S3 ^% x- g
{% T5 @4 E% M2 O+ O3 K" A
return ;+ _1 Q6 o U) r$ O! C
}$ j+ h+ w! ~& B* G+ t3 _) i6 B
//启动发送第一个字节后,产生中断,接着数据在中断中发送完成/ r! b8 R9 z! N, H v
KeyBoardTxFrame.index = 0;
: }: L- p0 |0 E9 O* n SciaRegs.SCIFFTX.bit.TXFFINTCLR=1;//启动发送中断
( ?; b5 |3 J5 `9 Z KeyBoardTxFrame.status = UART_FRAME_TX_ING;8 B1 Y$ c2 q* R. ~8 I& |6 I
}5 }2 M, p& o0 S$ B' S
|
|