|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
本文介绍DSP高效接收和发送不定长度的数据,该方法减小cpu的中断次数,经过长时间检验,该方法安全可靠效率最大。我使用的是28034只有4级FIFO,在优化前中断深度设置为1,cpu频繁中断,导致正常程序受影响。经过改进,设置发送中断深度为0级,接收中断为4级,只有在数据发送完成和接收满4个字节中断。
/ v( J V$ ~+ f7 ?3 l5 b8 l接收流程为:等待接收中断—》读取4个fifo数据—》超时检查—》读取fifo剩余数据。这样就会接收完整的一帧数据。
9 ?* V; e- a9 i- o发送流程:触发中断开始发送数据—》写入4个数据到发送fifo----》等到fifo为空中断–》写入下4个数据到fifo----》写入最后剩余数据。
) J1 c/ w, z' _具体如下:
4 a% Z* D# w$ n(1)初始化配置9 s) L" Q2 `. ^; d: g0 A3 O
void scia_init()* b- S/ @1 s2 O5 }: }# y9 j! s
{
% D4 q" y- K A0 w, c- L) z // Note: clocks were turned on to the SCIA peripheral8 e: Q2 o0 q. Y% K! Z5 x- b
// in the InitSysCtrl() function5 ^# w' u- E: y7 s3 D' P
SciaRegs.SCICCR.all =0x0007; // 1 stop bit, No loopback( c8 j# l+ N* ~( X
// No parity,8 char bits,* K8 [6 @1 m1 @8 L
// async mode, idle-line protocol
2 U8 R/ ?% y- v9 h3 g, E- u SciaRegs.SCICTL1.all =0x0003; // enable TX, RX, internal SCICLK,+ `8 r& j+ ?$ L' r+ s+ n6 f2 k
// Disable RX ERR, SLEEP, TXWAKE$ t+ l/ e ], z: ?4 e- s# P
SciaRegs.SCICTL2.bit.TXINTENA = 1;//使能发送中断7 V F T) ^8 D: i4 H9 x. i
$ T3 `$ e" |! u9 I0 G' V5 s9 U
! g* F( X: j* f
SciaRegs.SCICTL2.bit.RXBKINTENA = 1;//使能接收中断) R( P4 h+ X% h) M
0 l; D; Q0 d" W( l' r
//BRR = (LSPCLK / (SCI Asynchronous Baud * 8)) - 1 ,LSPCLK=30M, p: t5 o8 H5 z/ ~* C7 ?0 s( l
//BRR = 0x0020, baud=115200) N1 h3 G/ m* ]& H
//BRR = 0x0007, baud=460800
! ^- ]' d& D) d3 M( B0 k //BRR = 0x0061, baud=38400
0 c+ e N" s5 g, s Q& K3 A& A SciaRegs.SCIHBAUD =0x0000;* N& Y5 H4 _& v4 n7 i3 [6 S1 G0 Y$ k3 S' w/ @
SciaRegs.SCILBAUD =0x0020;/// @) |# g5 @/ E5 e8 D
SciaRegs.SCICCR.bit.LOOPBKENA =0; // Enable loop back
0 r6 ~6 [$ U0 v: q SciaRegs.SCICCR.bit.STOPBITS = 2; //
( Q2 u6 h# [9 c V* s# e1 S SciaRegs.SCIFFTX.all=0xC020;//设置发送中断为0级1 O- |9 b3 L5 \6 |( \! @) Q/ c, j
SciaRegs.SCIFFRX.all=0x0024;//设置接收中断为4级, I- P4 g4 B5 R. d( i. L- V
SciaRegs.SCIFFCT.all=0x0;
. i( W& w+ R7 ]8 P. S8 V2 ~4 F) \ SciaRegs.SCIPRI.bit.FREE = 0;//仿真模式下是否自由运行
3 E" z( B2 m- b% P! v2 R8 w9 m M SciaRegs.SCICTL1.all =0x0023; // Relinquish SCI from Reset$ \. r' |. M8 `) J. W
SciaRegs.SCIFFTX.bit.TXFIFOXRESET=1; //发送FIFO复位
/ W* v0 F6 R. r4 W6 } SciaRegs.SCIFFRX.bit.RXFIFORESET=1; //接收FIFO复位 # A' H3 d& Y- y8 k* Q
}$ @& N8 O" z2 b {8 k. |
+ M% U, s; h8 u1 ? v! ^1 Y4 z(2)接收中断和发送中断
1 _. a: A7 N; P9 s7 m# q: P% U
6 _4 C6 r* J. D9 n; w' d% }* Zinterrupt void SCI1_RXD_isr(void)
' t% U c! R5 |# Q. r{0 C* }8 F5 z5 Q+ S! y2 O3 B2 E
UINT16 RxData;# P8 }+ H1 A5 v, B
//RxData = SciaRegs.SCIRXBUF.all;2 v8 G/ `# t5 K! F+ X! X, L% d: O
//上一个数据帧应用层未取走,数据丢弃2 V# C# q& q, N
if ((KeyBoardRxFrame.status == UART_FRAME_RX_END) || (KeyBoardRxFrame.index >= 40))* s) d8 w/ U8 X, ?) |+ H9 K& ~
{
* r0 ^5 L J& P+ _# x KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;
( o6 Z) \/ {1 z% } KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;# ]0 @( d5 b! F
KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;
5 p! W& s1 o* ~& Y8 @# `' t1 {/ z$ A KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;
% r$ I! i) z+ h }else9 L9 g- }; ~, q8 J; \5 M4 k' x* \: A
{9 \( u9 S1 C6 J: ` x4 B( Z
KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;
1 l- H6 d' j" B KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;' Z- K: e9 X' p2 @: q$ Z8 |
KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;
: U/ y( N1 e5 i% v! E; G! W KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;0 j/ k9 U, O3 B' R0 B$ H
KeyBoardRxFrame.ticker = KeyBoardRxFrame.spacetime;
* i# \2 q" R2 r9 Y! N0 z } K( o$ Y9 w6 s
) ?- x) b+ C5 w& X0 \8 k7 p
SciaRegs.SCIFFRX.bit.RXFFOVRCLR=1; // Clear OveRFlow flag. s2 N- Q3 S, t; g2 Y+ X2 g
SciaRegs.SCIFFRX.bit.RXFFINTCLR=1; // Clear Interrupt flag7 X. n1 D, F. Z5 m" ]8 x
/ o( c# S: U7 x. z; C
PieCtrlRegs.PIEACK.all|=0x100; // Issue PIE ack5 Y: V# C) S( c) N5 A3 K" ^
}+ R6 N7 v; r( ^; h6 ^4 i
interrupt void SCI1_TXD_isr(void)4 C, l. s1 Q- ]# U. A% }
{+ Q/ b8 @' t: t0 [0 `' m
Uint16 i;6 d# }" T! \! u
Uint16 len;
# C# a7 B: @/ l0 z+ j3 [+ n // 发送一帧数据没有完成
0 M* N8 Z# {" O9 b1 Y8 {, |+ |0 E if(KeyBoardTxFrame.index + 4 < KeyBoardTxFrame.len)
% l( l2 t; Z- ?, B/ c! O- @7 ^7 ` {! f" \5 j! y8 N4 l9 G3 H7 T( D- M
SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];
' Y) s c- W0 [0 J5 H SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];; P/ a8 I) g ^: r, d! }. m
SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++]; r3 ?- S: c+ p1 ^- H* q
SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];. @ O7 v2 T4 c* T
# L# E- O# j$ o: f7 E
SciaRegs.SCIFFTX.bit.TXFFINTCLR=1; // Clear SCI Interrupt flag清除后产生中断; `3 x4 m- `: f4 `; ]4 ?
}% |9 Z+ h! i- q
else
8 v, u* o- C8 p7 T( I$ P {; S2 i! }& r2 x
//发送剩下的数据+ }) X- V4 O5 m6 a
len = KeyBoardTxFrame.len - KeyBoardTxFrame.index;# H! |. ?( L( G& ]8 k
for(i = 0; (len <= 40) && (i < len); i++)
1 k' {# f, [1 {7 |) Z+ P0 Z) L {) n9 j5 U) Z: Q/ Q
SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];
4 `; M% M4 v, A9 r* U }, u! C" L5 E* g
& a; c2 M9 J6 |6 X* w
//一帧数据结束- @4 U' ]- O0 K. F' Q# a% R- d
if(KeyBoardTxFrame.len)
+ ^6 T; Q- r" `% e7 ?% X' o! k {
8 C3 w9 }5 E# B: L6 _$ y+ w KeyBoardTxFrame.status = UART_FRAME_TX_IT_END;
6 ~9 V# Z0 ?0 ^. U }
$ U7 g; H2 \: a: O6 u6 F) g+ S: w }* b* m6 A7 }9 O: I; Q
PieCtrlRegs.PIEACK.all|=0x100; // Issue PIE ACK& B) Y8 N% G# C; z# L2 B# J" F
}0 t2 i4 G+ g4 a6 R
: x% U1 \- _$ v3 f) I! H* g2 ]" T7 }$ m(3)读取不到4个字节的数据 |" g, q2 @4 ~! g0 x
C: w0 w* I5 Z& `9 l4 Q6 Q) o }void SCI1_RX_FIFO(UART_FRAME *pFrame)0 W' g S4 {; t
{9 ?$ N% i) l1 g8 C( |% C
Uint16 maxNum = 0;% u8 ]" [2 w% U/ T1 g/ J! U4 `
while(SciaRegs.SCIFFRX.bit.RXFFST && maxNum < 4)8 I! n' n8 {9 i. x+ {4 O
{; b N. p6 Z* _1 z( c
pFrame->pdata[pFrame->index++] = SciaRegs.SCIRXBUF.all;) l4 C. w- N1 n: ]2 N8 j
maxNum++;5 r7 @5 [' c" g$ d+ Q4 x" W, J: l& G+ O
}; A! X' ~: a9 C( F' b$ w
}9 t. {) X/ U* y3 k
; t" k" G4 l; S/ [7 d
(4)在应用程序需要2ms周期查询接收数据是否结束& k3 x; r1 U* P8 v$ r
static void KeyboardJudgeRxFinish(void)7 f9 {$ P* C2 p. |5 R
{
) F% C* a* ]3 h* q //超时或数据长度大于40一帧接收完成
* P, v' @7 _; u' J# ~$ U/ z- S if(((KeyBoardRxFrame.ticker <= 0)&&(KeyBoardRxFrame.index > 0)) || KeyBoardRxFrame.index >= 40)
+ x8 K4 _/ Q% Z+ h4 y, L$ n5 w9 { {
0 d& q3 o7 i5 h, _ D5 f; ?6 q SCI1_RX_FIFO(&KeyBoardRxFrame);
4 E( d6 {) o& w L1 \, | KeyBoardRxFrame.len = KeyBoardRxFrame.index;
( I* K7 m' q6 b" {! ~ ] KeyBoardRxFrame.status = UART_FRAME_RX_END;//数据接收完成,应用可以取走数据4 b9 W$ C4 z0 u) B
}
% I4 F: B* w& l6 \, q- h; V0 J9 R if(KeyBoardRxFrame.ticker > 0)
) g5 ]* k! X* K {; `5 K% s5 K/ C7 A9 P4 `: s
KeyBoardRxFrame.ticker--;
8 k! ^- j: z! z/ k( y }
0 O8 v( j `3 Y: y1 n. L% I}6 G( k5 W0 _8 y0 i% y8 o/ o
5 t+ R( D+ b: p3 t( u(6)发送) i7 t N+ t n3 |$ ^( B, L- m7 I
void Keyboardrs485TxFrame(void). Y1 O, K, p* \% \$ z( {
{
7 \7 P" ] S( K% u' @+ U/ {0 J6 N SCI1SetTxMode();
5 @. ~+ I$ w1 U2 z //如果当前帧正在发送,又重新请求发送一帧数据,则请求的数据丢弃
( N) ~8 Z1 W1 b$ g+ U: } if(KeyBoardTxFrame.status == UART_FRAME_TX_ING)/ j, U9 ^6 ~0 Q( N
{2 }6 z, |* k Y& M4 Q6 e7 c
return ;
$ c4 T) ]+ F* b% e }
5 H _! V7 V4 r5 @9 E //启动发送第一个字节后,产生中断,接着数据在中断中发送完成% o1 q2 t1 v' a. u# O% x
KeyBoardTxFrame.index = 0;
* k4 M4 c" g+ F, M7 x SciaRegs.SCIFFTX.bit.TXFFINTCLR=1;//启动发送中断
2 w& S5 b: n1 k p3 |* r. q) b5 ?1 ~" }1 H KeyBoardTxFrame.status = UART_FRAME_TX_ING;) B/ D, N: i7 U2 f
}/ q- T, ]: w& p8 B6 j- F r
|
|