串口UARTRS232接收模块设计

1、端口信息

  输入端口信息:串行数据rx_data(串口接收的串行数据),系统时钟clk,系统复位rst_n;

  输出端口信息:并行数据的输出data[7:0],发送数据的请求信号reg。

2、UART时序

  本设计采用的是以16倍波特率对数据进行采样,保证数据的准确性,此时就需要用到时钟为9600*16hz;用n倍数的波特率进行采样,此时用到时钟为9600*nhz。

3、采样时钟

  以传输速率为9600Baud为例进行设计,则传输一位的时间为1s/9600;现在我们需要将传输一位数据采样16次,则串行采样时钟频率为9600*16=153600hz;在本设计中波特率等于比特率,因为我们我们传输的是二进制;一个二进制位只能最多表示两种信号0/1。

4、准备工具

  串口助手:用于发送数据。

5、比特、码元、比特率、波特率  

  比特:bit 数据位,表示二进制数1或者0;

  码元:在数字通信中常常用时间间隔相同的符号来表示一个二进制数字,这样的时间间隔内的信号称为(二进制)码元;

  比特率:单位时间内传输的二进制比特数 bps(b/s);

  波特率:单位时间内传输的码元个数(脉冲个数或者信号变化次数)Baud(位/秒);

  波特率和比特率的转换公式:C = B * log2N (C表示比特率;B表示波特率;N表示进制)。

6、代码如下:

 1 module universal_asynchronous_receiver(clk, rst_n, rxd, rx_data);
 2     input clk, rst_n;      //153600HZ=9600*16
 3     input rxd;  //接收串口给的数据
 4     output reg [7:0] rx_data;      //将接收的串行数据转换为并行数据
 5     
 6     reg [7:0] cnt;      
 7     reg state;
 8     
 9     parameter S0    =   1'b0;
10     parameter S1    =   1'b1;
11 
12     //状态机:一段式
13     always @ (posedge clk, negedge rst_n)
14     begin
15         if(!rst_n)
16             begin
17                 cnt <= 0;
18                 state <= S0;
19             end
20         else
21             case(state)
22                 S0  :   if(rxd)      //起始信号
23                             state <= S0;      
24                         else
25                             state <= S1;
26                 S1  :   if(cnt < 160)      //判断接收是否完成
27                             cnt <= cnt + 1'b1;
28                         else
29                             begin
30                                 cnt <= 0;
31                                 state <= S0; 
32                             end
33                 default : state <= S0;
34             endcase   
35     end
36     
37     reg [7:0] temp;      //中间寄存器用于寄存串行数据
38     
39     always @ (posedge clk, negedge rst_n)
40     begin
41         if(!rst_n)
42             begin
43                 temp <= 8'd0;
44                 rx_data <= 8'd0;
45             end
46         else
47             case(cnt)
48                 7       :   temp <= 8'd0;        //起始位temp寄存的上一个数据清零,也可以不清零
49                 7+16*1  :   temp[0] <= rxd;      //接收第一位数据
50                 7+16*2  :   temp[1] <= rxd;      //接收第二位数据
51                 7+16*3  :   temp[2] <= rxd;      //接收第三位数据
52                 7+16*4  :   temp[3] <= rxd;      //接收第四位数据
53                 7+16*5  :   temp[4] <= rxd;      //接收第五位数据
54                 7+16*6  :   temp[5] <= rxd;      //接收第六位数据
55                 7+16*7  :   temp[6] <= rxd;      //接收第七位数据
56                 7+16*8  :   temp[7] <= rxd;      //接收第八位数据
57                 7+16*9  :   temp <= temp;        //停止位保持
58                 16*10:  rx_data <= temp;         //将寄存的8位数据给输出端口
59                 default :   ;
60             endcase
61     end
62 
63 endmodule

 

      

posted on 2020-10-23 21:13  追梦的少年郎  阅读(119)  评论(1)    收藏  举报

导航