EDA365电子论坛网

标题: dsp高效接收和发送不定长度的数据的方法 [打印本页]

作者: geronimo123    时间: 2020-12-14 15:29
标题: dsp高效接收和发送不定长度的数据的方法
        本文介绍dsp高效接收和发送不定长度的数据,该方法减小cpu的中断次数,经过长时间检验,该方法安全可靠效率最大。我使用的是28034只有4级FIFO,在优化前中断深度设置为1,cpu频繁中断,导致正常程序受影响。经过改进,设置发送中断深度为0级,接收中断为4级,只有在数据发送完成和接收满4个字节中断。5 W9 e( ]: e- J# b7 D" O, q2 _
接收流程为:等待接收中断—》读取4个fifo数据—》超时检查—》读取fifo剩余数据。这样就会接收完整的一帧数据。
0 p4 b2 l- u! `发送流程:触发中断开始发送数据—》写入4个数据到发送fifo----》等到fifo为空中断–》写入下4个数据到fifo----》写入最后剩余数据。. \/ W" M% c  S6 T  Z
具体如下:
+ M$ I4 n+ {& s(1)初始化配置) A+ d& m" D7 S. f1 U) J4 o
void scia_init()
- Q. F1 K/ d: Q{. \1 D; R' H" `0 J. }0 g' F8 t
    // Note: clocks were turned on to the SCIA peripheral3 [% K: t) `( j! A
    // in the InitSysCtrl() function- X5 }1 J* U) e4 _1 O1 a% h
     SciaRegs.SCICCR.all =0x0007;   // 1 stop bit,  No loopback* o5 e3 h, ^2 `6 J
                                   // No parity,8 char bits,
6 e% Y9 j; {4 l# t; ~+ {- ?                                   // async mode, idle-line protocol
4 ^" ?( A* P7 p6 ]  }    SciaRegs.SCICTL1.all =0x0003;  // enable TX, RX, internal SCICLK,$ G" [% J) c$ X* J6 H7 B
                                   // Disable RX ERR, SLEEP, TXWAKE# a" L; v5 I: j
    SciaRegs.SCICTL2.bit.TXINTENA = 1;//使能发送中断
% w' Y. C, S; x1 \8 [- c; g4 e+ }) N; |9 {1 `
   
2 z/ ^! }* ]$ T: Y) G: A    SciaRegs.SCICTL2.bit.RXBKINTENA = 1;//使能接收中断
+ F0 A4 r& q4 n+ H+ C  b                           - {$ Q$ y4 d7 [1 y; W9 }
    //BRR = (LSPCLK / (SCI Asynchronous Baud * 8)) - 1 ,LSPCLK=30M,
0 p9 K0 V3 |% Y/ B6 s! G2 l  @    //BRR = 0x0020, baud=115200' w1 p) y) u7 W3 n1 e6 c% o
    //BRR = 0x0007, baud=460800, W8 M6 Q1 r9 w! n; L% g
    //BRR = 0x0061, baud=384001 h7 G1 q8 _$ t2 f% T
    SciaRegs.SCIHBAUD    =0x0000;
9 t+ ?& I3 N# o6 ?% J7 ^. z    SciaRegs.SCILBAUD    =0x0020;//
  x3 K& Q  s9 c& l8 O( g; @9 a    SciaRegs.SCICCR.bit.LOOPBKENA =0; // Enable loop back
0 w% w& x6 a5 p1 g6 n3 G/ C0 l1 u+ H    SciaRegs.SCICCR.bit.STOPBITS = 2; //
9 J( l+ d5 \7 y) F. n) f    SciaRegs.SCIFFTX.all=0xC020;//设置发送中断为0级7 P3 T' D6 B+ O3 K6 q. ~# \* R
    SciaRegs.SCIFFRX.all=0x0024;//设置接收中断为4级+ X9 f' Z% |/ E5 S$ K' f" R& H
    SciaRegs.SCIFFCT.all=0x0;
( v! L" e" e' P, d# J2 K/ i    SciaRegs.SCIPRI.bit.FREE = 0;//仿真模式下是否自由运行
; p* T: b' x: w. J5 R7 Z5 b. X    SciaRegs.SCICTL1.all =0x0023;     // Relinquish SCI from Reset
) `" c3 Y' D% \9 q    SciaRegs.SCIFFTX.bit.TXFIFOXRESET=1;  //发送FIFO复位
$ F  C) O1 ?6 p" P    SciaRegs.SCIFFRX.bit.RXFIFORESET=1;   //接收FIFO复位   
% k, l9 z- t' I3 q}
" A" _# S& @( e# p8 ]. x% G: n' z) S
(2)接收中断和发送中断/ S' K* U# P" ^9 @% H. ~1 K
8 Z3 }4 y8 W. L- r7 V! j5 \  V
interrupt void SCI1_RXD_isr(void)
- _& l( z( e# _( R/ l7 g7 j{
  z; @4 N, q- R/ _    UINT16 RxData;  q# H& s0 C0 H5 p4 {3 C$ M
    //RxData = SciaRegs.SCIRXBUF.all;6 \% G/ M4 g+ a% d$ O
    //上一个数据帧应用层未取走,数据丢弃7 t2 L" l2 N( z# `% ~
    if ((KeyBoardRxFrame.status == UART_FRAME_RX_END) || (KeyBoardRxFrame.index >= 40))# D$ r  s" s, E3 h& `- e" ~* c( C  J
    {; |0 ^& E/ V4 @7 k, S
        KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;
2 ^9 T& T/ p. q6 h8 L+ l! v        KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;* C0 T5 k8 L% G% b
        KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;
  p/ Y' q4 g* v        KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;5 B! O" t" m* A( n8 q
    }else# d: f1 h8 V3 t# s! z
    {3 p+ }$ ~8 R+ \9 e$ H. H
        KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;
/ Z/ I6 q  F- M- b0 d5 V! P+ M! M# S        KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;
) v' {0 I; i. W" U7 j        KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;8 z+ W' _7 i. W4 [  R
        KeyBoardRxFrame.pdata[KeyBoardRxFrame.index++] = SciaRegs.SCIRXBUF.all;) ~4 T0 V$ F1 X5 m2 S+ Y- P
        KeyBoardRxFrame.ticker = KeyBoardRxFrame.spacetime;# q. O8 w* _. [- D( [0 z: G
    }4 r  C/ w! w! j0 Y
   % o2 h) @# l0 a. J
    SciaRegs.SCIFFRX.bit.RXFFOVRCLR=1;   // Clear OveRFlow flag
