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:
clock
s were turned on to the SCIA peripheral
3 [% K: t) `( j! A
// in the InitSysCtrl() func
ti
on
- 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=38400
1 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.SCI
FFC
T.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 Ove
RF
low 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' r
static 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 Keyboard
rs485
TxFrame(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