协议——UART(RS232)

一、UART简介

  UART(universal asynchronous receiver-transmitter)是一种采用异步串行通信方式的通用异步收发传输器。一般来说,UART总是和RS232成对出现,那RS232又是什么呢? RS232也就是我们计算机上的串口,它的全称是EIA-RS-232C (简称232,或者是RS232 )。其中EIA(Electronic Industry Association)代表美国电子工业协会,RS是Recommended Standard的缩写,代表推荐标准,232 是标识符,C表示修改次数,它被广泛用于计算机串行接口外设连接。如果你的计算机上还有串口的话,那么你就可以在主机箱后面看到RS232的接口:

  随着时代的发展,这种借口已经很少用了,取而代之的是“USB转串口”,功能和原先一样,但接口更高效了。

  串口的主要功能为:在发送数据时将并行数据转换成串行数据进行传输,在接收数据时将接收到的串行数据转换成并行数据。这应该是大多数人接触电子后学习到的第一个通信协议吧。

 

二、通信格式

  下面来说说串口的具体要点:

1.传输时序

  UART串口通信需要两个信号线来实现,一根用于串口发送,另外一根负责串口接收。一开始高电平,然后拉低表示开始位,接着8个数据位,然后校验位,最后拉高表示停止位,并且进入空闲状态,等待下一次的数据传输。

  很多时候我们的校验位是允许省略的,所以协议就变成了:开始+数据+停止。

2.传输速率:波特率

  串口通信的速率用波特率表示,它表示麦苗传输二进制数据的位数,单位是bps(位/秒)。常用的波特率有9600、19200、35400、57600以及115200等。

  FPGA开发串口时,设计波特率的方法:FPGA的时钟频率/波特率。例如我的FPGA开发板时钟频率为50Mhz,即50_000_000hz,我想使用的波特率为9600bps,因此我需要的计数为:50000000/9600≈5208。

 

三、实战讲解

  现在用FPGA开发板做一个串口回环的实验,要求是PC端通过串口助手发送数据给FPGA,FPGA接收到数据后返回给PC端,并在串口助手处显示数值。即串口助手发什么就能收回什么。实验框图如下:

1.uart_rx

  如果直接用串口助手发送会出现一半数据丢失的情况。原因是串口发送助手发送数据是停止位后紧挨着下一波的开始位(即没有设置空闲位),导致下降沿检测没有办法跟上而丢失掉一些数据。解决办法是串口助手的停止位设置成1.5即可,即加0.5个空闲位。其他时候建议cnt1计数9下,这样即使停止位是1也不会出现数据丢失的情况。

  1 //==========================================================================
  2 // --- 名称 : uart_rx.v
  3 // --- 作者 : xianyu_FPGA
  4 // --- 日期 : 2019-06-24
  5 // --- 描述 : 串口接收模块,cnt1计数10下,是为配合发送模块的计数10下。
  6 //           此时需要将串口助手停止位设置为1.5,即加0.5个空闲位。
  7 //           其他时候建议cnt1计数9下,停止位为1,以保证连续接收数据无误。
  8 //==========================================================================
  9 
 10 module uart_rx
 11 //---------------------<参数定义>-------------------------------------------
 12 #(
 13 parameter BPS            = 5208              , //波特率
 14 parameter BPS_W          = 13                , //波特率位宽
 15 parameter BPS_half       = 2604                //波特率中间采样点
 16 )
 17 //---------------------<端口声明>-------------------------------------------
 18 (
 19 input  wire             clk                 , //时钟,50Mhz
 20 input  wire             rst_n               , //复位,低电平有效
 21 input  wire             din                 , //输入数据
 22 output reg    [7:0]     dout                , //输出数据
 23 output reg              dout_vld              //输出数据的有效指示
 24 );
 25 //---------------------<信号定义>-------------------------------------------
 26 reg                     rx0                 ;
 27 reg                     rx1                 ;
 28 reg                     rx2                 ;
 29 wire                    rx_en               ;
 30 reg                     flag                ;
 31 reg   [BPS_W-1:0]       cnt0                ;
 32 wire                    add_cnt0            ;
 33 wire                    end_cnt0            ;
 34 reg   [3:0]             cnt1                ;
 35 wire                    add_cnt1            ;
 36 wire                    end_cnt1            ;
 37 reg   [7:0]             data                ;
 38 
 39 //--------------------------------------------------------------------------
 40 //--   消除亚稳态 + 下降沿检测
 41 //--------------------------------------------------------------------------
 42 always @(posedge clk) begin
 43     {rx2,rx1,rx0} <= {rx1,rx0,din};
 44 end
 45 
 46 assign rx_en = rx2 && ~rx1;
 47 
 48 //--------------------------------------------------------------------------
 49 //--   接收状态指示
 50 //--------------------------------------------------------------------------
 51 always @(posedge clk or negedge rst_n) begin
 52     if(!rst_n)
 53         flag <= 0;
 54     else if(rx_en)
 55         flag <= 1;
 56     else if(end_cnt1)
 57         flag <= 0;
 58 end
 59 
 60 //--------------------------------------------------------------------------
 61 //--   波特率计数
 62 //--------------------------------------------------------------------------
 63 always @(posedge clk or negedge rst_n) begin
 64     if(!rst_n)
 65         cnt0 <= 0;
 66     else if(add_cnt0) begin
 67         if(end_cnt0)
 68             cnt0 <= 0;
 69         else
 70             cnt0 <= cnt0 + 1;
 71     end
 72     else
 73         cnt0 <= cnt0;
 74 end
 75 
 76 assign add_cnt0 = flag;
 77 assign end_cnt0 = add_cnt0 && cnt0== BPS-1;
 78 
 79 //--------------------------------------------------------------------------
 80 //--   开始位(不接收) + 8个数据位 + 停止位(不接收)= 10
 81 //--------------------------------------------------------------------------
 82 always @(posedge clk or negedge rst_n) begin 
 83     if(!rst_n)
 84         cnt1 <= 0;
 85     else if(add_cnt1) begin
 86         if(end_cnt1)
 87             cnt1 <= 0;
 88         else
 89             cnt1 <= cnt1 + 1;
 90     end
 91     else
 92         cnt1 <= cnt1;
 93 end
 94 
 95 assign add_cnt1 = end_cnt0;
 96 assign end_cnt1 = add_cnt1 && cnt1==10-1;
 97 
 98 //--------------------------------------------------------------------------
 99 //--   缓存数据
