|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
本文介绍DSP高效接收和发送不定长度的数据,该方法减小cpu的中断次数,经过长时间检验,该方法安全可靠效率最大。我使用的是28034只有4级FIFO,在优化前中断深度设置为1,cpu频繁中断,导致正常程序受影响。经过改进,设置发送中断深度为0级,接收中断为4级,只有在数据发送完成和接收满4个字节中断。 r: s1 D4 o) @' |
接收流程为:等待接收中断—》读取4个fifo数据—》超时检查—》读取fifo剩余数据。这样就会接收完整的一帧数据。6 b! ^) Q/ o+ o& e8 ?
发送流程:触发中断开始发送数据—》写入4个数据到发送fifo----》等到fifo为空中断–》写入下4个数据到fifo----》写入最后剩余数据。
/ n0 F1 B Q5 t9 V( I: j& C具体如下:2 W( e/ C7 u" Q. [# r
(1)初始化配置1 G8 V' ]. ?& o) M- U
void scia_init()
5 l M' @0 d. o* |' e{1 V" J4 Y+ }8 C9 y0 ]
// Note: clocks were turned on to the SCIA peripheral' e5 C A- t, u: ?
// in the InitSysCtrl() function5 l7 n- c* j' K9 g) o5 r3 T
SciaRegs.SCICCR.all =0x0007; // 1 stop bit, No loopback# L% M! I @4 r& C5 k0 F' n
// No parity,8 char bits,
% _; V" s4 \* _# y, E- x. W( ~ // async mode, idle-line protocol
% d- ~$ I% }- }1 P$ H7 C7 E SciaRegs.SCICTL1.all =0x0003; // enable TX, RX, internal SCICLK,
* ^1 ~* L6 ~ q/ Y" [8 ? // Disable RX ERR, SLEEP, TXWAKE, ^4 d5 A: E4 E. l4 q D
SciaRegs.SCICTL2.bit.TXINTENA = 1;//使能发送中断 X$ i3 u0 y/ B/ ~
9 [' M: W4 o5 e4 P# O( T) U
% P$ H8 i r" ?2 J- D/ q- a SciaRegs.SCICTL2.bit.RXBKINTENA = 1;//使能接收中断- \- ^0 P; _ a8 Q7 j
7 F; z3 w% K! x+ l# j6 A( e" @! A3 @
//BRR = (LSPCLK / (SCI Asynchronous Baud * 8)) - 1 ,LSPCLK=30M,
8 [5 a4 E% I8 l- E2 D/ E7 _$ N' Z //BRR = 0x0020, baud=115200
7 t* e+ e1 t: G9 ~- z# s //BRR = 0x0007, baud=460800
- Z4 O% i( U$ b" l0 U, N //BRR = 0x0061, baud=38400
! ~% r6 Z: U; s3 |% T: S SciaRegs.SCIHBAUD =0x0000;4 m& |8 l( G; v- M. Z
SciaRegs.SCILBAUD =0x0020;//
5 |1 }% R2 b# C( ~" _ SciaRegs.SCICCR.bit.LOOPBKENA =0; // Enable loop back
' v' N ]( w, g3 ~7 T7 ]% W* r SciaRegs.SCICCR.bit.STOPBITS = 2; //5 W1 `7 }$ {! u k$ F. C
SciaRegs.SCIFFTX.all=0xC020;//设置发送中断为0级# F( y2 ?8 R: |8 d" l1 `
SciaRegs.SCIFFRX.all=0x0024;//设置接收中断为4级% l& t6 a# A" a2 B* z) g. y
SciaRegs.SCIFFCT.all=0x0;
$ L. v2 C7 {" e4 `: ~! o# e SciaRegs.SCIPRI.bit.FREE = 0;//仿真模式下是否自由运行$ q# A4 N: z# }4 N' q. x
SciaRegs.SCICTL1.all =0x0023; // Relinquish SCI from Reset/ c( @: R( y1 {' W9 \ {
SciaRegs.SCIFFTX.bit.TXFIFOXRESET=1; //发送FIFO复位
! D3 \* k4 T8 C; [5 _ SciaRegs.SCIFFRX.bit.RXFIFORESET=1; //接收FIFO复位
/ x6 D6 y1 I2 s* ?' [' R}: q4 j- w( J, ]
( _; x0 T/ ?) m* `' J2 H0 W
(2)接收中断和发送中断1 r/ b7 R* y- V( z
' p$ e4 Y ]! L* G4 einterrupt void SCI1_RXD_isr(void)0 i% H& r% Y$ ?0 Q k1 m/ ~
{2 H7 s% Q; O: i' M/ H
UINT16 RxData;
( B! j. O/ r$ U //RxData = SciaRegs.SCIRXBUF.all;
) B0 c! M$ Q. q //上一个数据帧应用层未取走,数据丢弃1 J$ H F% R+ H3 s
if ((KeyBoardRxFrame.status == UART_FRAME_RX_END) || (KeyBoardRxFrame.index >= 40))/ K2 U; U; y7 B8 S {
{; s2 X* d" C) U& G
KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;
6 r* Z2 n h0 O0 {" P# @: X# T KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;
* m' h& |% K- K6 @* | KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;
7 Y, P% y# Z2 N* _# j3 h( h KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;' t- n# ~9 ?* d3 k4 [
}else1 T% H- s; R3 n+ Q1 m7 O! ~! z0 d
{
( T2 ^( O- C- o% f& v KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;% {7 @( q- N" s! w
KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;
9 L6 A8 O0 j3 R' p3 ^ KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;- a' Z+ t) _3 t/ f
KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;
% |& i1 X3 R# n KeyBoardRxFrame.ticker = KeyBoardRxFrame.spacetime;
. \4 c6 v+ [5 Y6 Y }
+ E- v$ m0 h4 c D% O
6 M7 q( s# d# K SciaRegs.SCIFFRX.bit.RXFFOVRCLR=1; // Clear OveRFlow flag
& H' d) y( T4 l: F SciaRegs.SCIFFRX.bit.RXFFINTCLR=1; // Clear Interrupt flag
0 j( j$ v; i( s8 Y3 L1 R/ t) k
. A9 a4 o5 h2 ]& N PieCtrlRegs.PIEACK.all|=0x100; // Issue PIE ack+ x* P; d$ t1 @' u0 ]
}
9 m- |3 _& u+ u- O h+ j$ {+ {interrupt void SCI1_TXD_isr(void)0 F& t1 O' N0 |1 X: B- C1 d
{
5 v4 _* ~' Q$ d2 U. ^ Uint16 i;
! D" @4 ?" [% l- W# t) x* _! S( X/ w Uint16 len;1 U, R1 a0 g& j5 \3 w' W( G
// 发送一帧数据没有完成
. x5 ?: C1 V" k. ~: z! [& x3 S if(KeyBoardTxFrame.index + 4 < KeyBoardTxFrame.len) 5 p D f% D; t8 g% b4 L
{6 A# i: f, Y8 ^2 w: k5 Y1 h
SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];
$ [, F& p4 K, z0 k3 I SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];2 L0 M, Z9 b3 J( E7 a+ W0 h* }0 m
SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];
- s+ j. Q/ S G! g SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];$ V2 h; V2 j9 I: }$ s
# k1 e2 x/ Z( n SciaRegs.SCIFFTX.bit.TXFFINTCLR=1; // Clear SCI Interrupt flag清除后产生中断
, E" p. ~8 z+ \. \" [" K: i }
7 J6 H: q8 T& i: v+ H/ g else) \4 y5 e) o1 {
{2 {6 k* z( j( n. V/ f
//发送剩下的数据
0 g% {- ^/ `+ o3 C len = KeyBoardTxFrame.len - KeyBoardTxFrame.index;
5 E: _- w9 b" V* ]& Z2 h. U for(i = 0; (len <= 40) && (i < len); i++): [- g: Y6 g) ]! H- [, k
{# k$ z: k8 ^ z% l) l
SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];
7 \# O3 e3 w6 r1 y }
( R8 e) t( K3 A/ Y& Y
& M2 |4 w2 @1 J* ~. Q/ w //一帧数据结束
9 h6 N! n+ ?6 V+ Z& Z C8 Z- x/ H! P if(KeyBoardTxFrame.len)
7 i$ q& d: A3 [! M, Z" K {
# @3 `8 @+ V4 ^5 @ G KeyBoardTxFrame.status = UART_FRAME_TX_IT_END;# ?. I9 \, q \" ]4 E4 u# @
}3 S, J" ?% Y1 J3 ?1 R9 W+ L2 S
}
6 W7 Q. z7 J/ T: Y F PieCtrlRegs.PIEACK.all|=0x100; // Issue PIE ACK" d0 u& n( J! @2 `
}
0 x! Q9 s5 ~0 J% i' l2 k' z5 W* K( x5 {/ g2 U
(3)读取不到4个字节的数据4 ~ _$ k0 f0 M8 r7 x/ ^
' c, \4 j- [ ~# ivoid SCI1_RX_FIFO(UART_FRAME *pFrame)
g( B6 ~% \7 j% m{
. S. } @* l* i2 ~# B$ [' X Uint16 maxNum = 0;- A; Z6 c+ d& e! W
while(SciaRegs.SCIFFRX.bit.RXFFST && maxNum < 4)2 h$ N, H, X8 U. l* p
{6 k4 K3 R& X8 O8 u# P' {& b) q
pFrame->pdata[pFrame->index++] = SciaRegs.SCIRXBUF.all;
- e$ G5 m) B5 T0 Y5 o7 c2 a maxNum++;
- ]! I/ M! d1 h$ s0 r% Q" G3 C }
( h* b8 l" h; I, r}
" [8 p# P4 _/ i( ~4 | t
1 B* K8 ?2 q( I2 w+ b(4)在应用程序需要2ms周期查询接收数据是否结束, E) d! m- I8 L0 ]8 I7 |9 |: k
static void KeyboardJudgeRxFinish(void)
- b2 }6 j/ Q9 c, D( G" I% m{
# o1 j6 O# |' Y8 D) W9 [3 }* z //超时或数据长度大于40一帧接收完成0 v" @, O4 k& u. G5 F4 Q. s) j
if(((KeyBoardRxFrame.ticker <= 0)&&(KeyBoardRxFrame.index > 0)) || KeyBoardRxFrame.index >= 40)1 P7 R0 {+ L# y- I
{
- f* G" v) A9 @ SCI1_RX_FIFO(&KeyBoardRxFrame);) W- v+ B, }! {* |0 c* q' u3 C
KeyBoardRxFrame.len = KeyBoardRxFrame.index;* p9 T; D7 F5 P# C3 f
KeyBoardRxFrame.status = UART_FRAME_RX_END;//数据接收完成,应用可以取走数据3 E& A+ f0 j( B0 Y: E
}
& l4 ?( f& g) l1 x3 L# O if(KeyBoardRxFrame.ticker > 0)
- v2 L+ S4 V& X7 e2 m2 P2 r8 U) b {0 i5 { G; J* f; H( J8 U2 z0 J
KeyBoardRxFrame.ticker--;# ]+ C) O4 J" p( h8 r0 \
}0 D$ D0 x6 ]) Z7 a1 ~
}
+ t F4 U+ x8 I/ h4 N9 Y
- o2 h7 \( C" `! Y5 @(6)发送5 ^3 Z0 f t5 c J+ K; t# `! V" n
void Keyboardrs485TxFrame(void)( T F' _, |1 {
{' O# P* K/ p9 \6 Q* u9 Y$ T8 i2 y
SCI1SetTxMode();
% y' l' t- a* ` //如果当前帧正在发送,又重新请求发送一帧数据,则请求的数据丢弃
/ v8 C { Y: O2 T( F! M& J if(KeyBoardTxFrame.status == UART_FRAME_TX_ING)
2 u/ x1 H8 H' F {
* L! Z. O# m+ G( g; \. J return ;
) V# A' G, L9 g- @. e% K }( f0 Q5 k& q2 l) I5 E& W
//启动发送第一个字节后,产生中断,接着数据在中断中发送完成
# N* U r' T( c0 y) D' V+ v- @- \ KeyBoardTxFrame.index = 0;
. C* v1 v( {8 w# L4 f/ u SciaRegs.SCIFFTX.bit.TXFFINTCLR=1;//启动发送中断* d2 \* p: L. f
KeyBoardTxFrame.status = UART_FRAME_TX_ING;6 R$ o+ c; `8 C) e- c
}
. n4 [$ b. p. {7 o% O. x |
|