|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
本文介绍DSP高效接收和发送不定长度的数据,该方法减小cpu的中断次数,经过长时间检验,该方法安全可靠效率最大。我使用的是28034只有4级FIFO,在优化前中断深度设置为1,cpu频繁中断,导致正常程序受影响。经过改进,设置发送中断深度为0级,接收中断为4级,只有在数据发送完成和接收满4个字节中断。
& y/ p+ P/ r; ?1 s接收流程为:等待接收中断—》读取4个fifo数据—》超时检查—》读取fifo剩余数据。这样就会接收完整的一帧数据。0 a& }- w( L7 }+ B
发送流程:触发中断开始发送数据—》写入4个数据到发送fifo----》等到fifo为空中断–》写入下4个数据到fifo----》写入最后剩余数据。' ]3 {: z9 j( `9 m
具体如下:6 Q6 A' W2 d Z7 a" ~2 R5 P9 b
(1)初始化配置! D# U( e) Z( z( r
void scia_init()! c% y: Y6 K$ C: g+ M1 \
{9 w0 p- Q1 ~: Q0 C7 H
// Note: clocks were turned on to the SCIA peripheral
, _3 j0 N0 A) Q- u1 e // in the InitSysCtrl() function
9 K) E4 `% C' U6 j% o SciaRegs.SCICCR.all =0x0007; // 1 stop bit, No loopback
+ M ~& E, b }7 F: }+ Q // No parity,8 char bits,- w0 x, Y4 E0 g8 u
// async mode, idle-line protocol1 X# p: w# w+ t' I: p- m* W" q6 r, @
SciaRegs.SCICTL1.all =0x0003; // enable TX, RX, internal SCICLK,7 l! \6 I4 {8 O% E6 { m8 o
// Disable RX ERR, SLEEP, TXWAKE, C5 R" N1 e& m* e0 @
SciaRegs.SCICTL2.bit.TXINTENA = 1;//使能发送中断) X4 ~( l d! }: ]* o
/ ^" [% k8 A6 l5 [
& V$ e# T7 O ]% h5 A+ u SciaRegs.SCICTL2.bit.RXBKINTENA = 1;//使能接收中断$ t/ N) N; F& ~' m
% [+ e$ g$ W* s
//BRR = (LSPCLK / (SCI Asynchronous Baud * 8)) - 1 ,LSPCLK=30M,* {% W$ f. Z9 j( u0 ~ L! g
//BRR = 0x0020, baud=115200
/ _4 ~) k2 h+ D3 G+ e0 G- h( A& E //BRR = 0x0007, baud=460800
+ Z3 k- \, l, s0 t2 F5 r. J( ` //BRR = 0x0061, baud=38400* n3 L& a8 F1 S
SciaRegs.SCIHBAUD =0x0000;$ k$ H& b1 _- s0 m4 [
SciaRegs.SCILBAUD =0x0020;//3 w" m' I% t8 P1 _& P
SciaRegs.SCICCR.bit.LOOPBKENA =0; // Enable loop back/ Z) \/ V# V9 I9 V7 x# e
SciaRegs.SCICCR.bit.STOPBITS = 2; //: d, H0 }: z) P, P1 m: M) a
SciaRegs.SCIFFTX.all=0xC020;//设置发送中断为0级+ s$ O5 q. B1 f% L( d$ K
SciaRegs.SCIFFRX.all=0x0024;//设置接收中断为4级8 u( _1 Q8 E6 ]2 i2 `
SciaRegs.SCIFFCT.all=0x0;' \5 L; z. Y6 K0 e
SciaRegs.SCIPRI.bit.FREE = 0;//仿真模式下是否自由运行/ A1 J+ }& p# ~4 X% w8 z# ^
SciaRegs.SCICTL1.all =0x0023; // Relinquish SCI from Reset- Y, T3 w- Y4 G8 {
SciaRegs.SCIFFTX.bit.TXFIFOXRESET=1; //发送FIFO复位
" r" B0 h/ R7 ^" ~( r/ V SciaRegs.SCIFFRX.bit.RXFIFORESET=1; //接收FIFO复位
5 O* u: M: Y5 k' |0 I6 H, E}
# S' L5 [7 \9 j) f5 k; A" O! Y' y( z E
(2)接收中断和发送中断
$ w% k5 n' R M$ m/ E0 U/ @1 l+ Y+ z- F+ ?( i n3 B
interrupt void SCI1_RXD_isr(void)
$ x( L' A5 s& I: ^% H{
|+ F" t4 S& G5 b- T UINT16 RxData;
6 W4 c7 f" ^$ }4 j: w& r: _: B1 ^ //RxData = SciaRegs.SCIRXBUF.all;# C4 z: K. Y3 V( E
//上一个数据帧应用层未取走,数据丢弃, O4 X6 }, Z3 a/ D
if ((KeyBoardRxFrame.status == UART_FRAME_RX_END) || (KeyBoardRxFrame.index >= 40))
" x+ z1 R1 R3 ` K- a1 l {
4 H& q6 {& y9 r8 r7 Y KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;& m" N2 N" x. C8 K2 l+ v9 h
KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;
/ i2 Y% e6 m" Y6 Y# E! o* G KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;# a1 \% }( ?2 j+ w1 }! h# k
KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;; N' Q4 j' L; ^& e
}else
2 e T$ a" Y* @5 x {
1 z4 o4 u% p, n' q& o KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;
' g& _# W3 I. u0 @8 m1 j KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;0 _$ L' q7 v6 J9 K3 A+ F3 A
KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;: |* l& U: r/ I z! M! g) {
KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;
) l7 ^/ _! I; ^# O# P2 x KeyBoardRxFrame.ticker = KeyBoardRxFrame.spacetime;
0 B; Z6 ~' X k1 x2 a n2 [% H8 | }
; U/ J9 x) B/ S; @: o: H# c 9 g5 ?1 I, T* B8 @) n( J `
SciaRegs.SCIFFRX.bit.RXFFOVRCLR=1; // Clear OveRFlow flag
1 {8 t" Z9 a& r8 H. X6 ` SciaRegs.SCIFFRX.bit.RXFFINTCLR=1; // Clear Interrupt flag& Z) G% t, Q/ T7 G2 M$ y5 Y8 t
, ?- D8 }. S6 L$ o" j/ O PieCtrlRegs.PIEACK.all|=0x100; // Issue PIE ack0 p, A0 E/ G3 _4 N
}8 U* P' ^; i' [% S# N+ y% n
interrupt void SCI1_TXD_isr(void)
; w/ E! g+ S8 D: _$ l1 `9 Z" G+ a8 h{
b i6 i5 Z- {1 d4 X4 S1 ]+ C1 K Uint16 i;/ ] x6 w a% \. T7 H! t) m$ P: b( y
Uint16 len;
$ E- m, ?7 L0 o) ]! c // 发送一帧数据没有完成, `- L2 r" Z0 F( G/ F0 } D
if(KeyBoardTxFrame.index + 4 < KeyBoardTxFrame.len)
! m5 ]& z4 J9 ]* R, I {
4 d' Q, n9 Z: H3 D, j, _ SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];
6 i3 e) V' \1 W SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];0 i% s7 n. Q+ i7 M: X
SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];+ {3 y5 j8 X% O+ s+ o
SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];* D9 B( R$ e5 [7 C, ?) M4 C* W6 j9 i/ M
7 A' _' X7 s' p
SciaRegs.SCIFFTX.bit.TXFFINTCLR=1; // Clear SCI Interrupt flag清除后产生中断
3 y( }* o/ n5 t* P+ h) ? }/ w, @$ z' [# C
else
4 X. |! d# z0 C- x6 f u {
5 T' t, ]5 H) D8 Z$ b1 T //发送剩下的数据
6 m$ C0 N8 U/ j x' H len = KeyBoardTxFrame.len - KeyBoardTxFrame.index;; e9 e" ?: k8 p8 H- g+ n
for(i = 0; (len <= 40) && (i < len); i++)
n6 N- \! P/ L% d$ e8 ~ {
3 w( P. A9 f5 ~: ? SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];! Q, E+ d/ t0 w, ?' g
}
5 T6 t% G" }% G9 S$ V' | " I( r/ T5 b7 q
//一帧数据结束% ?$ x- s: C1 K1 [& P- }2 |! X
if(KeyBoardTxFrame.len)% A6 p$ x/ K3 _: M1 n4 G& @
{
/ d& L* B$ C/ P! R; C x' \$ \ KeyBoardTxFrame.status = UART_FRAME_TX_IT_END;
& A9 s; {- d" y( a4 u- [* r% X8 H4 \ }
5 J5 O5 g A7 L5 D9 P1 N- L7 n% J }
s9 [ ~, ]6 m$ W) Z8 { PieCtrlRegs.PIEACK.all|=0x100; // Issue PIE ACK
- B6 V5 C$ P( W, ]# _$ c1 U}9 \! |# ]; U9 C' s% w D
- [- B0 `# D+ J0 H. { Y/ K
(3)读取不到4个字节的数据& T2 U" s) c) ~, `1 [4 ?5 }
% g. u* }- m H3 D" s9 n& N5 {! S
void SCI1_RX_FIFO(UART_FRAME *pFrame)* o) l5 b& W( Q8 }* W1 E; a8 C0 ~
{) |, \7 e+ H. T: j# k! ~5 X: t2 \- A
Uint16 maxNum = 0;
+ m( S0 N; |5 D+ H' p _& ^ while(SciaRegs.SCIFFRX.bit.RXFFST && maxNum < 4)% y, M- u A1 p
{3 A1 J# Q% u y7 z1 F5 W6 `5 B0 \1 r/ w
pFrame->pdata[pFrame->index++] = SciaRegs.SCIRXBUF.all;0 H3 ^7 C5 {( n& ^# b3 \* A
maxNum++;
, f# I0 p( e' R4 `( \ }
+ R9 i& X' \& R}" L& a3 p& q- t3 {# A7 [
+ ~0 i" _1 x* }2 O( ? h9 @/ h3 c
(4)在应用程序需要2ms周期查询接收数据是否结束
0 l5 r- j2 @6 Dstatic void KeyboardJudgeRxFinish(void)
. m0 ^) l1 ?6 S# R- ?) U: m{
# L4 B4 a: ?# V1 ]( T5 V //超时或数据长度大于40一帧接收完成9 I! P/ i5 R/ o; W
if(((KeyBoardRxFrame.ticker <= 0)&&(KeyBoardRxFrame.index > 0)) || KeyBoardRxFrame.index >= 40)" [6 O! K* m5 ^! n
{
8 S+ E9 Y8 Z! Z& H SCI1_RX_FIFO(&KeyBoardRxFrame);
4 R& I, l7 @1 t) m H KeyBoardRxFrame.len = KeyBoardRxFrame.index;
: Z" S, G+ G3 Z5 k% ^% R KeyBoardRxFrame.status = UART_FRAME_RX_END;//数据接收完成,应用可以取走数据
0 m6 I/ _# G5 C; y$ p }0 d5 C7 m5 j# A3 Y/ T
if(KeyBoardRxFrame.ticker > 0)
) h2 i9 V7 G% s' F0 ~8 }2 S3 F" H3 r {: a( O' i* q! f: U
KeyBoardRxFrame.ticker--;- v; |# v/ ~% l6 R5 |; W3 K9 e+ a
}5 x+ f o* z9 f1 U7 L& g
}
( m% ^) Q4 W5 U0 x* T# m
( j0 t: ]% i' K: G(6)发送3 h" F& h: d+ L- S9 B
void Keyboardrs485TxFrame(void)
, u% g4 w7 n4 B' m{
9 p& w9 U1 k! n* A SCI1SetTxMode();
4 H& m- K: q" h //如果当前帧正在发送,又重新请求发送一帧数据,则请求的数据丢弃* m6 m0 D; K$ }; r0 G4 ?
if(KeyBoardTxFrame.status == UART_FRAME_TX_ING)# j. c8 s, K( Z4 V
{
& |- i2 J" D+ I% {5 S5 n return ;) o/ n s/ U z3 u
}
$ P6 {' N# m& l. o# g8 A9 l% [, ]& V //启动发送第一个字节后,产生中断,接着数据在中断中发送完成+ E) e4 \6 [. N+ `0 x* i: w
KeyBoardTxFrame.index = 0;
$ l! a; e+ ]2 G9 S SciaRegs.SCIFFTX.bit.TXFFINTCLR=1;//启动发送中断& @1 B# E' W3 q8 D1 R+ k
KeyBoardTxFrame.status = UART_FRAME_TX_ING;+ s; R* X7 }! j5 r
}
z$ i$ A. g) G3 k) e |
|