2 z/ N4 K- [+ h3 b: F    SciaRegs.SCIFFRX.bit.RXFFINTCLR=1;   // Clear Interrupt flag
6 o: o: C6 v/ v; N
$ X! I1 J1 a- _    PieCtrlRegs.PIEACK.all|=0x100;       // Issue PIE ack) \: H+ a1 _( @9 J/ L) Y
}
3 K: |' U' U5 ~interrupt void SCI1_TXD_isr(void)# S: G5 u& T, T7 R8 d# n0 z5 B
{
+ v) q1 l4 H5 \. m* ~, l    Uint16 i;
+ }1 c! h' k! R- A4 ]    Uint16 len;
  n' m: h. D/ |3 v+ m. P  b8 Y! w    // 发送一帧数据没有完成* f4 s6 a* D' L' w6 ^7 K! v
    if(KeyBoardTxFrame.index + 4 < KeyBoardTxFrame.len)         8 o& l7 [( g8 x* G: G
    {
$ D+ i$ j* ]* o        SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];8 i2 N& F! b5 I
        SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];
0 n+ \; L$ Y% c5 F0 S+ k2 g        SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];
- W/ t1 D: F' g! o' Q8 s* p3 q        SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];
: i1 \5 n9 |' j        
2 K  _/ Q- i" I& m' t        SciaRegs.SCIFFTX.bit.TXFFINTCLR=1;  // Clear SCI Interrupt flag清除后产生中断$ C0 z8 H& ]2 B' S5 s0 v
    }! T3 E) `- I1 d, s
    else
+ o$ @# W1 _1 p8 r2 Y; O    {' K3 w8 r; [+ q% k
        //发送剩下的数据7 J# I& N2 O7 D
        len = KeyBoardTxFrame.len - KeyBoardTxFrame.index;" u0 N) }8 K4 S( A5 n
        for(i = 0; (len <= 40) && (i < len); i++)
5 x! w% g7 i' V" E' c        {
+ z  B9 i9 F* D* G8 E            SciaRegs.SCITXBUF = KeyBoardTxFrame.pdata[KeyBoardTxFrame.index++];$ m4 B) i" [4 J- L" N8 d5 G! g# c
        }
! t. W5 m; Z, Y- _8 b        - e% u! [8 ~. u, N3 u0 d$ u
        //一帧数据结束* O: u* O1 Z* b# O0 Y
        if(KeyBoardTxFrame.len)) o  I6 f3 A! r$ }; R: _
        {% Z, t. z3 ?3 E
            KeyBoardTxFrame.status = UART_FRAME_TX_IT_END;
; ^! r& R' y- y  r" f+ I        }
2 ^, n  z) Q2 \! e" ?0 f     }
% w4 d6 P# H+ w5 d& X& F    PieCtrlRegs.PIEACK.all|=0x100;      // Issue PIE ACK; p0 p9 |: W* x% a% U3 R
}
+ B% ^9 |/ M% p' b
6 L0 z' ?2 H7 z- z) \- n(3)读取不到4个字节的数据# B. `1 G6 g* m1 }7 ]4 a
6 S3 d) _7 Z* {+ Q$ H  C
void SCI1_RX_FIFO(UART_FRAME *pFrame)
) ]/ ~6 T, p8 M: {3 X{
( ]1 U# u/ U; V8 C    Uint16 maxNum = 0;
; R- \7 \8 \7 _3 P3 G    while(SciaRegs.SCIFFRX.bit.RXFFST && maxNum < 4)
- B5 D2 v6 m8 h6 i9 d: W; k    {
& p5 a2 Z! r) p6 k! n3 f# m        pFrame->pdata[pFrame->index++] = SciaRegs.SCIRXBUF.all;  T$ c' k5 i8 ]/ z. o) z
        maxNum++;
! C7 t) q# b1 b+ t+ b" g    }/ x- O7 @5 x: ]" ^1 Q5 b
}
+ m9 M7 `- f. R% _& t& I
) d& B' ~8 a% B7 `! x/ Z(4)在应用程序需要2ms周期查询接收数据是否结束
" Y; o/ u6 l' rstatic void KeyboardJudgeRxFinish(void)
% y" O4 w" c) O0 j) Y{# w8 Z$ I5 @, T  s
    //超时或数据长度大于40一帧接收完成4 ^6 k1 v4 m& z' ]
    if(((KeyBoardRxFrame.ticker <= 0)&&(KeyBoardRxFrame.index > 0)) || KeyBoardRxFrame.index >= 40)
# X3 B! t' Y0 S$ A* z# o5 ?7 ^' |    {
  ]" t- o7 c3 q3 B        SCI1_RX_FIFO(&KeyBoardRxFrame);
