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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

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

9 v0 p: n9 y) B: V+ }9 o! _: k) w 3 n# X: }8 b  ~# f6 l8 q- E
( B9 `1 p7 e0 h8 Q
串口memory mapped 总线与配置系统子模块寄存器代码分析; j0 u8 w& {+ \. H0 V1 L7 H$ H! Q
CMD
( g) v: g' K+ ^, j1 o
CMD模块为串口数据帧接收与解析模块,该模块负责串口接收到的每一的数据进行解码判断,从数据帧中提取出地址字节和数据字节最后地址字节和数据字节转换为类似于Avalon-MM形式的总线以实现对其它模块的控制寄存器的读写,从而实现通过串口控制FPGA各个模块工作目的+ [  P# a. H+ b1 q
在工业应用中,串口指令大多以数据帧的格式出现,包含帧头、帧长、帧命令、帧内容校验和以及帧尾不会只是单纯的传输数据这个实验小梅哥也使用了数据帧的形式来通过上位机向FPGA发送命令,不过这里我使用的帧格式非常简单格式以帧头、帧长、帧内容以及帧尾组成,忽略了校验部分内容,帧头、帧长以及帧尾内容都是固定的,不固定只是帧内容,以下为小梅哥设计中一帧数据的格式:
: ~5 H: k% A) M5 }% |5 Z; L- ]- ~8 v& G9 `% t/ G" J

2 L8 `8 A+ `  _) A
" _; i& t( x3 i# {: q( w
帧头
4 L/ z$ v% M8 }- j/ Y4 p' Z% V+ j3 a

$ J: [: D. ?* R% Y帧长
3 g* ?# G" f+ I$ B0 g% A

1 v  D( U' X% d; _2 d0 U. a地址6 v' R$ r4 F2 _7 }+ S

) U: F' u4 i) k" h, R* e数据
0 m4 i$ X  I# U* l7 P

9 ^9 N1 `1 A+ T, z- f数据' v/ s" [; q1 J

+ w; X" r1 E( D$ @  H& R; E3 c+ L# U) D& M' r

- f& H: ?4 D% p9 q( e0xAA
7 `5 p3 H- n, T" g6 F/ b' l: o# J* u

, Y: R# x3 u, P6 K6 g0x03! a4 u. d" B. ^7 R& n6 }6 _

