找回密码
 注册
关于网站域名变更的通知
查看: 334|回复: 1
打印 上一主题 下一主题

转——基于ZX-2型FPGA开发板的串口示波器(三)

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2019-4-18 09:25 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

EDA365欢迎您登录!

您需要 登录 才可以下载或查看,没有帐号?注册

x
转——基于ZX-2型FPGA开发板的串口示波器(三)
$ t5 e  o1 h- S1 v  k( [! D

: g' Z( g7 Z% G2 i& y( P5 S
  C* d) L9 Y7 I$ R3 O& `
串口memory mapped 总线与配置系统子模块寄存器代码分析; \; F8 P8 z9 c& b$ b# R
CMD# I: L) f- K7 r/ E
CMD模块为串口数据帧接收与解析模块,该模块负责串口接收到的每一的数据进行解码判断,从数据帧中提取出地址字节和数据字节最后地址字节和数据字节转换为类似于Avalon-MM形式的总线以实现对其它模块的控制寄存器的读写,从而实现通过串口控制FPGA各个模块工作目的# k( }0 ]; i6 N1 m9 ]# _' K
在工业应用中,串口指令大多以数据帧的格式出现,包含帧头、帧长、帧命令、帧内容校验和以及帧尾不会只是单纯的传输数据这个实验小梅哥也使用了数据帧的形式来通过上位机向FPGA发送命令,不过这里我使用的帧格式非常简单格式以帧头、帧长、帧内容以及帧尾组成,忽略了校验部分内容,帧头、帧长以及帧尾内容都是固定的,不固定只是帧内容,以下为小梅哥设计中一帧数据的格式:
0 r8 x- l; w, x& O8 g" p4 N! |/ ]- ~
/ d- N  v- U; W. B$ d9 u

! h2 K4 c: v4 y/ r6 {帧头: @% T  b6 A. D0 W5 |" [
7 D" y, @9 Z+ \  Y( Z
帧长
% n) {8 D' G+ t" K

& s& k7 p5 X0 }7 }9 S) v地址
9 ^. @/ n4 D3 R/ g. q6 H* C

: N# V( Y2 u" V1 [0 x数据9 b0 W8 m8 w$ n1 Y1 K$ T

4 \& s* L7 l" z4 n+ P/ W- ^# h) m, ?数据
+ t" Z, F, Z" v4 X/ r
, C9 ~+ Z6 h. s1 l) S( Y1 B

8 F' s1 Y5 V! \* M

0 H( G1 e1 B% j& N% x0xAA: Q4 p8 o2 a3 P' x

5 p/ h$ Y; e3 S! o3 J0x033 D) F1 a/ ]/ X, Q( R! k! m) W6 e
$ N+ }2 g( W8 |3 f! D8 F0 X& X
0xXX
$ A  \4 I, |8 s$ {0 Z5 Z
# |4 m: @$ {: @
0xXX# o+ F0 Q- H) z; q4 e# e

5 }) z; P9 [, O  w" n1 [) V0xXX
+ r! q+ M  m9 g# G! T  G

  `4 r' C% a5 b0x88. V1 Q. j1 d' o( M
由于数据帧本身结构简单,因此数据帧的解析过程也相对简洁,以下为小梅哥的数据帧解析状态机设计该状态机分为帧头解析、帧长解析、数据接收以及帧尾解析。默认时,状态机处于帧头解析状态,一旦出现帧头数据,则跳转到帧长接收状态,若下一个字节为帧长数据(这里严格意义上并不能算作帧长,因为长度固定,充其量只能算作帧头,读者不须过分纠结),则开始连续接收三个字节的数据,若非指定的帧长内容,则表明这是无关传输,状态机将返回到帧头解析状态继续等待新的数据帧到来。帧尾解析状态若解析到的数据并非指定的尾数据,表明此次数据帧非有效帧,则将此帧已解析到的数据舍弃若为尾数据,则解析成功,产生命令有效标志信号(CMD_ValidMemory Mapped 总线进程在检测到此命令有效信号后,产生外设寄存器操作。
0 [1 p& b3 ^- |7 |5 z! Z. P( r* E# \* i5 O, l% a
' t6 K3 F( I: g0 F/ G

# L5 m9 ^# J2 V5 j; a0 l命令解析的状态机实现代码如下所示:
% i% O4 b; L: z) W1 q4 o

- W) V* U# J0 W8 D. a! t017     localparam
& H) U* l2 `  o6 Z; K/ h, ~5 r8 W6 m# e& Q. Z! o$ r  |5 R
018         Header = 8'hAA, /*帧头*/9 i- G* J& Q3 A3 c9 i3 [2 ]+ ]

1 @+ B: a* Q' _, [, X: y9 }019         Length = 8'd3,      /*帧长*/
3 `9 d' P+ `8 V; Q% I9 \" j6 ?( D8 v1 B) r, @  A, w) x. ]; e/ I5 ^
020         Tail   = 8'h88; /*帧尾*/4 Z: E* M2 C2 ]# i( f

2 F$ l8 p# o/ `2 B021# @# U$ \2 ?1 j# N; i, C' P

! N, \5 b9 q! r' }; O! [022 /*----------状态定义-----------------*/     
  I' z1 G  H: w# b9 \) D' X( E& R+ Z" b% e! ?
023     localparam. N* h7 ^0 `' z& t0 i9 Y
1 w3 Z2 @7 J$ k. v8 I$ `  ?- k
024         CMD_HEADER = 6'b00_0001,
- E% Z2 p4 f! v5 z# t1 A0 U6 p6 n9 o0 S3 O; w, U  e
025         CMD_LENGTH = 6'b00_0010,
! i! V. T8 q! L- j# {' _* q; e' P' U& q3 ~: B' c+ J7 k
026         CMD_DATAA  = 6'b00_0100,
0 `  t+ K8 N1 p# B" q" B9 M  u( N+ r& O; d" N
027         CMD_DATAB  = 6'b00_1000,
  Y. u% u+ _0 y- B
8 g/ o: |; d9 Q8 Z0 M% T* J) Y028         CMD_DATAC  = 6'b01_0000,
- U' S0 L! Q; C* D- i7 u
) ~3 {$ e+ K  [8 _2 T: a! \029         CMD_TAIL   = 6'b10_0000;
. e1 q1 a2 W) e( L, O: a) o0 q( }: D# B1 }! u  G% ?
030     . r' P3 }+ u( K0 g

' {) B5 q, z; a$ z+ O031     
% L. y; m0 p( z7 @: W) z& k
: q# l, @7 S2 c* }5 q9 \032     always@(posedge Clk or negedge Rst_n)
5 J! X( L% W4 [. V  L2 W7 h" [% D0 b  `  ~
033     if(!Rst_n)begin5 U: \! ?) S# {

% |) x) h' C3 h$ ^7 Q6 J1 u034         reg_CMD_DATA <= 24'd0;
$ k, U1 m/ |0 H" z. b
5 N4 `2 P5 z4 G0 h3 k5 @035         CMD_Valid <= 1'b0;
" h8 R1 c0 C9 h# {$ q+ D" Z- A8 m4 U# Q6 w" x+ U) L8 J
036         state <= CMD_HEADER;
# V. U: V, }  v6 t2 O+ o& \4 S* s* W
037     end6 N/ X% R) {6 t4 m' u7 s& a
* j9 k! m1 w( p" N7 q
038     else if(Rx_Int)begin
% g2 q3 J2 |% u1 t- h/ _2 r/ J
& f3 x( L* X  R2 a) o2 i" r5 u: x. m9 w039         case(state)# T+ z( [- `# \0 @) s- y' L
/ ?5 _9 \) f; ?9 G0 C/ m4 k6 B
040             CMD_HEADER: /*解码帧头数据*/. a( k5 c  ~) O  ~6 j