100 //--------------------------------------------------------------------------
101 always @ (posedge clk or negedge rst_n)begin
102     if(!rst_n)
103         data <= 8'd0;
104     else if(cnt1>=1 && cnt1<=8 && cnt0==BPS_half-1) //中间采样
105         data[cnt1-1] <= rx2;                        //或 dout <= {rx2,dout[7:1]};
106 end
107 
108 //--------------------------------------------------------------------------
109 //--   输出数据
110 //--------------------------------------------------------------------------
111 always @ (posedge clk or negedge rst_n)begin
112     if(!rst_n)
113         dout <= 0;
114     else if(end_cnt1)    
115         dout <= data;
116 end
117 
118 always @ (posedge clk or negedge rst_n)begin
119     if(!rst_n)
120         dout_vld <= 0;
121     else if(end_cnt1)    
122         dout_vld <= 1;    
123     else    
124         dout_vld <= 0;
125 end
126 
127 
128 
129 endmodule

2.uart_tx

  设计和协议完全匹配。

  1 //==========================================================================
  2 // --- 名称 : uart_tx.v
  3 // --- 作者 : xianyu_FPGA
  4 // --- 日期 : 2019-06-24
  5 // --- 描述 : 串口发送模块
  6 //==========================================================================
  7 
  8 module uart_tx
  9 //---------------------<参数定义>-------------------------------------------
 10 #(
 11 parameter BPS           = 5208              , //波特率
 12 parameter BPS_W         = 13                  //波特率位宽
 13 )
 14 //---------------------<端口声明>-------------------------------------------
 15 (
 16 input  wire             clk                 , //时钟,50Mhz
 17 input  wire             rst_n               , //复位,低电平有效
 18 input  wire [7:0]       din                 , //输入数据
 19 input  wire             din_vld             , //输入数据的有效指示
 20 output reg              dout                  //输出数据
 21 );
 22 //---------------------<信号定义>-------------------------------------------
 23 reg                     flag                ;
 24 reg   [7:0]             din_tmp             ;
 25 reg   [BPS_W-1:0]       cnt0                ;
 26 wire                    add_cnt0            ;
 27 wire                    end_cnt0            ;
 28 reg   [3:0]             cnt1                ;
 29 wire                    add_cnt1            ;
 30 wire                    end_cnt1            ;
 31 wire  [9:0]             data                ;
 32 
 33 //--------------------------------------------------------------------------
 34 //--   数据暂存(din可能会消失,暂存住)
 35 //--------------------------------------------------------------------------
 36 always @ (posedge clk or negedge rst_n) begin
 37     if(!rst_n)
 38         din_tmp <=8'd0;
 39     else if(din_vld)
 40         din_tmp <= din;
 41 end
 42 
 43 //--------------------------------------------------------------------------
 44 //--   发送状态指示
 45 //--------------------------------------------------------------------------
 46 always  @(posedge clk or negedge rst_n)begin
 47     if(!rst_n)
 48         flag <= 0;
 49     else if(din_vld)
 50         flag <= 1;
 51     else if(end_cnt1)
 52         flag <= 0;
 53 end
 54 
 55 //--------------------------------------------------------------------------
 56 //--   波特率计数
 57 //--------------------------------------------------------------------------
 58 always @(posedge clk or negedge rst_n) begin
 59     if(!rst_n)
 60         cnt0 <= 0;
 61     else if(add_cnt0) begin
 62         if(end_cnt0)
 63             cnt0 <= 0;
 64         else
 65             cnt0 <= cnt0 + 1;
 66     end
 67     else
 68         cnt0 <= cnt0;
 69 end
 70 
 71 assign add_cnt0 = flag;
 72 assign end_cnt0 = add_cnt0 && cnt0== BPS-1;
 73 
 74 //--------------------------------------------------------------------------
 75 //--   开始 + 数据 + 结束,共10位
 76 //--------------------------------------------------------------------------
 77 always @(posedge clk or negedge rst_n) begin 
 78     if(!rst_n)
 79         cnt1 <= 0;
 80     else if(add_cnt1) begin
 81         if(end_cnt1)
 82             cnt1 <= 0;
 83         else
 84             cnt1 <= cnt1 + 1;
 85     end
 86     else
 87         cnt1 <= cnt1;
 88 end
 89 
 90 assign add_cnt1 = end_cnt0;
 91 assign end_cnt1 = add_cnt1 && cnt1== 10-1;
 92 
 93 //--------------------------------------------------------------------------
 94 //--   数据输出(用case语句也行)
 95 //--------------------------------------------------------------------------
 96 assign data = {1'b1,din_tmp,1'b0};    //结束,数据,开始
 97 
 98 always @(posedge clk or negedge rst_n) begin
 99     if(!rst_n)