$ ?0 ?! B8 l: {6 s0xXX
" x6 w1 D1 F3 c/ T* q4 [. J) F2 v

" f$ ~/ v  H; j: O$ w: X0xXX
" w+ p/ P$ N$ m) X
% ]4 ?1 R# @+ w& Z* L0 b% Y+ T" F: x
0xXX
2 T' [; G- \9 \' p  v4 Y
& ^) Y/ _8 B/ U' r6 H8 _4 t9 P. k
0x88% F$ _& r9 d( K2 G5 m- |
由于数据帧本身结构简单,因此数据帧的解析过程也相对简洁,以下为小梅哥的数据帧解析状态机设计该状态机分为帧头解析、帧长解析、数据接收以及帧尾解析。默认时,状态机处于帧头解析状态,一旦出现帧头数据,则跳转到帧长接收状态,若下一个字节为帧长数据(这里严格意义上并不能算作帧长,因为长度固定,充其量只能算作帧头,读者不须过分纠结),则开始连续接收三个字节的数据,若非指定的帧长内容,则表明这是无关传输,状态机将返回到帧头解析状态继续等待新的数据帧到来。帧尾解析状态若解析到的数据并非指定的尾数据,表明此次数据帧非有效帧,则将此帧已解析到的数据舍弃若为尾数据,则解析成功,产生命令有效标志信号(CMD_ValidMemory Mapped 总线进程在检测到此命令有效信号后,产生外设寄存器操作。3 ]8 ~8 w& Y7 J  N/ b% i, p; [2 S

: Z0 R$ I) z+ T. h % S4 v3 K8 R* J1 |
. |' {0 }4 W( r$ R
命令解析的状态机实现代码如下所示:
/ N- R  y3 J1 V3 E# I' E5 V& ^( \

1 K! n, k! v  d; E9 g, e3 w% G017     localparam
1 T2 x# u) U3 M8 B1 y% l% U7 X0 W" `: H, ^  I: w
018         Header = 8'hAA, /*帧头*/
& `; Y  W6 i# |9 s3 E; C
% P! ]0 h8 f) f019         Length = 8'd3,      /*帧长*/
6 x0 u& \' a+ b' E  P
- ]3 t' h. F8 Z' e' V$ ~3 _2 A* b020         Tail   = 8'h88; /*帧尾*/5 p% E8 r6 h, K, }/ V4 p
& O# E4 E. j8 N3 y
021( |4 j! a" e3 C" v

# d6 C: ^. a- Y' Y, O+ J8 N  o# d022 /*----------状态定义-----------------*/     
- B0 G% S' t. y* S! I# u) E5 s, E3 O9 d& C; C
023     localparam
! K% Q3 R7 v" A% u% f2 c
7 g: ^+ K9 s- |8 o7 Z: g) r- _0 q024         CMD_HEADER = 6'b00_0001,
* F- c4 Q/ z3 e$ e% Q+ H. Q7 c$ @( |9 V0 L) H
025         CMD_LENGTH = 6'b00_0010,. \# t& d' O: w, H( T' D1 @
( e/ y% V: ?& t7 \) C  _: f! U
026         CMD_DATAA  = 6'b00_0100,( w/ V* {9 Q6 ]# e. ^
2 Y4 Z, j+ u( [  F
027         CMD_DATAB  = 6'b00_1000,1 Y& E! u7 p9 h8 T5 S( L1 [
" J9 W5 `( z9 l# v
028         CMD_DATAC  = 6'b01_0000,# `* V) F$ ?- G8 [
9 B3 A( _7 o2 g  \( k" e
029         CMD_TAIL   = 6'b10_0000;
. c3 e9 A9 f$ U% A0 J/ Q- R
$ j. n. k& Q4 s. P/ J7 V# X030     
5 ?$ R2 i! s! `6 Q6 w1 ~, u' e+ C1 s+ C; r. M8 q% t. t3 T  I6 O- ?
031     
: G9 Z4 |* m) m+ C
$ h: J4 B& b  b1 O0 G3 i2 w8 N032     always@(posedge Clk or negedge Rst_n). \: O3 c( t0 ~

, m9 I7 n5 ~/ I6 O2 M( L2 n033     if(!Rst_n)begin1 l+ @/ e, W: ~/ ?5 S

% k5 v3 u1 l7 a9 K# f! M5 a3 d9 \3 v034         reg_CMD_DATA <= 24'd0;
0 y/ I  b& x" _4 S5 h" y* D* K4 M! ~2 A
035         CMD_Valid <= 1'b0;4 w3 x$ Z1 D5 x& s
- B* b+ s" B7 P3 O1 U0 J
036         state <= CMD_HEADER;
; K, a* J# I! f/ b( L* ?
8 ]7 ^- \6 o* \' C& f' J037     end
. U$ j4 j5 i- u3 i# V: [% j! f6 l* Q
038     else if(Rx_Int)begin
1 t4 ~3 G* W3 t. \& N8 k8 B6 Z7 B+ e8 R
039         case(state)
( c4 d2 A( n6 T/ _+ b5 t
# Q2 J5 g( Y9 h( Z, C8 A4 M+ r040             CMD_HEADER: /*解码帧头数据*/- F# |* B4 {; Y% [, K. R

2 @+ j5 G) }7 H- g* z' B041                 if(Rx_Byte == Header)
; \- M0 ^- s6 X* z
: c2 j5 Q9 x' P042                     state <= CMD_LENGTH;9 Q  w( t. j" H+ R* p1 S

6 e4 g3 e! |8 V9 _043                 else! Q0 {4 @0 e! Z7 _: `8 w
( K) u. N- f0 {6 T5 }, r
044                     state <= CMD_HEADER;
* T$ M) o; T9 L+ O; f
( \) \) z% O, }1 t4 }045            
) t, t* t3 ?$ `" {9 ~
6 @" Q4 G+ e- y6 a046             CMD_LENGTH: /*解码帧长数据*/
* o1 F& Q% w$ H$ {0 ?: @
! D3 ]' p1 U: W- c% h9 t# F+ D047                 if(Rx_Byte == Length)$ @$ I* H6 ?/ Q3 _7 F
% S$ D' L4 ~' |: y& \& r
048                     state <= CMD_DATAA;: Y6 M$ z2 z; x

' C) m$ H& O8 Y7 }, T/ X049                 else6 b  d1 V* e- V" V

! v& [! {1 l  p+ t) S4 n050                     state <= CMD_HEADER;
$ ^, q+ V8 e% M+ Z8 R4 [2 P2 h, B
051             " Z. J5 ?) U6 g" V& `' I7 U) F0 s

+ T, F0 |6 S; t% p$ \9 C052             CMD_DATAA:  /*解码数据A*/7 E* z5 X. ^2 ]+ n
8 ]" {6 Q& i6 _. j# d( a5 Q& z
053                 begin
$ f& z, T' o7 H7 t/ T$ W* [5 @. n% a9 M% c' G+ O8 B
054                     reg_CMD_DATA[23:16] <= Rx_Byte;
& P: g& X* \, j; Z7 J, `
6 j& m; R! Q4 N8 ^& Q4 }$ [055                     state <= CMD_DATAB;
2 s' h4 k1 `/ B" L# N; ~2 X4 a. v4 c+ K8 Q& G
056                 end. v+ m! d2 |$ n0 G* W

* M- u$ ]0 x5 z& V) P057                 - ]* o' Q5 F8 `% n: C; C
. ?. I" A# j% q0 C$ n  ^: M
058             CMD_DATAB:  /*解码数据B*/
7 }3 I& o- T8 K( p8 x% a' i0 T+ _
+ G" o; ]9 q. Z- F4 f059                 begin% P  O" U# N: z" ^

- A& I7 A- n$ f$ p; x8 M& l4 H060                     reg_CMD_DATA[15:8] <= Rx_Byte;3 Q4 \) W/ ?/ l) s) a1 h% t