! W& ?9 W" H+ X% }: ^- I041                 if(Rx_Byte == Header)
4 q. U0 Z( ]( A
5 ~7 J% R. E& n" U042                     state <= CMD_LENGTH;1 s, c8 ]( z3 Z" s8 H% U+ C' u
6 q1 H" ~+ {9 B9 h, Z3 P+ ^. ^) {" ?( h
043                 else
* w+ t3 N  p) ~* i0 w. D# {+ v+ H5 c
' t1 B! {% @8 k  e044                     state <= CMD_HEADER;
) T) x+ `" U" y8 p$ ^' k+ V! U* J( W7 w. d, c& g8 t/ Z& P
045            
% j9 u9 ]. W/ A% e( k
. B$ G' r" W" b( M( @046             CMD_LENGTH: /*解码帧长数据*/4 I! Y6 D7 [6 C0 {% ?) r! ~( z% @. d
6 \  u- M" ^: G
047                 if(Rx_Byte == Length)6 m( G9 R7 I" Q0 k1 h8 e
: n9 u6 V  G5 A- p
048                     state <= CMD_DATAA;- m1 O. y7 K. c2 `6 O0 m/ l
6 F/ |* Q  l7 `# y1 I2 p# H" y" n
049                 else" I3 {+ _0 `. C! l" Y, f" O' ~' w

/ t8 Z( v, ~1 K+ ?$ B050                     state <= CMD_HEADER;$ ]" D/ D2 j8 o* j
" I' g6 J5 f4 p" w) b
051            
6 M* \" ]5 {/ C' U5 ?, O3 ^6 m
1 S/ @- ?. V) c3 [8 q6 p052             CMD_DATAA:  /*解码数据A*/
$ h, E3 C( L& N) c+ c
: @4 z, O0 H  q% W+ V053                 begin
# q) L" N2 R/ o# R3 _4 w1 z
; Q# s8 d1 P3 Y) v9 z0 n8 F& f054                     reg_CMD_DATA[23:16] <= Rx_Byte;. e3 S7 u$ y. L: j
& t9 |. y; A$ Q+ Q1 g' T0 p' E2 M
055                     state <= CMD_DATAB;
+ j) t5 `8 a( b$ ^$ Q% t" E/ e  h8 |" g" S% @( I# W
056                 end
; n/ f: t' s' Z4 q- y4 A- n; w5 t2 r
057                 0 @1 k2 O) v5 w% ]6 f, u6 h) M
! g( k' Y5 P& X6 U2 z/ h/ j2 L' o3 r- L
058             CMD_DATAB:  /*解码数据B*/
; @5 c+ o. U% ]! v9 f
& z3 }" x- S& E! y: f059                 begin$ I, h* w1 [4 T2 F7 _$ _
) u# A2 a- n: f: J2 \
060                     reg_CMD_DATA[15:8] <= Rx_Byte;
: b2 R% X7 [6 O
+ A9 L6 c2 Y( \061                     state <= CMD_DATAC;            
* Z. I5 Z' _  N* D% K9 f# q) V, A9 K) i
062                 end4 l0 `8 x! a2 E+ X; D
8 Q7 ?5 z$ g) H/ p( b1 z) N# I
063                 % ~2 Y' U) f7 X  ~) v* a8 _
  M; V' q7 P, W# O
