|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
本文介绍DSP高效接收和发送不定长度的数据,该方法减小cpu的中断次数,经过长时间检验,该方法安全可靠效率最大。我使用的是28034只有4级FIFO,在优化前中断深度设置为1,cpu频繁中断,导致正常程序受影响。经过改进,设置发送中断深度为0级,接收中断为4级,只有在数据发送完成和接收满4个字节中断。3 Y$ a- A: H G3 ^" z' K; }1 z6 c. P+ o
接收流程为:等待接收中断—》读取4个fifo数据—》超时检查—》读取fifo剩余数据。这样就会接收完整的一帧数据。2 }3 O" m! Q c+ ^% m$ }
发送流程:触发中断开始发送数据—》写入4个数据到发送fifo----》等到fifo为空中断–》写入下4个数据到fifo----》写入最后剩余数据。
( T4 N- f: S' Q, b. K% G9 {具体如下:
) A0 z# C+ I7 i; Y o G$ U* |(1)初始化配置
% r! A/ z' r/ L& F' Svoid scia_init()
* @4 I+ s- A7 f6 X5 X) y" y{
4 A" c8 E7 \. n& ^" ~* N' p" Q; \+ A // Note: clocks were turned on to the SCIA peripheral2 }: H+ o3 F# I
// in the InitSysCtrl() function
1 r% _! e9 ~6 O- t0 m SciaRegs.SCICCR.all =0x0007; // 1 stop bit, No loopback
' F. H+ G I9 ^, a& f$ f# D$ Z/ m // No parity,8 char bits,6 C/ s0 N+ [! `9 U* V* t
// async mode, idle-line protocol
" j, t: l# p( p0 ?9 u% S# h* N SciaRegs.SCICTL1.all =0x0003; // enable TX, RX, internal SCICLK,
& n' ?# @$ D+ ^ // Disable RX ERR, SLEEP, TXWAKE9 v# S2 _1 O+ y$ j& K; ?4 S" {
SciaRegs.SCICTL2.bit.TXINTENA = 1;//使能发送中断
2 O9 [& W$ b( I/ L4 w5 @7 B+ T# D; @. L, a( v
% K/ m8 U2 b# @9 r SciaRegs.SCICTL2.bit.RXBKINTENA = 1;//使能接收中断" H8 O7 l# L4 X7 K" R/ M
; D. N: s" R$ C! n7 ?1 @! J //BRR = (LSPCLK / (SCI Asynchronous Baud * 8)) - 1 ,LSPCLK=30M,
9 j6 z7 |3 D% L$ c" Q //BRR = 0x0020, baud=115200: o' k3 X! y3 |5 a8 k0 |9 F
//BRR = 0x0007, baud=460800
" `2 N* E+ g M //BRR = 0x0061, baud=38400% r( ]+ ]! E* |, ?2 K
SciaRegs.SCIHBAUD =0x0000;
' n/ Z2 r; `* O; j' | SciaRegs.SCILBAUD =0x0020;//; \0 C1 B1 q0 c+ `1 F3 s/ k' v
SciaRegs.SCICCR.bit.LOOPBKENA =0; // Enable loop back
* N; I+ \4 W' @* o' M' o SciaRegs.SCICCR.bit.STOPBITS = 2; /// w+ c& t j+ J/ m$ R# I5 i( ]$ \
SciaRegs.SCIFFTX.all=0xC020;//设置发送中断为0级
. W$ p3 }/ {3 E' A SciaRegs.SCIFFRX.all=0x0024;//设置接收中断为4级
& x2 x7 K) a, Z, c! \# V SciaRegs.SCIFFCT.all=0x0;2 U5 m$ d' Q( Z4 {% J
SciaRegs.SCIPRI.bit.FREE = 0;//仿真模式下是否自由运行
9 ^' |; d& k3 a* R9 P/ e SciaRegs.SCICTL1.all =0x0023; // Relinquish SCI from Reset
6 Q" E7 W2 U/ S& ~ SciaRegs.SCIFFTX.bit.TXFIFOXRESET=1; //发送FIFO复位
2 Z4 y$ G0 O% U" o$ \ SciaRegs.SCIFFRX.bit.RXFIFORESET=1; //接收FIFO复位
* ^. a5 I, P# J# P. c) p3 y& O}2 z) k2 k! R. v1 G) {6 b
2 D2 p0 ~- a; m% c( i: |' Z(2)接收中断和发送中断
' q+ k, L0 w& K+ {6 y4 w! f
5 y! C+ b: _ a: Z$ Xinterrupt void SCI1_RXD_isr(void)
& k$ R7 D. Q6 i{: F8 O! Q/ _: ]; G) j2 W3 E: ^
UINT16 RxData;
9 g) ~# m0 x' |; P$ |3 q! j //RxData = SciaRegs.SCIRXBUF.all;. j* J0 I+ D- i
//上一个数据帧应用层未取走,数据丢弃
1 A9 \. m z: s/ k0 L& i- y if ((KeyBoardRxFrame.status == UART_FRAME_RX_END) || (KeyBoardRxFrame.index >= 40))/ ?) U/ y9 C# R
{
. w6 H1 a q8 F* A l& ? KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;2 F$ V9 N3 D+ X u$ p3 k8 ^
KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;0 l" b, H% X( x& j* ~* B2 k+ ^) A
KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;" B7 M9 J3 F$ s# W% q- ~' g# [
KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;
8 K2 n; W; }, Q3 P0 v& j }else
`1 O# w" d! { j+ z( o {# b9 \0 {: @, ~
KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;
4 `" K& ^8 f8 m0 x4 I2 L( c: Z KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;7 a" K+ U; t4 J" G' h# C$ c
KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;! K+ ?; }/ d* _7 A8 b0 S4 p5 v7 |
KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;8 a& u+ o' j, i4 q, }
KeyBoardRxFrame.ticker = KeyBoardRxFrame.spacetime;
# b4 g0 O- T+ h2 `0 @ }
4 B) {/ Q7 \) `. J% J) Y2 b- h 1 W8 Y( C3 g( w( N1 A
SciaRegs.SCIFFRX.bit.RXFFOVRCLR=1; // Clear OveRFlow flag
: u3 h* O5 J+ v# Q2 l+ k- ] SciaRegs.SCIFFRX.bit.RXFFINTCLR=1; // Clear Interrupt flag! Q. w+ n4 U: A3 D" ~5 o* [
! G- N3 S! r# r9 B PieCtrlRegs.PIEACK.all|=0x100; // Issue PIE ack
9 n3 d. R8 C5 d: O. {% p" k: r1 l}
* r. w: E2 o* g7 Q) Y5 ~interrupt void SCI1_TXD_isr(void)
- t4 i) @1 Z2 M& K! F9 q8 j. K{
. f C$ d( u, I3 d Uint16 i;; I- g* Z) S1 |3 ] {3 n
Uint16 len;0 J% I7 U4 H, `! m: ?- f4 ^
// 发送一帧数据没有完成
* y* E4 V. D Y- C! A- O if(KeyBoardTxFrame.index + 4 < KeyBoardTxFrame.len) 4 M6 Z! b ~9 J |
{# c- D5 M4 E; X0 h& P: n
SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];7 o$ i+ A" b% J) V& @
SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];) L& b! _' v0 I2 D: r9 I! p
SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];
* X, r- b, o: q W( ]" z# v3 N SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];: o* t B s: p
A- J ~, |& | ~2 |+ ]) Y
SciaRegs.SCIFFTX.bit.TXFFINTCLR=1; // Clear SCI Interrupt flag清除后产生中断
2 Z( k9 s) K# y/ w1 n }
* l- M7 ^1 I/ F3 h+ ?: z! p else
# q5 K) |3 b. A) k! L: J0 W, @ {
. f: S; l# \2 B* I5 u: Y6 { //发送剩下的数据
: Z- {7 ^. T. z6 R( t: D) C4 ? len = KeyBoardTxFrame.len - KeyBoardTxFrame.index;3 W: ]0 y4 k$ J0 B" M
for(i = 0; (len <= 40) && (i < len); i++)
6 h/ P* w: i- [ {
! x4 K1 h0 p* x/ F! [1 M o SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];9 J2 {" m" T l* E7 }
}
+ D: H5 x& V z0 d' d* I ! O2 G! K; u; u* u2 L1 Y. c
//一帧数据结束0 r$ x. B& ^3 e! W1 f% K! P
if(KeyBoardTxFrame.len), u! V0 m" i' g" v' j1 }
{( `- |6 O9 T7 w7 ?: q! A5 _8 U" v
KeyBoardTxFrame.status = UART_FRAME_TX_IT_END;
: _9 f' m% k2 d/ R; G }
4 m' {7 R: e' i7 m1 y }
1 k" Y% T) l' p/ u PieCtrlRegs.PIEACK.all|=0x100; // Issue PIE ACK# R( `+ Z/ Y4 Y! z% B2 V0 G
}
0 v" Z3 p+ ` m$ N
& p0 y; H( p2 V7 p5 d/ e(3)读取不到4个字节的数据
" V! N* k f# _# o1 q- P7 N( e$ Y* @/ c4 L3 D( ?" J
void SCI1_RX_FIFO(UART_FRAME *pFrame)
`' p' [( `& w* w; S{2 l& z2 N1 X. h6 p
Uint16 maxNum = 0;9 K8 n- k! B3 S5 V
while(SciaRegs.SCIFFRX.bit.RXFFST && maxNum < 4)
# M q3 n& {/ P, C/ V {" I6 d" a0 _! E1 q6 H- q4 w9 n
pFrame->pdata[pFrame->index++] = SciaRegs.SCIRXBUF.all;
( D8 L. j. B. H. K6 j' S% i3 ? maxNum++;8 T- `+ _/ m' s) A( O
}
8 B0 F! ?( w, ^( c1 }' d" g}4 S( m/ S+ b) c0 s8 E% x1 O
. F* Q- u9 }' e6 o+ s" ](4)在应用程序需要2ms周期查询接收数据是否结束. @5 H+ d- n5 v' h, ^
static void KeyboardJudgeRxFinish(void)
# f4 Z- K! w+ k* P9 c# r, ?) f{
4 v8 G: [2 P5 M //超时或数据长度大于40一帧接收完成4 w3 M2 f: n" C
if(((KeyBoardRxFrame.ticker <= 0)&&(KeyBoardRxFrame.index > 0)) || KeyBoardRxFrame.index >= 40)
* b3 F/ L8 R8 j/ E3 t {
B. x# ?+ e3 Q. T4 G SCI1_RX_FIFO(&KeyBoardRxFrame);4 O3 W8 \' V& O1 A. q/ A
KeyBoardRxFrame.len = KeyBoardRxFrame.index;
9 V1 h. X+ X+ ~3 v2 Y% V9 l KeyBoardRxFrame.status = UART_FRAME_RX_END;//数据接收完成,应用可以取走数据
# J; s! D+ a* L+ H1 t }
; O) |# V* ~* w1 `% f8 a9 g; O if(KeyBoardRxFrame.ticker > 0)' d' w: Q7 N& ~& _! X
{ f0 n A: c8 I' C8 o
KeyBoardRxFrame.ticker--;
" j2 |# g- ~& ?' F }: e& H! z ^* n
}
) m7 F5 u5 Z M0 \* T
0 x7 W W2 V4 B5 L4 ?# P(6)发送! ]" i. J& x# b
void Keyboardrs485TxFrame(void)
& g4 l$ d% H4 ?- O; p{
9 E( _( o; Q) K0 V" T& j SCI1SetTxMode();- T& [ L0 I" E0 i2 w. {; E
//如果当前帧正在发送,又重新请求发送一帧数据,则请求的数据丢弃
* `- G" w- S3 Z2 N if(KeyBoardTxFrame.status == UART_FRAME_TX_ING)& l, n9 x' U2 Y: o
{
V! ^( y: _) f% N2 c$ t8 P; [ return ;+ C. L; X- M5 {3 h' j! D" f6 ~
}
I$ A( o; L, g; V7 |/ {2 } //启动发送第一个字节后,产生中断,接着数据在中断中发送完成
1 Y8 \2 T+ o, ?- ` KeyBoardTxFrame.index = 0;
; Z. [) V3 y+ h3 \' e$ L9 ~8 ~; L SciaRegs.SCIFFTX.bit.TXFFINTCLR=1;//启动发送中断
+ w. a9 S6 ? ^/ I: i- t+ ] KeyBoardTxFrame.status = UART_FRAME_TX_ING;) U2 B7 K+ g# Z. e$ M4 U1 d, ]
}
' E% G7 i5 q9 z* z |
|