, O( X/ E2 g# G& b) K+ w; X$ q% X061                     state <= CMD_DATAC;             . J5 `3 n! t# Y6 X- Y

2 S. {$ \: |# C9 j062                 end- J  }& e. g- y9 I3 R) L

3 A4 V# r5 V- ^6 v3 ]063                 
/ a" G* G+ i$ p9 c# L# q$ V- e( H. g( I+ |$ ~# k( d' y
064             CMD_DATAC:  /*解码数据C*/
- d! N7 ?( s+ K, ~8 Y
- `! {- L: {4 r065                 begin" y4 \% v- E! w" v1 q

; H0 n0 h$ e2 M$ l  A$ t066                     reg_CMD_DATA[7:0] <= Rx_Byte;
$ X2 g! U+ Q- g2 |( w2 d4 J" q+ K4 y8 q! m, {) P' S
067                     state <= CMD_TAIL;              / G9 r) Q) W' Z& z
% U. b2 U5 W4 n$ C5 a6 K$ Z
068                 end9 Y' U  l  v; v  w' w( h4 T% t+ z
" y: U5 B9 G( T7 S& @. P
069' I% z$ ]$ G) Q1 t5 o

" b* G2 A6 W; f3 ~. m  `' t9 K: q+ O070             CMD_TAIL:   /*解码帧尾数据*/- j: B' s" [8 O% ?! L

) s. h5 Z) l" ~; I# _071                 if(Rx_Byte == Tail)begin
# `+ o+ y( x8 n1 R, X; W; s% l1 f7 a$ Y! K- d8 `# G" t( s
072                     CMD_Valid <= 1'b1;  /*解码成功,发送解码数据有效标志*/  _! |0 d1 m' f* w, E  M

8 I$ ?8 V/ h. L' `, ^073                     state <= CMD_HEADER;: R: @+ c8 F  J  [. e( W

* Y1 U$ L% @1 e' o! Z074                 end. p) e2 d/ J. F' l3 ^1 }0 u
% @5 i) e0 o$ p; b$ v' C4 J" J
075                 else begin
6 {) F; ~. u* `8 o+ E; s0 x- ^$ F: k. x/ G$ D) ~) ]  ~( O
076                     CMD_Valid <= 1'b0;# a, C6 J: Z" j8 Z7 U* }7 |- t8 `  T: Z

3 |9 @: _7 h1 Y077                     state <= CMD_HEADER;, M+ W: o3 U6 a' |4 i7 b7 G& C  y
# E: C$ e# O9 q$ G# |! C4 Q
078                 end
0 l- g0 k: E+ Z! Z! \) z
' g4 f9 P$ b' j7 q6 }2 {079             default:;. w3 Q6 p9 G1 G, D# Y, T
5 A3 C+ T# A  Q% M* n
080         endcase + z0 d  S/ R- H, Z' G" Q
$ B; Q+ }' ~& k* G
081     end
* l" a/ O: x# r: F/ [- K# }& w1 _' O5 Y9 o6 a; K1 J8 n) {
082     else begin5 N9 n1 Q. Q9 j- c& r3 e6 P: W
/ D/ j2 M  E9 I3 ?1 c* o( U
083         CMD_Valid <= 1'b0;
& p4 t' Y& g" A# A& d& P5 \. H; p/ y  T$ `+ n9 G, V' f3 g
084         reg_CMD_DATA <= reg_CMD_DATA;
8 Z9 Y' f5 P8 l) ]) a3 s0 B- n/ T" [* {! h; y5 D8 Q6 B( Q
085     end4 t) G$ _2 U" }
23到第29为状态机编码,这里采用独热码的编码方式状态编码方式有很多种,包括二进制编码、独热码、格雷码等,二进制编码最接近我们的常规思维,但是FPGA内部,其译码电路较为复杂,容易出现竞争冒险,导致使用二进制编码的状态机最高运行速度相对较低独热码的译码电路最简单,因此采用独热码方式编码的状态机运行速度较二进制编码方式很多,但是编码会占用较多的数据位宽格雷码以其独特的编码特性,能够非常完美的解决竞争冒险的问题,使状态机综合出来的电路能够运行在很高的时钟频率,但是格雷码编码较为复杂,尤其对于位宽超过4的格雷码,编码实现二进制编码和独热码编码要复杂的多。这里详细的关于状态机的编码问题,小梅哥不做过多的讨论更加细致的内容,请大家参看夏宇闻老师经典书籍《Verilog数字系统设计教程12相关内容。
( ]- ^4 B0 U( _/ a0 _# D% sMemory Mapped 总线进程根据命令有效标志信号产生外设寄存器操作相关代码如下所示:
# x5 F2 ?1 U4 H* D! V

) ^" }" ]3 h4 ?" G087 /*------驱动总线写外设寄存器--------*/    
/ a6 I/ R; r- F. f  Z- R6 @* f; R% F' q$ f; c
088     always@(posedge Clk or negedge Rst_n): U0 O; ~5 Z& s% a

  U* `( r( U/ M1 \" L* Y089     if(!Rst_n)begin3 O. X7 A7 U( @' _- q9 o5 R
! m8 B3 H0 d$ r1 d+ ]1 Q1 j" A& j
090         m_wr <= 1'b0;: l$ {* p. p- b. I( b" k

; `" Z. t6 p& |: S$ H' R+ x091         m_addr <= 8'd0;
. D0 A' D: F. j% j8 d9 [% p" X
. A8 @/ z/ |* d+ J, O6 N" Z092         m_wrdata <= 16'd0;
% [: r/ x6 A) v( |* R8 z& C) W3 a2 ^' o; l: w6 n. }( ?$ X, v
093     end5 T5 i/ _, I6 D% g. ~9 ?2 v- ]) q: g
6 a, g' u; V! N1 T  e" X
094     else if(CMD_Valid)begin
0 W1 _* t+ y# [4 ?4 V) u8 q- r8 H9 I
095         m_wr <= 1'b1;
+ Z& B% X9 c1 C+ F5 b+ C+ J, g' z8 ^; Z" l, l
096         m_addr <= reg_CMD_DATA[23:16];; j1 Z5 E' f/ {