064             CMD_DATAC:  /*解码数据C*/
; _. f0 V) t! H# ^8 r) @7 d: f  z% E) K- ]9 w$ h" \
065                 begin
/ u* O! S7 P4 @4 b( u8 }6 J' x1 `( J! ?1 u
066                     reg_CMD_DATA[7:0] <= Rx_Byte;
: d; y  Z. O9 O- _3 _  B3 d; C; }* S- Y- X4 m; }  j1 U
067                     state <= CMD_TAIL;              0 X" i! R# S9 {

. X2 I8 R5 f! h  Y: Z1 V% h0 V. M9 M068                 end
' @, }* K0 V/ T
$ n% V/ w+ K) @% Q: {: t069
' X  ^) b1 x  g5 E
% w  w% v' [# z) j) x3 Z8 e; f070             CMD_TAIL:   /*解码帧尾数据*/1 r5 v* [* g* Z5 A$ L$ q. A
; J4 I) v+ W4 b" G4 B$ h
071                 if(Rx_Byte == Tail)begin: s, |% {/ v$ C( r+ f. w, u. L$ h
# W( p% b$ p% z& l
072                     CMD_Valid <= 1'b1;  /*解码成功,发送解码数据有效标志*/
8 K9 g% ^2 x+ ~# v  N2 i9 q5 Z0 |- R# J! O. P2 D  M
073                     state <= CMD_HEADER;- \7 w! z) H3 h- ^/ _

2 W- I$ b3 i( l: E; F0 u7 `- L+ L074                 end
* [. {/ H( J& Q9 _) j8 ]% `0 B! N7 ?; p; f; ^
075                 else begin
9 H' V+ P; Q3 s8 H# G! u: @' q- o: c
& h# s/ H$ Z1 m9 W3 J076                     CMD_Valid <= 1'b0;
8 t0 K; G1 B8 {# M+ d8 N
9 ]1 y3 j" C  f: `8 n  u$ A5 \077                     state <= CMD_HEADER;' X" o: Z! e. g. T. V. O4 e. H
2 P0 q: s0 f2 \2 ]
078                 end' H6 q. K: k4 Z- @

5 U7 B9 ~  u" d. l079             default:;. M' h# m+ T- n& u/ [+ n# h
. ]' U5 J  n8 D
080         endcase + w( {  j2 \1 b; a# v6 F$ \* g! _0 \

! s  V! ^) w# T! l' I081     end% P( R, L* L- }  ~4 e
1 L  o- \! n" t8 o" C0 Q: e7 n$ D
082     else begin: }' O- @' q7 H7 r7 t- ^, t
: M+ K' f& c# s2 s) ?& n; P
083         CMD_Valid <= 1'b0;, I- k, ^/ `* ]. @& m1 n! k
! c' v' J% ?  k6 N5 i  @
084         reg_CMD_DATA <= reg_CMD_DATA;+ N  O+ C# J. M( O) |7 T: W
0 `4 D; I6 R( R- Q
085     end
" ~- L6 {! J2 s
23到第29为状态机编码,这里采用独热码的编码方式状态编码方式有很多种,包括二进制编码、独热码、格雷码等,二进制编码最接近我们的常规思维,但是FPGA内部,其译码电路较为复杂,容易出现竞争冒险,导致使用二进制编码的状态机最高运行速度相对较低独热码的译码电路最简单,因此采用独热码方式编码的状态机运行速度较二进制编码方式很多,但是编码会占用较多的数据位宽格雷码以其独特的编码特性,能够非常完美的解决竞争冒险的问题,使状态机综合出来的电路能够运行在很高的时钟频率,但是格雷码编码较为复杂,尤其对于位宽超过4的格雷码,编码实现二进制编码和独热码编码要复杂的多。这里详细的关于状态机的编码问题,小梅哥不做过多的讨论更加细致的内容,请大家参看夏宇闻老师经典书籍《Verilog数字系统设计教程12相关内容。; @( q" E! r1 v; X
Memory Mapped 总线进程根据命令有效标志信号产生外设寄存器操作相关代码如下所示:
0 |) w+ j6 U( I% V6 \
( |1 B+ B  |; j3 E
087 /*------驱动总线写外设寄存器--------*/    
4 u; Z4 S6 P$ O4 X
$ m. E& v0 M% l  j, `+ E+ E088     always@(posedge Clk or negedge Rst_n)
; ]" H9 b2 `# H; ?" {& y& P! h$ a/ l/ C: w8 Y& k
089     if(!Rst_n)begin/ ?# d* u; c+ K% k1 }
& j; V: V" x2 ]% ~8 r6 B
090         m_wr <= 1'b0;0 r* T) U- \0 O: F+ V

  {/ k( S5 z6 R9 m7 s% x091         m_addr <= 8'd0;
- c; N* z) I# p* r' |5 s# m4 K
8 M" t, w6 _2 X3 |& w092         m_wrdata <= 16'd0;
* G" y! s) `. T* I4 p: l
# q! l2 Y/ y4 [& P9 U4 u093     end3 c& y. ^+ y; a5 s0 [( j8 E% i

& \& z3 t5 B' A9 b9 b094     else if(CMD_Valid)begin
' n" P3 Q1 U: i1 }5 B' s/ o! h7 F0 d) J
095         m_wr <= 1'b1;
) e1 |5 ?8 t8 y* B; i9 P7 s- P9 g! `
096         m_addr <= reg_CMD_DATA[23:16];
  y. J& {+ R, |. ~( [/ f+ @# Z2 l
' Q' _* u& d( a* V097         m_wrdata <= reg_CMD_DATA[15:0];
$ I& I0 ?3 }2 ?
! z$ E5 P, C3 Y4 t0 g: Z098     end$ B% ^9 H: p- `( a% S, t/ K/ i
( l7 g5 I  E% _! u6 V; U
099     else begin
$ W( w" D, \' W4 o3 ]- g6 {
% V& P# V, H' I7 @, X: F# L) k" R8 a100         m_wr <= 1'b0;
& M, j! Q) k- K8 b4 J$ W+ ~+ M* e+ Z
; I( K: q" [0 W3 W3 y/ X3 y( [0 g# T101         m_addr <= m_addr;1 K5 A* J9 \; R. O+ R+ }2 C# G

  X% n$ Z' X7 y* y7 ^& m1 q% `102         m_wrdata <= m_wrdata;   1 x  v, D0 [' M' \

; x4 W$ v" i/ r8 U5 S; M103     end' P) x! }  _& _: M6 ]" [8 J* k. ?
7 J. r/ y7 X) E9 j
1 p. w- w" U9 _: W/ }1 c

- [  h9 g4 T/ i# q3 X* i% b
, W) a% X0 N0 j) r- X1 |+ p7 C

5 A& g0 E1 h& u" X: z( h5 H; U" K本系统中,需要通过该Memory Mapped 总线配置的寄存器总共有12分别位于ADC采样速率控制模块(Sample_Ctrl)、串口发送控制模块(UART_Tx_Ctrl直接数字频率合成信号发生器模块(DDS,各寄存器地址分配及物理意义如下所示
# G( s: w% \: u2 l6 W

1 W0 N$ t( {! z. Y5 M) V  J地址& M2 n5 D( V5 }: }( Q; Z

  b1 m' K1 j$ t' `0 R寄存器名称
) Q) t6 ]( _- r& J

  d6 j. x0 N+ o% p! S5 K7 N寄存器宽度
6 d9 f1 e! x9 H4 S2 a/ m5 \

: I$ Y& T; S# h0 _+ Z) ]寄存器功能2 ?" O2 h6 y$ [6 G- j1 E! o
& e- Y7 o7 Z2 q; k! [3 h
0x01  P; N4 n: V- T0 L6 D1 F
- g( n2 J3 A  e
ADC_Sample_Cnt_Max_L
8 J, c0 V! r; c9 E+ ~7 d( i- `* D9 L

: R* g2 r. e3 o8 m# z16
- M6 e, z* m; g: |
% R% f- r8 E: k- P$ W2 @+ {" E4 u
ADC采样率设置分频计数器计数最大值的低16
- {3 r6 @- A+ u5 p1 B$ s
0 L' Z9 h' v7 }- [
0x02( s4 k' V; |2 Y" T( D
* A0 P# W0 Q% p# ~  y% k. G
ADC_Sample_Cnt_Max_H
& k# q3 z+ M. Q# K) D# i3 l

! T9 _( i8 h1 y. f; }( |16
/ f% {' V, v3 ]- l
% ~1 g" R' }+ P3 z2 u
ADC采样率设置分频计数器计数最大值的高16
9 W$ [8 l2 @9 j0 L, U: M

- c! G* x+ Y2 {4 K- q0x03
' _# ^8 e! o; q9 F3 g
- `" A5 r; S' ^7 g; V' }  F; v
ADC_Sample_En
0 ~7 n0 H- V% w9 B# Y

& G- Y1 \) Z- Q; J* `1 c: ?5 u( p1
- D1 j% p, W2 ?9 f" w( q4 ~
; j( E* v, q+ {, L' K& I
ADC采样使能寄存器
" C8 A# J$ w6 D
8 |2 r2 O3 L- \4 b1 C
0x04
7 B& D; n& {  ^8 b0 P8 Y  X! x7 q

; k% e8 i! Z2 j0 N" eEn_Tx
4 z5 @# s+ U# g2 A* ]# A& q

3 O& B# g3 k1 k8 F+ r1- K  H& Q/ T# D7 A& X6 [: A5 X
7 R6 v0 j& |$ e  \
串口发送使能寄存器$ C4 ]* G1 ?9 k" w# r, f

$ L6 s, P& g5 Y7 {0x05
4 b# @- E  M& R. s: X. |7 T
+ x/ h8 Q6 @# k. d" u
reg_Baud_Set: J' d9 B  H/ ]; B, Q2 ^

" H6 W! h0 y' P2
# `: g8 P- V* U% r0 z7 c) f' y

3 s: l: L, e& L9 }: N% c串口发送波特率设置寄存器
% n4 p; i( }8 L

! A, Z1 s" K& }3 S7 v* u# W0x066 V- R6 I* z7 Y9 k
8 L9 q, D; u# L, ]# A
DDS_En
" l) V/ [' a0 J7 l9 ]
: Y7 I3 L) x8 j; f
1$ j: R' N% ], a; Z
5 F& n4 l) G' N; b# n
DDS使能寄存器
, L: w2 E, l9 ~
+ w0 N% {7 K8 }% Y
0x07+ l5 p( r0 s* k% k8 Y" `6 B( w% e# g& _7 `

; o; E# Q9 M  L5 n4 Y6 M  `reg_Fword_H
8 h0 W7 ?1 a7 N
6 @1 _6 u8 v3 R# v' l3 k" H" {- H
16
& A5 c% R0 V8 h" c. h2 k

' {0 y. x% r" H8 {& }2 X, tDDS频率控制字高16) |6 X* }! d' P# W
7 x) p! ~- v" @) S% N3 i' B' B
0x08' {. ?) R6 }( \' `; v& Z% b/ n

# i6 t  U1 n# F# V$ e% f  f3 Yreg_Fword_L
, S3 F0 X) C" w' m' s
8 T3 v2 `; x4 ]) z. w9 v& J  P
16
2 u9 p: G% t9 ]: W( j" r

% r4 X4 [& z( c# |DDS频率控制字低16
( D$ ^$ k3 u9 i( }1 ~  H! V

0 C& f) w0 o3 l" Q; e5 H0x09+ s1 w( ]  U4 |# q3 V

* a) _0 v# N8 p* b# Mreg_Pword
# A5 ?  W+ d8 X# X9 @

" ]0 J3 e4 v# f12  g- m1 C7 x# D! E+ a$ @( ?
2 B- X  G9 B! @- M2 `" Z
DDS相位控制字' O, l  z3 G8 G& z

7 D: H% H5 P: R( [& ]. e. s, d0x0a$ \6 {- W* `. E5 `
8 n  V  V. c0 H% M/ i+ j
DDS_Sample_Cnt_Max_L. j+ f7 i% H% L7 U, m6 M

  ~; Q# k% h( P# h$ v161 q7 d% \  Y) v
: j( s2 [' ^6 {
DDS采样率设置分频计数器计数最大值的低16
$ n9 J$ n' n1 L# P* s: ~  G7 w
6 n# E5 \" h% n. F; l5 l; b/ h1 _
0x0b! U+ |% n/ }( K/ I4 U4 }5 T
7 R, i5 b* o! ]+ @
DDS_Sample_Cnt_Max_H4 O  c/ }( F! h( P# j# ?) ~

! Z' i  s8 E$ E7 B6 n9 `: s163 _, z% j7 H5 C/ J% x
& \6 s. Q6 |* S2 {8 C
DDS采样率设置分频计数器计数最大值的高16
' k" }7 ?3 V! ~: p

4 X" {& x- G( u  l- M0x0c5 \9 Q: S8 ^2 w

+ s: N7 D* G' D" lDDS_Sample_En" n$ m2 o* T7 `; i) c1 @1 f* v
. c  U; b* W' ~7 ?9 {
1
% u9 J& H: c8 G5 G0 A6 I

8 V8 R8 e1 ?% U; |1 R1 WDDS采样使能寄存器4 |; z! _: l7 n7 j3 x
8 d7 q) I9 \0 [( I) x) o  A

# i+ r6 A! i. g
$ G0 s# Z) ]0 ~: G& {: E- c指令使用说明:
2 Y8 ~" C8 k3 N2 Z( q/ X2 n' b9 g* y0 i8 p0 q$ p! [" g6 Z2 L2 A

6 `7 \7 N$ R4 M' f, }7 B1 }3 y
. o+ p8 r4 i) p! R6 B; c, |" j& Q  _( W
操作
4 |  _2 e+ }4 H) A0 g( n' O
/ ?" @5 t7 X2 O" I) M/ |1 c
指令1 g$ j6 m  x+ x0 S4 L
. {6 U* N7 P; m3 \* w5 e
使能DDS生成数据# D9 N% b# _- Z. a" ]6 Z

4 h1 w8 w+ R* w. J6 s, e* W) WAA 03 06 00 01 88
) W  ?# Z' _0 r5 s7 O* p/ a4 L
, s2 [/ H+ f3 J
停止DDS生成数据
; k* h( O' K, e& u0 p- }* C
% n, E+ g9 s, h, p" G: m
AA 03 06 00 00 88
3 `% q% Y; ?3 i; A3 M- e% U$ h2 ?

. v6 n& ~; D* u4 q8 E使能采样DDS数据
- |6 X  e/ Q' V# Y: q
+ l. A9 T; m* u4 O
AA 03 0C 00 01 88  |6 l/ m# ^/ E* s1 F1 s5 y  ^3 V

! {) Z' b1 y" G: ~6 C0 Z: a  \停止采样DDS数据
9 R' J: e4 d4 y

* Q2 G1 T8 e7 T2 t9 |; r, VAA 03 0C 00 00 88. P( m  o' ^7 A0 G' X6 w" z

3 `$ V' O: p5 f+ l8 T- p+ m使能串口发送
1 u7 t/ _1 f( @; c# ?: f4 `
5 U% m: }3 u+ y. V$ |
AA 03 04 00 01 88! Z$ T' B: X. n; ^; L- l/ T2 \6 ^

0 C) l; g/ j4 m# \; ?3 ?停止串口发送, h7 ~# J( n: f+ _( q
" }: M( d' h7 Z
AA 03 04 00 00 88
6 V" r" {7 u& m1 [4 C
: H9 P; L/ \6 K! j. f& X" s/ t
使能ADC采样8 c: o, R. P2 x! ?) y( x7 O

+ O" ^+ C- e7 j  fAA 03 03 00 01 88
7 `8 O! d4 ]- d+ M- z5 h

& M$ S$ ?% m( s; c8 R停止ADC采样* \, N5 M4 n# X, l8 X9 f
% E- {5 j9 z8 P; @
AA 03 03 00 00 88
/ N( ^' ~# K1 H; O  A' W' R' d

9 x$ ^7 T8 ~1 X3 A; R" p  bDDS频率控制字高16
9 h( |$ P* I; @* j1 O; ?  K
2 Y9 H- w( s3 x- `8 q0 W/ {* M
AA 03 07 XX XX 88
' ^" `4 ]: Q. O9 @0 u- N! I

$ N" D0 ?9 u2 ?- q  B5 l$ N. uDDS频率控制字161 r3 `. ?3 ?+ z. q) y& L9 w
7 @, B* R* R7 u; M: z) D  g
AA 03 08 XX XX 88
/ B, [: ^9 X$ [2 w* `: F. Z) _: Q* t- x  z; u0 Y
XX_XX_XX_XX = 232*Fout/50_000_000: h9 Z" B7 g+ ?# P4 S3 w

# X) [  m: ]9 K# E5 D3 K! V: y! i( q' t  j$ f

$ ?- w4 R/ k  EDDS相位控制字
# n! i0 W6 L1 N  h

( [3 i0 M3 d& l8 E( T8 [% qAA 03 09 0X XX 88
8 r4 ]8 w) d0 C  |/ |. k( {. O

, E5 h" ], u# a/ q9 y5 n采样DDS输出数据的采样速率控制高16
9 M' ^% N) q# X; m

4 C$ N/ Y1 R/ T: U' ?+ rAA 03 0B XX XX 88( t! w/ q5 K9 J$ g
2 k, _/ p# ^7 F! `: b
采样DDS输出数据的采样速率控制16: S+ V7 J2 g0 F

, ]0 n1 n- R0 Y% F. ^AA 03 0A XX XX 88
2 U& z: X- b/ m+ e. l6 s
# y. e1 b+ T8 S( GXX_XX_XX_XX = 50_000_000/Fs - 1
0 D8 L) @! _4 S  |/ k& Q& ]
" f" a, x# l  G0 i+ u* {8 |; X6 k2 z+ l5 N" i9 p

. N! B- N- n# N" _8 z. q' |ADC采样速率控制高16  d- {$ ^% d7 K

" M  a) p8 P& {- Z# J. IAA 03 02 XX XX 888 |3 D8 q* ~& M( g  ]$ A
& Q! L; [# i# c! O+ |
ADC采样速率控制16
8 G( X6 i1 L6 O- ?" }8 {. ^
9 V; \, S. g3 y/ Z6 r/ |
AA 03 01 XX XX 88% C+ e3 r7 G4 j0 f) S6 y0 v
8 G4 r- K8 W( [7 j7 q
XX_XX_XX_XX = 50_000_000/Fs - 1
5 n% F- E7 y% z0 X0 y2 Y' I. v6 ^. P3 C- P# H! L: T) u

" z  X! `( Z. j) {# f4 }! A
; V! w/ F/ {1 l; D  o8 \/ k9 q; `0 _
设置串口波特率
+ A6 e3 N* A- r0 Z
! B* Q) i5 q& e. e& p. k
AA 03 05 00 0X 887 ?' k% U; C: \/ I. |% T+ D

" J) s( p' o/ {1 BX=5 i$ a: r  G8 ]) \2 Y6 C

. N0 I: _6 E5 K4’d0:9600bps;4 J0 K2 O% C% i; E2 q/ z

8 d3 i" O. h( Y' ]* ^2 q) i4’d1:19200bps;
! o  {( u! u+ v$ o  v/ i) x$ }* q/ N8 O# Y  l7 f
4’d2:38400bps;5 _& E. g, r; n, ]" n& `

1 `' i3 v* g4 [0 R( `7 T4’d3:57600bps;, i! t$ T# B0 c4 F

* B, @$ m- r* T  Z4 ?8 `4’d4:115200bps;
) c9 u( j# c8 K% }' r& E* g( G' A0 G; E2 Z. }! D' B/ I
4’d5:230400bps;1 Q- V9 y' o9 \+ h
( b5 y; n) Z- @. ?( r0 U" _
4’d6:460800bps;
- @9 F* G' ~9 h
; ]; r; T/ ?5 W; B4 C6 F% p2 r4’d7:921600bps;. c6 }$ r* ?/ p( X- Z* J9 C
+ Z( `( w" Z2 n

8 W# U! G8 h6 |4 P例如,系统在上电后,各个模块默认是没有工作的,要想在上位机上看到数据,就必须先通过上位机发送控制命令。因为系统上电后默认选择的数据通道为DDS生成的数据,为了最快的方式串口猎人上看到波形,一种可的控制顺序如下所示:
4 r7 u2 O2 D" J- @7 C- W使能DDS生成数据AA 03 06 00 01 88> 使能采样DDS数据AA 03 0C 00 01 88>使能串口发送数据AA 03 04 00 01 88; B2 ]9 Q2 r" M7 D( T+ _# V
这里,为了演示方便,因此在系统中对数据采样速率和DDS生成的信号的频率初始值都做了设置,因此不设置采样率和输出频率控制字这几个寄存器也能串口猎人上接收到数据。
- G: P% n* C, p( [, l+ B经过此操作后,串口猎人的接收窗口中就会不断的接收到数据当然,这离我们最终显示波形还有一段距离,这部分内容我将放到文档最后,以一次具体的使用为例,来step by step的介绍给大家。0 e! s, C  T+ e( u7 T0 U- O3 t' B

6 q; t7 w2 B! w1 K) a- V9 u  B
& Y! z* l6 }8 r) Z, B4 n关于Memory Mapped 总线如何实现各模块寄存器的配置,这里小梅哥以ADC采样控制模块Sample_Ctrl三个寄存器的配置来进行介绍Sample_Ctrl三个寄存器的定义配置代码如下所示:
6 r& m! e; K: p  f% w; t' w

% i* i& R( y" `* V7 A4 Q2 H14      reg [15:0]ADC_Sample_Cnt_Max_L;/*采样分频计数器计数最大值的低16位,ADDR = 8'd1*/
# d$ N; u; F* h0 r7 x6 W  I- ?
% h! r$ @8 c" D6 A15      reg [15:0]ADC_Sample_Cnt_Max_H;/*采样分频计数器计数最大值的高16位,ADDR = 8'd2*/
$ o# u5 e' K* A2 h1 e
3 G# k4 @5 Y, C' Y7 \16      reg ADC_Sample_En;/*采样使能寄存器,ADDR = 8'd3*/
; q% ]$ H2 k$ Y+ a( @" h( M) T9 X3 u2 ~5 }. _) t0 U) U. K, R
17  t3 x8 H$ o3 |6 h- t( q( e  v

! n% P- S: @6 }+ [* }% l9 z5 F18  /*-------设置采样分频计数器计数最大值---------*/  5 F) V! G8 [& q7 f6 P

4 O8 N& B, }9 J  Y  |% j19      always@(posedge Clk or negedge Rst_n)/ Q' v' E5 w# `& p
& x* H2 S7 m( {9 P" I' V
20      if(!Rst_n)begin
; _8 n! r" `0 ~* l1 X7 J- R/ B
; g- i% B4 G* |: w, w3 t21          ADC_Sample_Cnt_Max_H <= 16'd0;
& g* K9 H2 \1 z1 O1 L$ H: G* C4 a
% S' y3 I, N/ m' W) \22          ADC_Sample_Cnt_Max_L <= 16'd49999;/*默认设置采样率为1K*/; U2 @- G! f5 U0 j6 F4 C

/ D; Y8 e' _8 k23      end8 E. @( p! E/ m3 E. V

! l* r* H" L# M' Y24      else if(m_wr && (m_addr == `ADC_S_Cnt_Max_L))//写采样分频计数器计数最大值的低16
+ l. f  C! c: a6 V, B+ L  [4 R- x6 u3 S, N7 n: @6 n% x
25          ADC_Sample_Cnt_Max_L <= m_wrdata;, l% r9 D' y4 P. p
1 V- @) k& W/ W8 M
26      else if(m_wr && (m_addr == `ADC_S_Cnt_Max_H))//写采样分频计数器计数最大值的高16
4 \% o- m* L) M6 X4 x  \5 m/ A
: U! V7 p2 W* Y- T6 k27          ADC_Sample_Cnt_Max_H <= m_wrdata;$ k2 B' A9 v7 q/ @. M

2 ^/ o3 Y3 L2 v) K: j' l) v28      else begin- a/ E( x) w; r. ?+ \3 N
. x" j* M, B. m; \0 K4 m
29          ADC_Sample_Cnt_Max_H <= ADC_Sample_Cnt_Max_H;5 c4 C0 o( k, P/ u
! [, W9 L* u! J2 k0 e9 h  r; l
30          ADC_Sample_Cnt_Max_L <= ADC_Sample_Cnt_Max_L;
; D% |9 B7 {7 n3 d
& Y- R3 ]/ q# G31      end
3 {. z5 ]$ B2 l, V/ O
& g3 v/ c8 R5 I32      9 ]  ~4 P2 P4 I$ L7 h
8 s1 k1 V- w( r8 p! d+ T) t
33  /*---------写采样使能寄存器-------------*/
! F5 I# n* ?7 M7 b: S( p% t+ t4 w8 y- k
34      always@(posedge Clk or negedge Rst_n)5 Q8 T1 I8 e% P6 o1 l' J: a
* Y; z& ~( |9 g' U( T0 k
35      if(!Rst_n)
( t: Q, ]8 K. j8 {  ^4 J+ R7 {7 w7 p
! h6 e3 l, e5 c7 k36          ADC_Sample_En <= 1'b0;
9 l9 g7 d3 |9 X" j9 y6 ^( ]
" h7 j8 T- Y4 Y& t) k37      else if(m_wr && (m_addr == `ADC_Sample_En))
! C) k4 A/ o4 R8 G* `# B/ h8 l
: J7 y9 k* z( v/ {% P- M4 w# t38          ADC_Sample_En <= m_wrdata[0];
9 U# X7 Y6 g) ]- @
" L3 G7 c/ c2 ?& I2 _39      else6 v1 `. b+ d' _9 e1 v' j9 f
6 L' z2 C+ p; m& F6 N# L
40          ADC_Sample_En <= ADC_Sample_En;$ _8 n1 `- f; |7 w; m# Y
$ K' T% ]# X6 O8 Z5 z7 a4 W
+ C4 r8 k9 [' l  t
9 S6 h( z, B- X* A2 M
8 t2 L6 }: k! |4 ^
采样率的控制采用定时器的方式实现。使用一个计数器持续对系统时钟进行计数一旦计数满设定时间,则产生一个时钟周期的高脉冲信号,作为ADC采样使能信号。这里,系统时钟周期20ns,因此如果要实现采样1K采样率(采样周期为1ms),则需系统时钟计数50000次;若实现20K的采样率(采样周期为50us则需要对系统时钟计数2500以此类推,可知改变采样率的实质就是改变计数器计数最大值,因此,我们要改变采样速率,也只需要改变采样率控制计数器的计数最大值即可所以这里,我们设计了两个16的寄存器,分别存储采样率控制计数器计数最大16161415所示。我们需要修改ADC的采样率时,直接通过串口发指令,修改这两个寄存器中的内容即可。2 i: z' m7 a  S1 [  V
3 n/ R: @( p5 t: V
' ]! o6 m8 j. e5 ?$ M
这里小梅哥使用自己设计的一个山寨版Memory Mapped 总线来配置各个寄存器,该总线包含三组信号,分别为* v3 j* o- z) G

1 A: S$ [+ B* R) D使能信号m_wr3 j! a, _" b, n! s* u; b# W
. n. v# E# Q% |! f" z
地址信号:m_addr3 N% F# F+ m% O/ n" D3 Y7 t
' [  N' c& l. D# F+ U0 v* U" Y  i3 [
数据信号:m_wrdata
- i0 R5 S% l) ]1 ?% y  F- W( I, Z那么,这三组信号如何配合工作的呢?我们配置ADC_Sample_Cnt_Max_HADC_Sample_Cnt_Max_L这两个寄存器来进行介绍这里再贴上这部分代码:4 K! z: t9 x; ~& S, C

& G2 ~& e2 `9 |9 v3 h8 f( x$ Y18  /*-------设置采样分频计数器计数最大值---------*/  
$ g- e! r. X. U
! j4 j: m& D, O! P19      always@(posedge Clk or negedge Rst_n)
- d9 V& p$ r1 C3 `5 \- n2 e  y, x1 m  E
20      if(!Rst_n)begin
, F& [( e9 |( P) U6 |' q$ l, s1 o/ Q/ a, U1 p
21          ADC_Sample_Cnt_Max_H <= 16'd0;
4 v8 O: Y) G% J8 T+ e- a: s. T7 O7 Y2 Y( R' j  Q' E% f1 i. ~
22          ADC_Sample_Cnt_Max_L <= 16'd49999;/*默认设置采样率为1K*/
' [' G6 I' u: x1 N# K+ q; t3 q# d7 D  l% e4 v: J
23      end
: J0 t! Z# _. M" t: h, i# q5 D8 l4 _) g3 _1 W
24      else if(m_wr && (m_addr == `ADC_S_Cnt_Max_L))//写采样分频计数器计数最大值的低16- @0 J* w1 o5 u

' p4 J' G! d3 Y- @* k& P$ I$ m25          ADC_Sample_Cnt_Max_L <= m_wrdata;
7 J7 V* \7 F. X% E, @  }0 `) z
: R  u0 L% q9 p26      else if(m_wr && (m_addr == `ADC_S_Cnt_Max_H))//写采样分频计数器计数最大值的高16
8 ^! M/ A0 w2 w/ ]5 g- j- O0 N. }) A- |) N2 {( A. E/ [
27          ADC_Sample_Cnt_Max_H <= m_wrdata;+ E1 f# ?5 U  X/ \2 V( t- {' T, j
# U$ m; T  O. ?+ a+ Q: R
28      else begin
/ @4 i% B5 k1 s; O4 k3 D" E
6 G# _' [" U1 N8 t29          ADC_Sample_Cnt_Max_H <= ADC_Sample_Cnt_Max_H;3 h& g9 F3 F7 G9 n0 r5 _
1 H  j  |' N& o0 A
30          ADC_Sample_Cnt_Max_L <= ADC_Sample_Cnt_Max_L;0 ~# k5 L4 p# h; o/ o" w

/ {' h; T  \3 k5 i! S  A- Q! Y31      end
! c$ C" k* o) P4 _  u3 l2 k+ \( T; i5 q3 k2 m
" S. J8 `9 n& N& }7 E

) R* a% o. {: c3 H; w2 Z复位时,让{ ADC_Sample_Cnt_Max_HADC_Sample_Cnt_Max_L }49999,即设置默认采样率为1K每当m_wr高且m_addr等于ADC_Sample_Cnt_Max_H寄存器的地址时,就m_wrdata数据更新到ADC_Sample_Cnt_Max_H寄存器中,同理,若m_wr高且m_addr等于ADC_Sample_Cnt_Max_L寄存器的地址时,就m_wrdata数据更新到ADC_Sample_Cnt_Max_L寄存器。其他寄存器的配置原理此相同,因此不再做阐述,相信大家举一反三便可理解了。
- y5 e3 n. f4 Q! P; ^- D" Z7 m* w; K  Z8 @8 e1 e7 `
小梅哥

1 r4 O( H4 @+ ?, m% S6 r. Z0 `, G4 o" a+ {
201548 于至芯科技

该用户从未签到

2#
发表于 2019-4-18 17:26 | 只看该作者
thanks for sharing
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

推荐内容上一条 /1 下一条

EDA365公众号

关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

GMT+8, 2025-8-1 05:33 , Processed in 0.171875 second(s), 23 queries , Gzip On.

深圳市墨知创新科技有限公司

地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

快速回复 返回顶部 返回列表