100         dout <= 1'b1;
101     else if(flag==1)
102         dout <= data[cnt1];
103 end
104 
105 
106 
107 endmodule

3.uart_top顶层文件

 1 //==========================================================================
 2 // --- 名称 : uart_top.v
 3 // --- 作者 : xianyu_FPGA
 4 // --- 日期 : 209-06-24
 5 // --- 描述 : 串口实验顶层文件
 6 //==========================================================================
 7 
 8 module uart_top
 9 //---------------------<端口声明>-------------------------------------------
10 (
11 input  wire             clk                 , //时钟,50Mhz
12 input  wire             rst_n               , //复位,低电平有效
13 input  wire             uart_rx             , //FPGA通过串口接收的数据
14 output wire             uart_tx               //FPGA通过串口发送的数据
15 );
16 
17 //---------------------<模块连线>-------------------------------------------
18 wire [7:0]              data                ;
19 wire                    data_vld            ;
20 
21 //--------------------------------------------------------------------------
22 //--   模块例化
23 //--------------------------------------------------------------------------
24 uart_rx u_uart_rx
25 (
26     .clk                (clk                ),
27     .rst_n              (rst_n              ),
28     .din                (uart_rx            ),
29     .dout               (data               ),
30     .dout_vld           (data_vld           )
31 );
32 
33 uart_tx u_uart_tx
34 (
35     .clk                (clk                ),
36     .rst_n              (rst_n              ),
37     .din_vld            (data_vld           ),
38     .din                (data               ),
39     .dout               (uart_tx            )
40 );
41 
42 endmodule

4.testbench

  里面的data.txt是一个文本文件,其内容为:0 1 2 3 4 5 6 7 8 9 a b c d e f ,放到你的工作文件夹区即可。

 1 `timescale 1ns/1ps  //时间精度
 2 `define    Clock 20 //时钟周期
 3 
 4 module uart_top_tb;
 5 
 6 //---------------------<端口定义>-------------------------------------------
 7 reg                     clk                 ; //时钟,50Mhz
 8 reg                     rst_n               ; //复位,低电平有效
 9 reg                     uart_rx             ;
