|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
用DMA0向UART1-TX发数据,出现奇怪现象,要发送的字节提前了,而且总数还是对的?7 V; N4 o1 ^; C
要发送的数据为# \" p/ U' ~% b: b
chr(04) & 197331" & chr(0x1B) & "2021Echo00202111”; m- N4 v' M# a; O' ^! j
接收到的是:' i% |- X8 K, g- T# Y" k; U
chr(04) & 197332"& chr(0x1B) & "202EEch2**202**
: k( G# B0 ~2 L4 J) b7 ^5 Z- ^4 `+ Y' a- x2 G x* K5 `: b1 B
; b! P/ a9 g* f3 W8 _经过试验发现197332最后一个2,是2021第一个2多发一遍,并且覆盖了前面的1& Q8 r5 Z R F+ W' S
# ?; |+ ^; B* _( O
' u8 ]9 W5 ~& V
DMA设置:' G6 w& G7 E8 Z
static void SendCC(uint8_t ComName)5 @. q n. y3 U% k( X3 Z- o
{2 d. u! X* d3 E ^# y6 X% I5 e
uint8_t i ;1 U( \+ B z0 k R3 Y3 ~
$ [9 [0 X5 Y# R, P
//- ********本段为DMA为初始化部分***********/
" P( b/ Y, u1 }$ X* @! b/ g
$ ~, e3 x7 z* W$ C DMACONbits.DMAEN = 0; //禁止DMA模块
5 Q8 i _4 Y/ l* U, J9 T* J DMACONbits.PRSSEL = 1; //优先级循环方案
/ Q4 e7 q7 w* f9 }! Q DMAL = 0; //RAM寻址下限
, H% a, r' C# h4 c- E d8 n DMAH = 0x8000; //RAM寻址上限
) ]3 h" K9 `& R- k5 R/ V. H IPC3bits.U1TXIP = 7; //DMA0优先级为7
) I% ?1 O. G% A( t3 m9 C" s 5 ^" t$ u# r/ n( j
IEC0bits.DMA0IE = 0; //关闭DMA0中断% C( r9 j0 J( u4 ~5 Y, s( ?$ Z
IEC0bits.DMA1IE = 0; //关闭DMA1中断
; @6 Q3 D0 a% N& o* \9 n IEC1bits.DMA2IE = 0; //关闭DMA2中断
. ` h1 [) f6 ~2 Y- u2 z IEC1bits.DMA3IE = 0; //关闭DMA3中断! W7 _8 K7 E) ?* z' R0 m5 U K
//禁用计时器中断矢量
0 J8 l! f8 f8 @$ K# J T1CONbits.TON = 0;
9 ? T9 N0 ~5 B" G _T1IE = 0;
- N3 U" r( g, O; ~ IEC0bits.INT0IE = 0;
$ C- @& G9 k& T! G! V3 x- _! b. O* }' Z$ b
//- ******************************************** u3 E/ I, x9 Y4 P( W- f! H# Z
3 d. }4 U( e* u7 @ //-------初始化DMA0-------------------
# T, K7 r @' t' l // ******设置DMA0通道从COMM_BUF向UART1-FIFO发送数据*****************4 x. G, x0 ^- k0 @0 r* M
DMACH0 = 0x42; //禁止DMA0,并开始对DMA进行配置
9 u% ]& m+ I0 d1 [; [ DMASRC0 = (unsigned short int) & Send_Comm_Buf + 4 ;//设置DMA0的源数据地址
: F! p! l ~: j( p // DMASRC0 = *Send_Comm_Buf;//设置DMA0的原数据地址# H5 X: T9 _* l: Q
DMADST0 = (unsigned short int) & U1TXREG;//设置DMA0目标地址为UART1-FIFO;
4 Y9 B" z" @. f# p. h1 K# G DMAINT0bits.CHSEL = 0x05;//设置DMA0通道触发源为UART17 P9 u+ a, l- q% X$ }8 A* W0 C
DMAINT0bits.HALFEN = 1; //设置DMA0半满中断
: V! H" j: @. h' s; [0 U& u
& n# n# Z" q1 e( h6 v5 i; L/ a. y) A4 `/ z) B
//-------------------------------------* g/ |. `% Q4 N6 z8 N
3 J! k* y. Y% D! I+ I c& o
//写入前7个字节,即指令号+器件ID,
' @7 T I- \0 y //由于器件ID为6字节,由于某些通讯部件FIFO不支持7个字节的存入,须将器件字节分段
1 w! P8 O" Y$ w p. n //现分为两段,即直接写入FIFO的,包含指令一共4个字节
( G( ]! Q5 m1 i7 J6 k* F
8 j- ^; [: K5 _+ a' F# z Send_Comm_Buf_P = Send_Comm_Buf;
$ @* b3 v. A# N& T U1TXREG = ComName ;//写入指令% [! v1 J6 p3 {2 h
*Send_Comm_Buf_P++ = ComName;//指令写入Buf,Buf指针加一/ b# b' H+ n5 a0 k# W @
for (i=0;i<6;i++)! h0 g: @* g+ U f L4 }
{8 L7 d q3 _; R2 O& t5 c
*Send_Comm_Buf_P++ = SYSID;//写入数据到Buf4 p% F) A F( O2 [" r
if (i<=2) , H$ f' |2 z% Q; e0 z& D
{
/ R- A3 W; h0 L" J/ P c U1TXREG = SYSID ;//写入数据到FIFO- {6 D: x8 c- R0 }. T& Q
}! w, [+ A- Q R, j3 P- J, n
}4 ?8 D" ~/ m& C# P$ G
, N! O8 F8 m2 w& u4 f# ^9 [9 v
% }; m( x- S/ _( f
5 S% | n* p- ~% f+ Y _' l2 x8 K
// 以下针对各不同指令进行处理,不再直接写入TXBUF,而由DMA进行处理1 y" j4 A( Q7 Q* _ I+ X( F6 f: }
// 发送本机基本参数," D' E t9 }2 i. [
if (ComName == C_SysInf)
9 K* X: i. C6 a/ o3 D4 k {
* ] `* x, O) T$ o( _8 o0 } Send_Comm_Buf_Len = 0x1B;7 _2 n) k! t6 ?4 h9 l6 w
; R5 j) D$ R X/ K6 } J( o *Send_Comm_Buf_P++ = Send_Comm_Buf_Len;//07:指令长度7 x3 F: Y- k D) q3 @( f
*Send_Comm_Buf_P++ = SYSMData[0];//08:出厂日期Y
1 g5 y" i# G( C" _2 L5 D *Send_Comm_Buf_P++ = SYSMData[1];//09: Y0 s0 j, x+ h& R
*Send_Comm_Buf_P++ = SYSMData[2];//0A M: s! W4 Z4 Z7 R7 i6 x+ K
*Send_Comm_Buf_P++ = SYSMData[3];//0B D) U4 T6 M% U" b" g. V
*Send_Comm_Buf_P++ = SYSModel[0];//0C型号$ K3 M5 u( J8 q1 X
*Send_Comm_Buf_P++ = SYSModel[1];//0D型号 |1 Q: K( ^9 U
*Send_Comm_Buf_P++ = SYSModel[2];//0F型号
/ I$ u3 k T, y% g3 D' P- X( h/ D *Send_Comm_Buf_P++ = SYSModel[3];//10型号
, V8 f+ }. d) ?" Q+ D* N+ ^6 b *Send_Comm_Buf_P++ = SYSMEdition[0];//11出厂版本号
) ~6 z8 b4 k7 `, P8 T8 m; n c4 J *Send_Comm_Buf_P++ = SYSMEdition[1];//12
% ?+ I* C. ^; _ *Send_Comm_Buf_P++ = SYSCData[0];//13系统更新日期Y- U$ W3 I* D* z O0 r/ u" V$ ?6 a
*Send_Comm_Buf_P++ = SYSCData[1];//14 Y' o7 L9 P* j$ {+ k: H c7 R
*Send_Comm_Buf_P++ = SYSCData[2];//15 M
6 b; E! O7 N" r$ a *Send_Comm_Buf_P++ = SYSCData[3];//16 D/ u0 _4 _' }6 z0 O& O7 H. _
*Send_Comm_Buf_P++ = SYSCEdition[0];//17更新的版本号
" s9 w6 r+ [* E1 s *Send_Comm_Buf_P++ = SYSCEdition[1];//18
1 Z4 o1 o4 B2 J- h' [ }" V% r! W- ^$ ?9 b4 t, B
: D# L/ v5 T+ L' s //启动通讯-DMA
7 H& o2 P- @* I* X# X
/ O2 b9 P6 d1 D4 F) j0 ?# u DMACNT0 = Send_Comm_Buf_Len - 7; //设置传输数据数量
6 T6 g' r4 |7 D* r# S | U1STAHbits.UTXISEL = 0;//TX接收缓冲区有8个空位触发中断& s6 X/ _( C( d+ @
// *********************************************************************# f9 N+ N6 l6 i/ B f
7 s$ Y1 S2 C1 P! H
// **************启动DMA0***************************************
3 V/ ?, `3 t& Z. A //IFS0bits.DMA0IF = 0; //清除DMA0中断标志+ v+ z' E% w% A2 U
DMACONbits.DMAEN = 1 ; //启动DMA模块
- E% J0 J! j5 B1 L8 I" |; a" w# T9 Z DMACH0bits.CHEN = 1; //使能DMA0
) M& s0 y' A. p) `
, Y+ f) n |- _! ~+ I* O* T4 M+ r // ************************************************************
! G. i# O2 V3 c5 U, _; l
3 P- D& Q2 n: K IEC0bits.U1TXIE = 1;//开启U1中断
' T7 k; d& B0 y2 M IEC0bits.DMA0IE = 1; //开启DMA中断
4 M' V. W8 x8 n' C5 L
3 A# k$ A9 N; M4 i" ]$ D" m, R
0 e0 z* A! ]7 H, }7 m' [
" b# K% D- t1 H, f$ C}
1 A- b& Y9 y! d% i- ~( \1 ]+ i$ t8 X
UART设置:" [7 r) U9 P+ T+ u
8 \1 T/ F# l3 w) K* t8 h
* r2 S- n1 ]9 O4 r9 Q/ N/ D
0 m* N+ q% |: [( R( ?, r9 W+ J: m+ t: p, `3 g2 `
void UART1_Initialize(void) T/ G, j6 @8 f% x* G
{
; f' m/ N0 z& S4 H E+ T% E% }* {7 | // URXEN disabled; URXEN禁用;+ p' m) S9 C; _+ g
// RXBIMD RXBKIF flag when Break makes low-to-high transition after being low for at least 23/11 bit periods;
! c2 ` o0 X# d- @, D. Q // RXBIMD RXBKIF 标志当中断在低到高过渡至少23/11位期间后进行低到高转换;) N9 F# n- U1 b* I. K
// UARTEN enabled;使能Uart1;
$ R1 @8 ]3 k( W9 v, K) d0 W // MOD Asynchronous 8-bit UART; 异步8位UART;
- q6 a% T6 f/ }) |& c // UTXBRK disabled; 禁止同步暂停符号发送3 Y7 F3 d4 v: t/ Y
// BRKOVR TX line driven by shifter; TX线由移位器驱动;
7 j$ ~7 P3 c g- u // UTXEN disabled; 禁止发送;9 { {3 U3 E% }3 ]3 I
// USIDL disabled; 在空闲模式下工作;7 |; Y2 r( a1 `5 N/ i) ]
// WAKE disabled; 关闭唤醒使能9 q( i) C: p2 A# s0 d8 @
// ABAUD disabled; 禁止自动波特率检测
+ {) |1 ?$ _* \+ R // BRGH enabled; 高速波特率(baudclk/4)
$ c% y' p. Z4 }7 y. M4 N" \ U1MODE = (0x8080 & ~(1<<15)); // disabling UARTEN bit
1 c0 k* d# Y; i2 x2 _4 C& e 5 z3 V3 m8 N" d' Q) j% P. D
// STSEL 1 Stop bit sent; 一个停止位
. M. }0 u. i& X5 v: j* u // 1 checked at RX;
5 `1 K& n# l. s! D: V: G; V F4 C // BCLKMOD disabled; 使用传统技术器生成波特率具体取决于BRGH位;
* p- W5 m9 q- }4 Q( N! { // SLPEN disabled; 休眠模式下关闭
. J1 \: D, s! s1 Y+ Y# S G // FLO Off;流控制关闭5 t. ~+ ?4 B9 Q, `
// BCLKSEL FOSC/2; 时钟源为Fosc/2(指令周期时钟); m, H+ D4 y; Y- q7 z
// C0EN disabled; 校验和模式0. I$ [# V/ @3 V! A0 J3 `: T
// RUNOVF disabled;检测到溢出错误时RX停止接受新数据
' D$ c4 j( I* G' L! Z, ] // UTXINV disabled; 输出数据不翻转,空闲状态TX高电平
1 t4 p' U d# u, e // URXINV disabled; 输入数据不翻转,空闲状态为高电平
8 [3 } v7 K% K: w // HALFDPLX disabled; 全双工模式
. x. ~3 c. @4 M% ? U1MODEH = 0x00;
7 Q5 L; {9 F0 w$ E: L& ]
/ @" o% l: e5 y# s) }) w% |0 v // OERIE disabled; 接收缓冲区溢出中断禁止6 S. n0 K J2 Q. [! G( g* s
// RXBKIF disabled; 接收暂停字符中断禁止+ n. s1 c+ ^/ i5 P
// RXBKIE disabled; 接收暂停字符中断标志位清除
: P9 ~! D5 I5 U0 G( v/ q // ABDOVF disabled; BRG尚未在自动波特率采集序列期间计满返回
. q( c. h. H6 G' }! [; s' F // OERR disabled; 接收缓冲区溢出标志清除, q8 l6 X! V7 v, b1 `4 i5 y
// TXCIE disabled; 发送冲突中断禁止4 |3 c+ Y. Z& b; {: s
// TXCIF disabled; 发送冲突中断标志清除
. ~% I7 @" Q" O // FERIE disabled; 帧错误中断禁止
# @: j- [7 j5 }5 b/ N/ S // TXMTIE disabled; 发送移位寄存器空中断禁止
" L# n9 g( C& r# U // ABDOVE disabled; 自动波特率采集中断禁止' G6 q3 E) K8 e5 }
// CERIE disabled; 校验和错误中断禁止/ R! h! s( R8 t8 y
// CERIF disabled;检验和错误中断标志清除
" S9 ]1 O! c/ v* h // PERIE disabled; 奇偶校验错误中断标志清除5 \/ q; P! R4 |' _3 i; Q
U1STA = 0x00;
# r5 H; K5 n* w 8 j8 j4 t: Y# l: Q$ z
// URXISEL RX_ONE_WORD; 在缓冲区有1个以上字节时触发接收中断! s9 r% ~/ Q6 D0 z! V2 k. H' z
// UTXBE enabled; 发送缓冲区设为空,在UTXEN=0时写入1将复位TX FIFO指针和计数器 ?; i9 l( L# k9 `& R2 ]
1 x* j5 P+ _0 ?# `% N // UTXISEL TX_BUF_EMPTY; 发送缓冲区全空时触发中断
7 a; I7 j( k8 l5 r ! R2 C8 N+ ?( F" Z! V7 C8 y
// URXBE enabled; 接收缓冲区为空,在URXEN=1时写入1将复位RX FIFO指针和计数器
7 I9 j. Q. h: u1 B$ p6 z' g // STPMD disabled; 在第一个或第二个停止位(取决于STSEL)的中间位置触发RXIF/ d+ F8 P& h5 C* K' N
// TXWRE disabled; 清除写发送错误标志# j: i" }( c2 V, p+ U2 Y
U1STAH = 0x22;# a! l1 b" a+ r& B, D9 G
, {. v- b* T+ g0 a7 \/ i
// BaudRate = 38400; Frequency = 4,000,000 Hz; BRG 25;
. X( Q9 } x0 n% J8 l* U S/ x2 t
9 S' T) w: p5 n3 e% m, m* W U1BRG =0x19;
7 ~2 y, q* s6 U4 T U1BRGH = 0x00;! F- u/ Z' G+ j R
: {. l8 P1 t6 p) u, g
U1P1 = 0x00;- W5 ]3 r6 n {8 T' V- e' v Z
U1P2 = 0x00;
$ e8 K. e9 a; l# z: T1 T2 V! ~+ O U1P3 = 0x00;* i5 N% c. z( r! a
U1P3H = 0x00;: f; ~2 \( I. B" v
U1TXCHK = 0x00;
/ q/ W1 v! ?* ]. [" E Z. d U1RXCHK = 0x00;( U Y, G/ S1 q8 o
7 X4 d2 {1 p: w9 q
U1SCCON = 0x00;//9 X+ y6 V3 B X3 w5 k
1 ^+ {6 a+ W; r% |+ J6 C/ L
U1SCINT = 0x00;# r% I& v) z3 b% P- s" g+ q
4 O& a0 e" j% \6 v7 b4 p# c/ B5 f6 o
// UART1中断寄存器$ _! u0 H% l, F- b4 f
// ABDIF disabled; ABAUD 未使能,或已使能但未完成自动波特率' V( _5 u$ v- Y0 A) `& y6 p
// WUIF disabled; WAKE 未使能,或已使能但未发生唤醒事件
2 Q% k$ d* V* f# i% ]& s // ABDIE disabled; 不设置事件中断
% O# o0 ] P6 ]* K/ j. K7 v8 L U1INT = 0x00;
" n' w/ N- z6 i" K) W* u( e! V, w5 U. G2 B/ E: U
/ G5 U% z+ T4 S0 n9 f9 J6 O
IEC0bits.U1RXIE = 1;// UART1接收中断允许9 r* c' y' \3 W. E" s
% q! P, s, F9 b8 g
0 Y4 K9 _* F+ b4 ]$ m}
1 f" A) h+ e1 d. ]4 t* U& B3 z$ ]5 F- }4 g( w- N
I0 R' W' ~) r) V F# e- M
+ _/ l. x. k, c/ L7 P* B
8 H! O8 I3 {- ^9 K/ O7 Z7 [
各种办法都试过了,包括降低波特率,提高优先级,关闭了所有其他中断,把TX发送中断改为7个空位,等等,都试过了。甚至只发送chr(04) &“197331”,结果收到的还是chr(4) &“197332”。改为不用DMA都没有问题,有没有大侠能够指点一下
) D3 u; v- Y; q) D" i! h |
|