* s8 B) }/ u/ K/ @  v& y097         m_wrdata <= reg_CMD_DATA[15:0];
% w  I0 {" h( a( r" ]3 s1 {( d9 x3 y) D3 m
098     end
: t. L+ {" G/ ?# Q+ O3 P8 y
, o, Z+ o* |2 F$ }0 z099     else begin. O1 b' g4 V9 W* }

3 B) N6 o. \! ]7 m5 e9 w100         m_wr <= 1'b0;
; I3 z7 k; t1 C& E, O4 C0 i
1 s. `" ~6 \( M+ h% A& n, Z( i4 T101         m_addr <= m_addr;5 \/ @1 k9 _, l& N/ E( Y% P  Y# h* |

5 @% X/ }: r5 ~0 c5 g102         m_wrdata <= m_wrdata;   ( K; \6 K/ X. k/ `/ o
/ n' z) i8 D0 u% G0 [8 K+ B4 l
103     end
. @! a; L- c+ O$ I! x
6 R& @$ A( l; c
5 z2 Z. w9 d/ w/ M$ h5 I8 G
& z' @7 W5 B. u
. Q6 S' f5 Q" j% p. Y  `
- T1 y5 [4 ~3 Q% K( F" \5 ?

% a& T  h: K- h( c8 y本系统中,需要通过该Memory Mapped 总线配置的寄存器总共有12分别位于ADC采样速率控制模块(Sample_Ctrl)、串口发送控制模块(UART_Tx_Ctrl直接数字频率合成信号发生器模块(DDS,各寄存器地址分配及物理意义如下所示. O# T* v3 n  |* M- b) Z
/ Y8 C( u9 f* I
地址" ~( Q7 d2 k  |" i. |

0 N6 Y- c( k% g0 H# M( }0 J8 L寄存器名称
) k% p/ w: ^% G/ ?" W, {2 @

7 V  R( V6 D: I+ Q, G寄存器宽度$ h3 F3 E. g+ K5 O( W

. s' [$ }4 n* Q/ Q5 I: k寄存器功能9 o$ ?+ |, [4 {5 j
6 k, k  h* t% Z5 F  A
0x011 t7 ~& D# p' w% C

1 {! T, W, V- z' t7 BADC_Sample_Cnt_Max_L- i' h* g0 i6 Z& b" E
% M7 b9 Z( t: ~+ Y3 J* [2 ]
16
& ?% T3 M7 _, P& I* a

( w! T, k4 L7 s7 I9 k/ ?) ]0 VADC采样率设置分频计数器计数最大值的低162 K* J& s8 z4 `4 u6 U1 `( l
* E& i2 i" n. ?! L/ k+ S
0x023 ?3 K( m+ [; ]2 T* n) |

+ P" m/ [+ n  T/ MADC_Sample_Cnt_Max_H
+ b6 _: W$ |& F
) j: S& z- L7 r" L3 t( [* W+ Q
16, n6 z. s& q+ f- [6 W- f- _3 i
" n) p3 Q% |4 j$ y. ^
ADC采样率设置分频计数器计数最大值的高16$ {9 e' H. ]$ B

; j/ ~- h2 l" A; \) w9 f0x03
( {+ l/ t1 P8 P( {1 p
  a4 J; Z8 j& f8 R& y* N8 L: ^
ADC_Sample_En
! ?. \( w" D& a4 J3 _; E. m
7 l' \2 V# q; D5 X' C& I" [- a
14 p0 W+ ^  W! R" g$ n# ?
' k1 ^5 N( Q$ C  E
ADC采样使能寄存器
, G$ V. K5 z( l6 d1 X+ s9 w6 I
' y8 M3 ~, L, q" A
0x047 C, C6 y! l: ^; }

7 a' E" v# g3 q7 x# ]5 w; U2 [, R; }En_Tx
. H: Q! e4 m' K4 n7 ^1 }# Y/ p/ l% F
. l1 @' B& \6 t5 o# E8 n
1, o" L$ R$ h0 a: b
8 X  ~5 R) F" X8 K5 t2 _
串口发送使能寄存器* Y6 e! b9 d8 I1 Q9 A

: m% V! r* b# s7 ~. L0x05
/ J$ p& V4 a/ ?8 Y0 v' X
3 i6 X  M9 U+ L7 w4 Y# o) \
reg_Baud_Set
9 h2 _1 d8 X" o& U7 @9 D

1 `( Y4 u. f9 _* S2
; X) r4 _) G5 Q$ `" @; {- y

: i3 r: C+ y9 M0 ]! @$ u串口发送波特率设置寄存器1 x8 w  ]9 l; D1 L$ N1 Y
1 ]! o8 i4 V5 S
0x066 ~' c. G* R8 }1 G1 Z% V+ i
0 Y' f7 n- T: \6 p9 F
DDS_En
, I6 |4 l5 _0 }! `4 O9 m1 l; ]

  n# |, d0 r  M( u9 f1) i) o* \* t& r; @5 V$ a" {: z/ C
! P1 _' n8 f( `' ]
DDS使能寄存器
  J9 y9 X2 g7 @- J# B$ A

( M6 N  c2 F" d5 L0x079 V7 n) C8 n+ _+ L9 d7 `' }

- N7 H0 U  Q5 p1 Areg_Fword_H
6 G& g  j$ Q0 V* o
4 D  s' |+ E( f' ]9 d
16: @8 T: h8 ~5 t" o% g0 \; ^

4 O$ p( z, [& O+ G6 qDDS频率控制字高16- g0 O, L1 \. w) N

8 \, F$ \7 r% U0x084 E" }3 H  K8 p$ F4 y

0 I! g6 ^* _1 i+ }9 Q) H/ Qreg_Fword_L5 S9 \: A2 U. H5 t3 i; d

# P; [, J( K* q2 N16
' Y) R5 h- y6 l4 u* }

2 W  q$ l4 A. b( L5 mDDS频率控制字低16
; G7 r) \1 x# a$ }

1 D0 c5 @1 M8 r) f" d/ f0x09
, o# V" |  n3 j) ~. B

1 w  A2 V" y" _' ?7 [/ breg_Pword
2 S, ?# {) z( q: p
7 @- [+ K# J7 p  S0 i' w$ A, ]8 \
126 h* M% }  w/ H" P( a2 X

3 v8 a6 d' e% P9 }/ T; PDDS相位控制字5 G! @. i& X  N2 H

8 K/ g" Z1 ^; r' F" A& H0x0a
$ b8 ?, @' \2 ~: ^

. e5 J! t: H# E, lDDS_Sample_Cnt_Max_L
4 f) V/ E  l$ v9 m; I, y
6 K! K1 K2 r3 j0 S
16
) l- H$ M* Y" s3 g& W/ J

7 W& _$ ^9 b: `0 gDDS采样率设置分频计数器计数最大值的低16& [! f4 N9 m0 V
0 O" c9 O  I0 C7 R2 B! ^: F: T# e
0x0b6 N* J! t; \- Y
& R/ O. n& R' ?$ O
DDS_Sample_Cnt_Max_H
$ ~& H: \5 f* j2 k! h! z

" s) }0 i; B4 \9 S+ f: H  D4 E( m6 x16
2 x: U4 e- B5 r' Z  x
* b" L5 m5 B# E1 Z  I1 A
DDS采样率设置分频计数器计数最大值的高16
; U3 O* r$ s) l% D

% {: ^1 V0 j( G2 \2 v/ Q: \4 g0x0c5 a' U3 y0 j) V- u0 I

$ e7 G- r2 s3 l2 Y2 g$ X" ?( e, oDDS_Sample_En
# }3 E( u2 d1 T+ w$ Q* ]
' g: n8 T$ }9 v/ f: Q$ b
1
& x+ s" a) S4 q$ R
9 ~$ X& U- _, q/ N5 a" ~. K
DDS采样使能寄存器6 c6 P: t: J6 E3 t

: _4 b- I5 i' S9 L0 P* S) Z8 P1 ^  ^. ?/ m$ i% z3 j: \
4 Y# s% B+ a  [
指令使用说明:
) v9 l8 t( ?8 u2 k$ p+ s( [' f! j. U5 |8 H. }( v9 [6 X8 Q: R, s
* @$ Z4 k. x* Q+ z( P$ r9 K( l

) F* x# }4 B5 s' z" }  r操作
' ^6 }2 p1 s0 `1 |5 g

2 w7 A0 |- ?  i& N2 T2 {指令
& R! B- |$ m% X' @& h) h3 e% u
/ c$ _$ W; x5 w0 y
使能DDS生成数据9 b1 n! m% ~. l4 z& e0 I, l, ~. q

* y& ~' a2 X, b% qAA 03 06 00 01 88/ S  Z0 r$ X5 G4 P! Q

% n6 P% L' z- {停止DDS生成数据" P7 k( z# L$ h6 |9 _" ?) }
. L' w3 q. }6 ]* T; Y( z7 w3 P
AA 03 06 00 00 88* o0 K3 \7 a! T( T4 `% m; [: r

4 X5 ^+ d! C$ @  N& e# V$ b5 O. t使能采样DDS数据1 q/ I( C( [; r$ E

7 q- _& y5 r) I0 @4 S1 qAA 03 0C 00 01 88
4 A  B0 n/ S! u# J* f

5 X" V# a/ A) W停止采样DDS数据  A4 F1 j# n- c- f! x. Q5 L9 h
7 N8 N+ Z! C' a+ ]' z
AA 03 0C 00 00 88
+ x) b2 @; s' s; q1 G

8 I, \; ^/ r! W6 _5 c5 }使能串口发送# H" Q4 t9 P" j4 [' I0 Z: s
& i/ X, u3 y5 J
AA 03 04 00 01 88
; }" ^* R& `5 ~" C) Y

% ^5 D" g) O. \  f) x9 a/ n停止串口发送
; x3 O8 y" H8 n6 Z% s" e
/ n" U( D/ P7 X: F! T
AA 03 04 00 00 886 _+ k7 L' J6 Q) G1 S+ a7 }

& H6 M6 p* A- f  Q7 W# I$ ^使能ADC采样; V1 _  }. E  r" r0 d! |; M0 D$ u
5 P6 J4 {4 Z% ~5 `! t2 k
AA 03 03 00 01 88; k- M+ u$ y9 I, _, [  [" E; B

2 i1 i- m% B; e- I3 F% e5 Z停止ADC采样. W4 j3 u! q3 e6 ^( r2 s

2 X- O: j, q( i! Z+ f0 {8 ?AA 03 03 00 00 88% `- X6 O; `" t; M
6 j% ]1 H9 C; f3 z
DDS频率控制字高162 u" O; W- @6 J8 \3 g

4 H7 h; C4 g/ g/ GAA 03 07 XX XX 88
1 @. _3 k! r' [1 L, P

- N/ P* D# O. l  T& u( C% lDDS频率控制字16) x6 n( R6 G( z, Q! L% Z  [- ]
/ p- M% h8 }; [! l; Q7 I
AA 03 08 XX XX 88
# A+ o! i+ g) V. H, _
3 a; j1 g: q8 L9 b5 N" P& j2 R! a& FXX_XX_XX_XX = 232*Fout/50_000_000; P# K; N9 l( M9 @% `5 l

  W+ ~0 k: ~. j" e
6 w  @- ~1 ]0 l& N# {" ?5 V( B  O
: `5 c' e& P, u  h) k
DDS相位控制字; U* R6 y% \1 z+ \7 T

3 Y+ @! {2 R# p! Q9 z2 B" sAA 03 09 0X XX 88
- j( {, M2 K3 P  o8 j5 U
  Y) n, s+ s$ }( M5 s3 J! k, s
采样DDS输出数据的采样速率控制高16$ T  Y6 ?0 r1 H  r
* Q" N- H- u6 \4 z4 y& k; P
AA 03 0B XX XX 88
. @' ?3 X. r) o; x7 x6 T* Y9 S
% [! v& d/ i; N7 [) M" m
采样DDS输出数据的采样速率控制16
( l3 Q8 {, q6 Y& x
. x; Z3 ~8 r2 i
AA 03 0A XX XX 884 g7 p3 ~& a5 ~3 w& o; R

+ t+ A" f: X/ {. _1 eXX_XX_XX_XX = 50_000_000/Fs - 1+ `! F% C4 j! n+ V

; X1 U2 Z$ A$ O% }7 z# j  G
3 j8 b2 L; G5 I# Q# A6 o5 Q: J

- u% n+ s( e7 DADC采样速率控制高169 I- b2 b6 D1 o5 @( @
( Z. r9 U, x4 E  M
AA 03 02 XX XX 88; s1 v) I* d" {/ F

* m& P7 y9 s# P) xADC采样速率控制16
5 W6 r6 ?& {- G

0 |, a) f' N  H8 e  U9 a2 \, r% gAA 03 01 XX XX 88; b" }0 P+ v* f  Y- `: z

1 \! L+ c. C  k; x* }XX_XX_XX_XX = 50_000_000/Fs - 1& A6 T$ [" \2 E7 B* m

6 i0 \6 M; g, `. @4 ^$ n
3 ~$ y0 b$ ~8 y8 o' S6 O! o

! A( B4 L1 \9 ~* m  m* E设置串口波特率* `- g' d  e. G+ ?

3 V' C/ Y: \6 C. ]+ t9 A2 j1 ?AA 03 05 00 0X 88
% }$ Y/ `. G) s0 }0 i7 z4 `  O7 G* e5 ~1 @
X=
/ H& g3 ]5 |6 B# V: ^. x; \' H. E
6 u8 Q% x6 m& X) d) F' F4’d0:9600bps;/ C# W1 u2 m+ ]6 }1 y$ A; D
+ Y6 C" w; m" E2 ?3 Z2 v- U" K5 L
4’d1:19200bps;
) L3 y! i; h6 S% H+ m- v: i3 p7 K& W( }6 k+ e
4’d2:38400bps;
) f1 Q5 ^& j$ S0 ~3 T! J$ ?" K0 V" f
4’d3:57600bps;
4 `/ ?5 _8 U4 P2 ~
4 C1 D, f6 i1 r5 \  c4’d4:115200bps;8 l1 D% V+ L: z5 {+ a7 \- E7 ]

* [, m' [1 K$ A! @# F- k4’d5:230400bps;! q4 k. g9 F+ ?% p& ^
, E; k0 R% u0 C  @! X! k. j* G+ T
4’d6:460800bps;) |! E+ e; l  _" U& T1 L3 G

5 ]& r/ c( r. x  A4’d7:921600bps;
7 m! j9 W4 e, S) q

8 o2 ~% W( ~3 H5 N5 h" {2 `) K( [/ `) O9 L
例如,系统在上电后,各个模块默认是没有工作的,要想在上位机上看到数据,就必须先通过上位机发送控制命令。因为系统上电后默认选择的数据通道为DDS生成的数据,为了最快的方式串口猎人上看到波形,一种可的控制顺序如下所示:5 {9 j& J6 e- h
使能DDS生成数据AA 03 06 00 01 88> 使能采样DDS数据AA 03 0C 00 01 88>使能串口发送数据AA 03 04 00 01 88& f( Y7 L/ I2 \/ A' o0 y5 k
这里,为了演示方便,因此在系统中对数据采样速率和DDS生成的信号的频率初始值都做了设置,因此不设置采样率和输出频率控制字这几个寄存器也能串口猎人上接收到数据。
7 ~1 S1 g8 E; v9 _7 D4 P经过此操作后,串口猎人的接收窗口中就会不断的接收到数据当然,这离我们最终显示波形还有一段距离,这部分内容我将放到文档最后,以一次具体的使用为例,来step by step的介绍给大家。
5 G; ^6 v! P5 h2 y, P; N9 r& K5 C
, g; e! L4 F: y% ^/ O$ n1 @+ P2 q+ W% E4 D- \& ^8 O9 ^, O
关于Memory Mapped 总线如何实现各模块寄存器的配置,这里小梅哥以ADC采样控制模块Sample_Ctrl三个寄存器的配置来进行介绍Sample_Ctrl三个寄存器的定义配置代码如下所示:( l" @- w! x3 V1 z  `

1 G/ n* L" S# y0 x) A) n+ L, B14      reg [15:0]ADC_Sample_Cnt_Max_L;/*采样分频计数器计数最大值的低16位,ADDR = 8'd1*/
2 c, D% l: F9 i4 H* p) {
4 f' w  j& g! H/ H5 ?( Q0 o7 o15      reg [15:0]ADC_Sample_Cnt_Max_H;/*采样分频计数器计数最大值的高16位,ADDR = 8'd2*/
% e$ U6 {1 [% z
. f- y  l8 |% k$ t. ?# n: b' W16      reg ADC_Sample_En;/*采样使能寄存器,ADDR = 8'd3*/+ K1 s/ Z9 E1 a- q
1 r6 Q4 I0 n/ u, x, q
17
% M. L4 |9 V5 I% p8 [( C4 l
0 s5 f; M9 E" X18  /*-------设置采样分频计数器计数最大值---------*/  1 ~, D* k/ }. o" D

$ m2 \) T  t) w: L6 f% ]  q19      always@(posedge Clk or negedge Rst_n), U& p7 w4 I. C6 |

6 r) z* p8 K9 \: y6 U+ J3 C" B20      if(!Rst_n)begin
% h" R; p: f$ ?- d0 u* X/ e% R0 v9 t5 P0 K2 a/ T" r8 V& P/ G- N
21          ADC_Sample_Cnt_Max_H <= 16'd0;
; Y+ t- h0 \- C/ \9 q# M& M) X% a4 Z" z8 V
22          ADC_Sample_Cnt_Max_L <= 16'd49999;/*默认设置采样率为1K*/
8 v4 N6 g! V3 U3 G, c  |1 E& g
, `& i! {; t5 Z" t23      end/ G3 y) Z/ r9 N

  ^7 N# W: l. T2 M24      else if(m_wr && (m_addr == `ADC_S_Cnt_Max_L))//写采样分频计数器计数最大值的低16
4 k* U, p1 G1 o2 x& v+ s# D# w, |5 h
25          ADC_Sample_Cnt_Max_L <= m_wrdata;
3 h. |0 y# J2 y9 `# R8 k; P( s2 J
% M* d3 z1 ]% d& H26      else if(m_wr && (m_addr == `ADC_S_Cnt_Max_H))//写采样分频计数器计数最大值的高16
' _5 X: o/ c- J9 q8 ?( b# K" `' \* `( ~3 b. q
27          ADC_Sample_Cnt_Max_H <= m_wrdata;5 `9 M5 R" y6 _" k0 q) m

* |* T. W) @8 _28      else begin- q1 f% K% b1 j; C+ O( T9 H  T
. a7 \# u  p9 \# j
29          ADC_Sample_Cnt_Max_H <= ADC_Sample_Cnt_Max_H;; f" X$ w" v5 ~4 n

, F3 R, Q0 X, u2 i30          ADC_Sample_Cnt_Max_L <= ADC_Sample_Cnt_Max_L;7 X% U2 I. T5 C3 T, h

9 A* x# W+ r: W; D  m* C7 W31      end
; d( d& a+ `& F; G4 r
" ?3 p* a( g/ J. s7 L1 E- h32      
  l' Z* D% e7 Y- I+ C8 E) o* S8 T6 Z" i3 w# Q# ^$ J, r8 o
33  /*---------写采样使能寄存器-------------*/
' Z% ]( s5 }/ r  S. [$ c( j& e' |
5 j: M  b$ t& W7 n9 h8 e" _5 ^6 h34      always@(posedge Clk or negedge Rst_n)( x# V& a4 P+ Q( c. _9 p# o
* E7 G. M" @0 L6 @7 Q# o
35      if(!Rst_n)( [* J& F* V) H" Y
9 o: v1 T  f, i
36          ADC_Sample_En <= 1'b0;
" o& _9 }: \' L  E6 a# S% I" P1 M2 E1 W
37      else if(m_wr && (m_addr == `ADC_Sample_En)): U, o! m+ Y  L$ k. m
. Z0 m& b  v' ^3 ]2 t
38          ADC_Sample_En <= m_wrdata[0];
4 r6 ~) V8 R  _, ]9 v
  ~* W3 i: j& E7 f3 r2 }39      else
4 H* X9 X4 T+ b' _, i0 }# G  p
" O: p: e  c8 W+ Z) p40          ADC_Sample_En <= ADC_Sample_En;+ z+ C  W# Q! @0 I0 F  a3 o
% t- v2 [' o* r3 z$ z

1 x" \- c8 V( \* u+ u" C3 d
' o. r9 z* X9 i! T% E8 C. ?

  \( d* M3 i- v. t采样率的控制采用定时器的方式实现。使用一个计数器持续对系统时钟进行计数一旦计数满设定时间,则产生一个时钟周期的高脉冲信号,作为ADC采样使能信号。这里,系统时钟周期20ns,因此如果要实现采样1K采样率(采样周期为1ms),则需系统时钟计数50000次;若实现20K的采样率(采样周期为50us则需要对系统时钟计数2500以此类推,可知改变采样率的实质就是改变计数器计数最大值,因此,我们要改变采样速率,也只需要改变采样率控制计数器的计数最大值即可所以这里,我们设计了两个16的寄存器,分别存储采样率控制计数器计数最大16161415所示。我们需要修改ADC的采样率时,直接通过串口发指令,修改这两个寄存器中的内容即可。8 r! R2 |! U- y. {- W" O

0 e2 [/ R, _+ f- n& Q2 H8 x/ F7 ^+ u
这里小梅哥使用自己设计的一个山寨版Memory Mapped 总线来配置各个寄存器,该总线包含三组信号,分别为6 N6 K2 Y, E9 ^/ F7 u! Z
5 o( s( F$ m# P. t6 W
使能信号m_wr, j6 v; ^- T7 R5 H+ b
' b9 ~0 W3 p5 o. A* m
地址信号:m_addr1 B, z$ ^5 D8 t! S

, {0 @0 G( l6 h$ s& K4 _1 l数据信号:m_wrdata
1 f8 |2 g+ D9 U: D) u% q那么,这三组信号如何配合工作的呢?我们配置ADC_Sample_Cnt_Max_HADC_Sample_Cnt_Max_L这两个寄存器来进行介绍这里再贴上这部分代码:  N# @( P  k2 k; _4 n, }  `& }% j

3 z# t/ C( a* O6 Y  J8 J! x; _6 g3 d' _18  /*-------设置采样分频计数器计数最大值---------*/  ' [) e5 I2 d, P" j+ S1 F% @

, P* o1 G* }; I* k% d2 ]19      always@(posedge Clk or negedge Rst_n)
0 T8 j* |$ c$ [' j9 o7 @% V# Z: l& x) C* v
20      if(!Rst_n)begin
5 J* T) {8 O* `6 K
! S8 R# I2 L# `4 n$ y' `21          ADC_Sample_Cnt_Max_H <= 16'd0;8 W% a. r& a6 U- p8 J7 r) a+ }

5 m: q4 E. u0 b& T6 S5 S22          ADC_Sample_Cnt_Max_L <= 16'd49999;/*默认设置采样率为1K*/+ e" U) M5 w! @1 U6 b

) ^* E3 K' T0 p* j) F4 [9 a( _! {23      end
: U* b# e1 P4 \4 @
1 E( W6 p* K( e24      else if(m_wr && (m_addr == `ADC_S_Cnt_Max_L))//写采样分频计数器计数最大值的低16
4 e. _5 w: m. t. V) K' `( G0 _3 p- Q! |7 L( z# O7 \; q  N& I6 H
25          ADC_Sample_Cnt_Max_L <= m_wrdata;$ I. w: r# X8 Z' m$ |

8 ?* [) o& f/ j* D26      else if(m_wr && (m_addr == `ADC_S_Cnt_Max_H))//写采样分频计数器计数最大值的高16
: x( X" E8 m: A
9 I* p& @  a# f9 h0 W27          ADC_Sample_Cnt_Max_H <= m_wrdata;
% |4 M' I/ j& f! l$ Z& U% s: _' f; F/ D; k* O& o
28      else begin
+ S1 A8 S; ?2 \" s" t+ G8 O% B+ c: B: N8 S& r5 \8 y6 @8 h
29          ADC_Sample_Cnt_Max_H <= ADC_Sample_Cnt_Max_H;/ t1 g9 T# w# @1 I* Y3 v6 d
; n7 L0 x) u0 `% I3 c
30          ADC_Sample_Cnt_Max_L <= ADC_Sample_Cnt_Max_L;: h9 o" ?0 J  \: N4 ]" A

! @# c6 a6 S: B& `* W) |& Y: c. O31      end7 k9 j9 a* e" N( [* H, t. `9 q$ l
" A* e. A7 ^# N! D2 @
' c8 `7 C$ g: K

& p0 G& Y% \. S7 W) m3 A6 V复位时,让{ 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寄存器。其他寄存器的配置原理此相同,因此不再做阐述,相信大家举一反三便可理解了。9 z! W/ r, {( n

; n8 _; l; J3 p" t5 u% B  i( B
小梅哥

; U# F* n6 x4 E3 T. M/ [# d) R+ a5 r! F" ^5 |! H
201548 于至芯科技

该用户从未签到

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

本版积分规则

关闭

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

EDA365公众号

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

GMT+8, 2025-10-9 10:58 , Processed in 0.203125 second(s), 23 queries , Gzip On.

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

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

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