10 wire                    uart_tx             ;
11 
12 //--------------------------------------------------------------------------
13 //--   模块例化
14 //--------------------------------------------------------------------------
15 uart_top u_uart_top
16 (
17     .clk                (clk                ),
18     .rst_n              (rst_n              ),
19     .uart_rx            (uart_rx            ),
20     .uart_tx            (uart_tx            )
21 );
22 
23 //----------------------------------------------------------------------
24 //--   时钟信号和复位信号
25 //----------------------------------------------------------------------
26 initial begin
27     clk = 1;
28     forever
29         #(`Clock/2) clk = ~clk;
30 end
31 
32 initial begin
33     rst_n = 0; #(`Clock*20+1);
34     rst_n = 1;
35 end
36 
37 //----------------------------------------------------------------------
38 //--   tase任务
39 //----------------------------------------------------------------------
40 reg     [7:0]           mem[15:0]            ; //位宽为8,深度为16
41 integer                 i                    ;
42 integer                 j                    ;
43 
44 //读取外部数据
45 initial begin
46     $readmemh("./data.txt",mem);
47 end
48 
49 //
50 task rx_bit(input [7:0]data);
51     begin
52         for(i=0;i<10;i=i+1) begin    //0-9
53             case(i)
54                  0:uart_rx = 0;
55                  1:uart_rx = data[i-1];
56                  2:uart_rx = data[i-1];
57                  3:uart_rx = data[i-1];
58                  4:uart_rx = data[i-1];
59                  5:uart_rx = data[i-1];
60                  6:uart_rx = data[i-1];
61                  7:uart_rx = data[i-1];
62                  8:uart_rx = data[i-1];
63                  9:uart_rx = 1;
64             endcase 
65             #104260; //一个完整波特延时:5208*20=104160
66         end             //考虑到空闲位,也可以设置得104160稍大一些
67     end
68 endtask 
69 
70 //字节
71 task rx_byte;
72     begin
73         for(j=0;j<16;j=j+1)
74             rx_bit(mem[j]);
75     end
76 endtask
77 
78 //--------------------------------------------------------------------------
79 //--   调用task
80 //--------------------------------------------------------------------------
81 initial begin
82     #(`Clock*20+1);
83     rx_byte();
84 end
85 
86 
87 
88 endmodule

5.仿真波形,软件:isim

  上半波形是uart_rx模块,下半波形是uart_tx模块,其中紫色的信号为输出。可以看到,波形和我们的设计相符合,能正确的接收和发送数据。

6.实际上板

  软件:友善串口助手。停止位是1.5位或2位,成功!

 

四、总结

  UART是我学习FPGA后设计的第一个协议,之前一直是拿着教程demo跑一跑完事,自己亲自设计才体会到时序的不容易。难怪串口的停止位上设置了选项:1位、1.5位、2位,看来这都是前人遇到过的坑啊!

  总结一下:由于串口助手的发送机制是停止位和下一波的开始位连着(中间没有空闲位),因此我们设计uart_rx接收串口助手的数据时,如果计数10下,则串口助手的停止位要设置成1.5或2位。如果停止位设置成1位,则计数必须改成9下。

 

五、更改!!!

  等等哈,为什么要弄的这么复杂?不就是个串口吗?别人的串口回环实验中串口助手的停止位是1就行,到你这就要1.5位或2位?

  经过思考,我发现一个很好的办法:停止位计0.5下!这样就解决了串口助手发送数据时,停止位和下一波的开始位连着(中间没有空闲位)的问题啊!我自己制造一个0.5的空闲位,完美解决问题,美滋滋!