" y& ~# _6 O) M: U, P, ]/ |. H. A        KeyBoardRxFrame.len = KeyBoardRxFrame.index;
! U9 E! U: |! T+ F7 C        KeyBoardRxFrame.status = UART_FRAME_RX_END;//数据接收完成,应用可以取走数据/ B% t9 Z) a0 ^" A6 L+ G
    }' o5 v9 f% A! p2 C1 E- d+ b
    if(KeyBoardRxFrame.ticker > 0)
& w7 N0 B( N0 f, L( q! |8 g; N5 {    {
4 k$ f% B: U6 L+ k. T" _, \        KeyBoardRxFrame.ticker--;8 r9 e: ~* u) p4 _. Z
    }
6 K# `" `4 J! j4 z5 e+ q% R}
7 P. _. `2 `9 A( }
+ C% [' o- e0 }. j/ t- j  W8 ^0 }(6)发送5 V/ E0 p$ U7 D' _- e( I
void Keyboardrs485TxFrame(void)( l; z+ Z- A( N% ~5 e5 [
{' {8 }$ i( a1 b( M# K
    SCI1SetTxMode();- ~* L% K1 u$ @  d9 s
    //如果当前帧正在发送,又重新请求发送一帧数据,则请求的数据丢弃5 O0 y+ B% N$ j; L3 C
    if(KeyBoardTxFrame.status == UART_FRAME_TX_ING)! b( Z  B  G4 j. m! T
    {) d9 q; y( {9 v' [0 [: {8 y# D
        return ;
/ r& |: v8 _  N9 U1 N& e    }( [$ y" B- \2 S# h$ M+ P
    //启动发送第一个字节后,产生中断,接着数据在中断中发送完成4 Q' e" b2 e2 ~, K1 F) ?
    KeyBoardTxFrame.index = 0;7 q* u$ ?. }. K4 s( u$ S
    SciaRegs.SCIFFTX.bit.TXFFINTCLR=1;//启动发送中断2 b4 F0 o3 y5 y9 R/ P' `
    KeyBoardTxFrame.status = UART_FRAME_TX_ING;
/ c9 b4 ?# ^# a% ~% l  `}
% Z" r1 [3 N0 g; a% J
作者: shapeofyou888    时间: 2020-12-14 16:56
等待接收中断—》读取4个fifo数据—》超时检查—》读取fifo剩余数据




欢迎光临 EDA365电子论坛网 (https://bbs.eda365.com/) Powered by Discuz! X3.2