|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
本文介绍DSP高效接收和发送不定长度的数据,该方法减小cpu的中断次数,经过长时间检验,该方法安全可靠效率最大。我使用的是28034只有4级FIFO,在优化前中断深度设置为1,cpu频繁中断,导致正常程序受影响。经过改进,设置发送中断深度为0级,接收中断为4级,只有在数据发送完成和接收满4个字节中断。. l! j; P. l9 W9 j
接收流程为:等待接收中断—》读取4个fifo数据—》超时检查—》读取fifo剩余数据。这样就会接收完整的一帧数据。, F4 |) H" a4 k) @3 I9 _
发送流程:触发中断开始发送数据—》写入4个数据到发送fifo----》等到fifo为空中断–》写入下4个数据到fifo----》写入最后剩余数据。
8 N* l9 c0 ?# H$ D9 w具体如下:
8 a; S" ?7 ?& M# m L(1)初始化配置
0 C+ [1 N( O8 wvoid scia_init()7 Q& _9 N% l/ [0 _2 H S3 Y. e
{) r! f( ]5 J J4 \! E
// Note: clocks were turned on to the SCIA peripheral$ d) E- F' I% A K+ B# G
// in the InitSysCtrl() function
7 M3 r+ M+ G( J/ u: f4 Q$ h( {" A0 p SciaRegs.SCICCR.all =0x0007; // 1 stop bit, No loopback
3 z0 b! e b" U) O, N8 p) A3 F* V // No parity,8 char bits,
9 q6 e% `: R* T5 I K8 O6 h0 C // async mode, idle-line protocol
4 I, O {" _' F- F2 ^ SciaRegs.SCICTL1.all =0x0003; // enable TX, RX, internal SCICLK,
3 u E8 ]- z9 O3 ^ // Disable RX ERR, SLEEP, TXWAKE
A% v- Z! t5 J$ G6 h; q: m SciaRegs.SCICTL2.bit.TXINTENA = 1;//使能发送中断, M" Z1 Y) p, i" O" A7 Z
9 p# \; Z! _ Y) }( O
t9 R! a+ D. D% p SciaRegs.SCICTL2.bit.RXBKINTENA = 1;//使能接收中断
$ z1 ~, @2 u a. T Q/ ^" e* v3 g) [
//BRR = (LSPCLK / (SCI Asynchronous Baud * 8)) - 1 ,LSPCLK=30M,, U9 |! _9 Z4 X* i9 R. n& x, v3 Q
//BRR = 0x0020, baud=115200
, N. K9 ]$ p- |8 V' G( c //BRR = 0x0007, baud=460800
5 R$ _. K ?' z: L7 C //BRR = 0x0061, baud=38400
9 D. ?; m3 i. `3 \ SciaRegs.SCIHBAUD =0x0000;- i" j, i* y- ]6 f4 D- |
SciaRegs.SCILBAUD =0x0020;//+ ^& G' z3 }( h3 }6 R2 N7 M
SciaRegs.SCICCR.bit.LOOPBKENA =0; // Enable loop back
d) ~$ E& |; y$ u SciaRegs.SCICCR.bit.STOPBITS = 2; //
2 |( q; G# H- L4 c( {8 F3 g SciaRegs.SCIFFTX.all=0xC020;//设置发送中断为0级
* ^6 s j% ]' d. K% p) X- y SciaRegs.SCIFFRX.all=0x0024;//设置接收中断为4级
0 g1 X1 D) f: d* a SciaRegs.SCIFFCT.all=0x0;
+ s* q6 N: B+ V, f6 e9 H6 H SciaRegs.SCIPRI.bit.FREE = 0;//仿真模式下是否自由运行1 O. g9 o+ s" g% i
SciaRegs.SCICTL1.all =0x0023; // Relinquish SCI from Reset& s+ l" p/ p) B6 G
SciaRegs.SCIFFTX.bit.TXFIFOXRESET=1; //发送FIFO复位# v: U" t" O, y) `# L2 F* g0 G; B8 Z
SciaRegs.SCIFFRX.bit.RXFIFORESET=1; //接收FIFO复位 3 R; u; ?, b, r( I1 D# \2 c+ _% Y* Y2 F
}
- j( s! ?0 Z- q1 o; s; ]
" }9 B( B' i! q* t! k0 |5 \* Y* |(2)接收中断和发送中断2 i/ {; D% r4 O' j' ], E
: S8 F$ Q! y xinterrupt void SCI1_RXD_isr(void)
2 f; `" @6 i: f8 Y) U3 h{
# Y! j; w9 e! H: y' k- K1 I UINT16 RxData;9 D% \4 \& A0 I' B, P; ]1 x" d
//RxData = SciaRegs.SCIRXBUF.all;' s1 ^- }* {1 ~8 c5 x
//上一个数据帧应用层未取走,数据丢弃8 l" F: n. Z: B- e+ d
if ((KeyBoardRxFrame.status == UART_FRAME_RX_END) || (KeyBoardRxFrame.index >= 40))
0 T, b" W' C, |( n {
( ^8 A6 B2 ]9 _/ g KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;& O) z- S- d' W) P* K( h3 D
KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;, ^6 Q4 c/ z' D) ^5 s _: A: e; J
KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;
' w) \+ x' i- Z! P" N KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;& g% }8 @+ I0 E0 }1 n
}else& y4 t, x. n$ b' \! G2 A
{
+ w8 o$ m- H/ I2 A8 q KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;
+ e% _9 A. N9 k' y! t/ P& ]# M! C KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;4 `. @7 j% ]0 w+ k( r) C
KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;: {/ y) ?1 X& {3 _
KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;
* ^# T8 Y. d; V7 M: k" _ KeyBoardRxFrame.ticker = KeyBoardRxFrame.spacetime;, B' K5 i1 r \! S0 V
}
# v; y/ w" t/ z7 |# `7 I
/ f' ~" z7 y" |+ s+ |! k SciaRegs.SCIFFRX.bit.RXFFOVRCLR=1; // Clear OveRFlow flag
4 p0 o, y0 U* M* A0 z SciaRegs.SCIFFRX.bit.RXFFINTCLR=1; // Clear Interrupt flag! g9 [0 b# [, X4 v$ k
/ _5 |2 U/ n! A, p9 M5 y
PieCtrlRegs.PIEACK.all|=0x100; // Issue PIE ack( m6 J! X/ f! l' b1 S7 X
}
& X* b$ V. b% R* finterrupt void SCI1_TXD_isr(void)
; F9 y# D) o0 G8 _{
5 k' g, k, \% V* u; h Uint16 i;
7 y: l. h- e* r. L0 ? Uint16 len;& K& s- ^; w" f- r9 I
// 发送一帧数据没有完成1 D f- {. {- f3 l6 g
if(KeyBoardTxFrame.index + 4 < KeyBoardTxFrame.len) # {4 T2 }- D- u |& T$ W' ?
{
3 t" @" p' H; v) _! s SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];
2 y- t$ H# }6 ^/ b$ n SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];4 z. e& N9 p/ m" L3 ]: m5 A+ K
SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];7 E" l7 ?" d0 K+ B! ]) E
SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];
' |6 X4 B2 c% p3 d# D5 @0 [
" Z3 U$ K2 {3 ?# d' g+ u# U SciaRegs.SCIFFTX.bit.TXFFINTCLR=1; // Clear SCI Interrupt flag清除后产生中断5 I* b/ G, I. D! x7 G; Q! S$ K
}$ n, G( V4 C- K) U! c$ ?
else# q; [7 `, r- j# h# }" G7 d
{2 |1 p/ i- c9 L1 q7 m8 A* Z
//发送剩下的数据
. S' ~8 u# [/ w" n5 ~+ t len = KeyBoardTxFrame.len - KeyBoardTxFrame.index;4 R1 j5 K0 y& h* a4 L0 u! N
for(i = 0; (len <= 40) && (i < len); i++)
1 p$ J% s5 V6 x: \+ D {
4 [4 S# v2 y- d/ t8 \7 U7 c9 |- T7 R SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];9 |0 a" S1 e+ b! m! p T9 n" R- ?
}/ k2 A% h# v# v1 q" Q( G
9 k2 F0 h9 U5 Z( J& ^
//一帧数据结束
: _" G! Y! ]0 L+ _' ^ if(KeyBoardTxFrame.len)5 |% ]. E" B& B; @& E1 E( C5 S
{
4 z: z( P. I0 b# i5 q$ E KeyBoardTxFrame.status = UART_FRAME_TX_IT_END;2 i0 N' F6 O5 L8 m" q
}' a# v" w1 }. y1 K' W
}
& X1 k* k3 v. v8 |+ A PieCtrlRegs.PIEACK.all|=0x100; // Issue PIE ACK
% o2 B1 F6 n7 J( I$ Y/ k( }}3 L$ f9 z$ l2 ]: v
- |; i7 z0 {4 p: C# d6 g+ j4 V6 E
(3)读取不到4个字节的数据- a+ t0 @- ~4 V. `* ]% O
+ J9 {. t2 T' |; W* ^
void SCI1_RX_FIFO(UART_FRAME *pFrame)8 a! }9 p% N$ t" G L9 z
{
d# D; c( j: @' Z( ~: ^ Uint16 maxNum = 0;3 J% V. Y" P% S4 J
while(SciaRegs.SCIFFRX.bit.RXFFST && maxNum < 4)
6 o" g1 H8 g8 |$ V {8 w# \) R8 N& E. A. |
pFrame->pdata[pFrame->index++] = SciaRegs.SCIRXBUF.all;
& q- E4 J( u- A% u maxNum++;
7 u I+ U5 y8 b6 j1 k }! G2 v+ k6 W! B H
}5 k! K- E, B8 [9 R; s1 D& ~* u
_% t3 ^& e$ s" I. n) _7 m- B( q2 n
(4)在应用程序需要2ms周期查询接收数据是否结束
5 |( c5 S& j: @2 h9 bstatic void KeyboardJudgeRxFinish(void)
2 I7 r' P7 B/ O7 n% s{
& h% u2 t% b' h //超时或数据长度大于40一帧接收完成
5 X6 \+ R& I8 y& `) j if(((KeyBoardRxFrame.ticker <= 0)&&(KeyBoardRxFrame.index > 0)) || KeyBoardRxFrame.index >= 40)
; b' M0 d3 {3 L& f: {& ^9 F {
6 R+ ]6 c& s+ L: i6 ^ SCI1_RX_FIFO(&KeyBoardRxFrame);5 B/ Q2 i3 h) V
KeyBoardRxFrame.len = KeyBoardRxFrame.index;$ k- W& q% v) I. F' \! r
KeyBoardRxFrame.status = UART_FRAME_RX_END;//数据接收完成,应用可以取走数据
0 }, c6 ?7 @7 U, ^9 T }3 G8 w) C E) d U1 S9 H, g2 `
if(KeyBoardRxFrame.ticker > 0): J3 Z- b# K( m
{8 k6 ~# o, t/ |2 U# z) b$ N" n
KeyBoardRxFrame.ticker--;
, E2 B7 O' i' G# Y0 ` }
& ?' E+ a* {/ K7 j}
3 h1 l V: C. { H' L1 n7 m. h& s4 w" g) D% Y
(6)发送
, u; q6 M7 h' gvoid Keyboardrs485TxFrame(void)
1 `: s+ o8 H. j" K) O* {& f{
' [% ?" B" Y! s( ? SCI1SetTxMode();
, ]1 @3 ?) R/ j //如果当前帧正在发送,又重新请求发送一帧数据,则请求的数据丢弃' i, Y1 P, D9 E. S7 F0 ~/ v
if(KeyBoardTxFrame.status == UART_FRAME_TX_ING)
3 T! u' a9 M, j$ q2 |8 U {
6 \: C) P! H9 ^2 Q7 S0 s return ;
+ |. x# \/ g0 y& K* ^$ n/ E3 z+ Z$ ^ }
; b8 ?+ o/ u5 ^9 W+ B G7 E" \ //启动发送第一个字节后,产生中断,接着数据在中断中发送完成4 p2 Y F% G! k/ z( ]; W
KeyBoardTxFrame.index = 0;3 F* Z1 Z# l( }2 ~. B, w
SciaRegs.SCIFFTX.bit.TXFFINTCLR=1;//启动发送中断
5 g6 y$ l+ o5 H! @ KeyBoardTxFrame.status = UART_FRAME_TX_ING;6 i+ m7 v- x5 Z8 I) J/ @. v! V9 J
}
& B+ \ b$ b: i& Y3 k" G$ [3 ^9 T |
|