1.uart_rx更改

  1 //==========================================================================
  2 // --- 名称 : uart_rx.v
  3 // --- 作者 : xianyu_FPGA
  4 // --- 日期 : 2019-06-27
  5 // --- 描述 : 串口接收模块,计数9.5下,其中停止位0.5下
  6 //          * 因为串口助手发送本次停止位和下次开始位中间没有留空闲位
  7 //          * 若计满10下,则才结束本次传输下次数据就来了,会来不及接收
  8 //==========================================================================
  9 
 10 module uart_rx
 11 //---------------------<参数定义>-------------------------------------------
 12 #(
 13 parameter BPS           = 5208              , //波特率
 14 parameter BPS_W         = 13                , //波特率位宽
 15 parameter BPS_half      = 2604                //波特率中间采样点
 16 )
 17 //---------------------<端口声明>-------------------------------------------
 18 (
 19 input  wire             clk                 , //时钟,50Mhz
 20 input  wire             rst_n               , //复位,低电平有效
 21 input  wire             din                 , //输入数据
 22 output reg    [7:0]     dout                , //输出数据
 23 output reg              dout_vld              //输出数据的有效指示
 24 );
 25 //---------------------<信号定义>-------------------------------------------
 26 reg                     rx0                 ;
 27 reg                     rx1                 ;
 28 reg                     rx2                 ;
 29 wire                    rx_en               ;
 30 reg                     flag                ;
 31 reg   [BPS_W-1:0]       cnt0                ;
 32 wire                    add_cnt0            ;
 33 wire                    end_cnt0            ;
 34 reg   [3:0]             cnt1                ;
 35 wire                    add_cnt1            ;
 36 wire                    end_cnt1            ;
 37 reg   [7:0]             data                ;
 38 
 39 //--------------------------------------------------------------------------
 40 //--   消除亚稳态 + 下降沿检测
 41 //--------------------------------------------------------------------------
 42 always @(posedge clk) begin
 43     {rx2,rx1,rx0} <= {rx1,rx0,din};
 44 end
 45 
 46 assign rx_en = rx2 && ~rx1;
 47 
 48 //--------------------------------------------------------------------------
 49 //--   接收状态指示
 50 //--------------------------------------------------------------------------
 51 always @(posedge clk or negedge rst_n) begin
 52     if(!rst_n)
 53         flag <= 0;
 54     else if(rx_en)
 55         flag <= 1;
 56     else if(end_cnt1)
 57         flag <= 0;
 58 end
 59 
 60 //--------------------------------------------------------------------------
 61 //--   波特率计数
 62 //--------------------------------------------------------------------------
 63 always @(posedge clk or negedge rst_n) begin
 64     if(!rst_n)
 65         cnt0 <= 0;
 66     else if(add_cnt0) begin
 67         if(end_cnt0)
 68             cnt0 <= 0;
 69         else
 70             cnt0 <= cnt0 + 1;
 71     end
 72     else
 73         cnt0 <= cnt0;
 74 end
 75 
 76 assign add_cnt0 = flag;
 77 assign end_cnt0 = cnt0== BPS-1 || end_cnt1;
 78 
 79 //--------------------------------------------------------------------------
 80 //--   开始1位(不接收) + 数据8位 + 停止0.5位(不接收),共10位
 81 //--------------------------------------------------------------------------
 82 always @(posedge clk or negedge rst_n) begin 
 83     if(!rst_n)
 84         cnt1 <= 0;
 85     else if(add_cnt1) begin
 86         if(end_cnt1)
 87             cnt1 <= 0;
 88         else
 89             cnt1 <= cnt1 + 1;
 90     end
 91     else
 92         cnt1 <= cnt1;
 93 end
 94 
 95 assign add_cnt1 = end_cnt0;
 96 assign end_cnt1 = cnt1==10-1 && cnt0==BPS_half-1;
 97 
 98 //--------------------------------------------------------------------------
 99 //--   缓存数据
100 //--------------------------------------------------------------------------
101 always @ (posedge clk or negedge rst_n)begin
102     if(!rst_n)
103         data <= 8'd0;
104     else if(cnt1>=1 && cnt1<=8 && cnt0==BPS_half-1) //中间采样
105         data[cnt1-1] <= rx2;                        //或 dout <= {rx2,dout[7:1]};
106 end
107 
108 //--------------------------------------------------------------------------
109 //--   输出数据
110 //--------------------------------------------------------------------------
111 always @ (posedge clk or negedge rst_n)begin
112     if(!rst_n)
113         dout <= 0;
114     else if(end_cnt1)    
115         dout <= data;
116 end
117 
118 always @ (posedge clk or negedge rst_n)begin
119     if(!rst_n)
120         dout_vld <= 0;
121     else if(end_cnt1)    
122         dout_vld <= 1;    
123     else    
124         dout_vld <= 0;
125 end
126 
127 
128 
129 endmodule

2.uart_tx更改

  1 //==========================================================================
  2 // --- 名称 : uart_tx.v
  3 // --- 作者 : xianyu_FPGA
  4 // --- 日期 : 2019-06-27
  5 // --- 描述 : 串口接收模块,计数9.5下,其中停止位0.5下
  6 //         * 因为极端情况是本次停止位和下次开始位中间没有留空闲位
  7 //         * 若计满10下,则才结束本次传输下次数据就来了,会来不及发送
  8 //==========================================================================
  9 
 10 module uart_tx
 11 //---------------------<参数定义>-------------------------------------------
 12 #(
 13 parameter BPS           = 5208              , //波特率
 14 parameter BPS_W         = 13                , //波特率位宽
 15 parameter BPS_half      = 2604                //波特率中间采样点
 16 )
 17 //---------------------<端口声明>-------------------------------------------
 18 (
 19 input  wire             clk                 , //时钟,50Mhz
 20 input  wire             rst_n               , //复位,低电平有效
 21 input  wire [7:0]       din                 , //输入数据
 22 input  wire             din_vld             , //输入数据的有效指示
 23 output reg              dout                  //输出数据
 24 );
 25 //---------------------<信号定义>-------------------------------------------
 26 reg                     flag                ;
 27 reg   [7:0]             din_tmp             ;
 28 reg   [BPS_W-1:0]       cnt0                ;
 29 wire                    add_cnt0            ;
 30 wire                    end_cnt0            ;
 31 reg   [3:0]             cnt1                ;
 32 wire                    add_cnt1            ;
 33 wire                    end_cnt1            ;
 34 wire  [9:0]             data                ;
 35 
 36 //--------------------------------------------------------------------------
 37 //--   数据暂存(din可能会消失,暂存住)
 38 //--------------------------------------------------------------------------
 39 always @ (posedge clk or negedge rst_n) begin
 40     if(!rst_n)
 41         din_tmp <=8'd0;
 42     else if(din_vld)
 43         din_tmp <= din;
 44 end
 45 
 46 //--------------------------------------------------------------------------
 47 //--   发送状态指示
 48 //--------------------------------------------------------------------------
 49 always  @(posedge clk or negedge rst_n)begin
 50     if(!rst_n)
 51         flag <= 0;
 52     else if(din_vld)
 53         flag <= 1;
 54     else if(end_cnt1)
 55         flag <= 0;
 56 end
 57 
 58 //--------------------------------------------------------------------------
 59 //--   波特率计数
 60 //--------------------------------------------------------------------------
 61 always @(posedge clk or negedge rst_n) begin
 62     if(!rst_n)
 63         cnt0 <= 0;
 64     else if(add_cnt0) begin
 65         if(end_cnt0)
 66             cnt0 <= 0;
 67         else
 68             cnt0 <= cnt0 + 1;
 69     end
 70     else
 71         cnt0 <= cnt0;
 72 end
 73 
 74 assign add_cnt0 = flag;
 75 assign end_cnt0 = cnt0== BPS-1 || end_cnt1;
 76 
 77 //--------------------------------------------------------------------------
 78 //--   开始1位 + 数据8位 + 停止0.5位,共10位
 79 //--------------------------------------------------------------------------
 80 always @(posedge clk or negedge rst_n) begin 
 81     if(!rst_n)
 82         cnt1 <= 0;
 83     else if(add_cnt1) begin
 84         if(end_cnt1)
 85             cnt1 <= 0;
 86         else
 87             cnt1 <= cnt1 + 1;
 88     end
 89     else
 90         cnt1 <= cnt1;
 91 end
 92 
 93 assign add_cnt1 = end_cnt0;
 94 assign end_cnt1 = cnt1==10-1 && cnt0==BPS_half-1;
 95 
 96 //--------------------------------------------------------------------------
 97 //--   数据输出(用case语句也行)
 98 //--------------------------------------------------------------------------
 99 assign data = {1'b1,din_tmp,1'b0};    //结束,数据,开始
100 
101 always @(posedge clk or negedge rst_n) begin
102     if(!rst_n)
103         dout <= 1'b1;
104     else if(flag==1)
105         dout <= data[cnt1];
106 end
107 
108 
109 
110 endmodule

3.实际上板

  停止位是1位,成功!

 

六、后记

  一个串口搞了我两次!唉,不想说什么了,菜就是罪啊!

 

参考资料:

[1]明德扬FPGA教程

[2]正点原子FPGA教程

[2]威三学院FPGA教程

转载于:https://www.cnblogs.com/xianyufpga/p/11086676.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值