FPGA之RS232

串行通讯
数据以每次一位的方式传输;每条线用来传输一个方向的数据。由于计算机通常至少需要若干位数据,因此数据在发送之前先“串行化”。通常是以8位数据为1组的。。先发送最低有效位,最后发送最高有效位。

异步通讯
RS-232使用异步通讯协议。也就是说数据的传输没有时钟信号。接收端必须有某种方式,使之与接收数据同步。
对于RS-232来说,是这样处理的:

1. 串行线缆的两端事先约定好串行传输的参数(传输速度、传输格式等)

2. 当没有数据传输的时候,发送端向数据线上发送"1"

3. 每传输一个字节之前,发送端先发送一个"0"来表示传输已经开始。这样接收端便可以知道有数据到来了。

4. 开始传输后,数据以约定的速度和格式传输,所以接收端可以与之同步

5. 每次传输完成一个字节之后,都在其后发送一个停止位("1")

让我们来看看0x55是如何传输的:
FPGA:实现串行接口 <wbr>RS232
0x55的二进制表示为:01010101。
但是由于先发送的是最低有效位,所以发送序列是这样的: 1-0-1-0-1-0-1-0.
下面是另外一个例子 :
FPGA:实现串行接口 <wbr>RS232
传输的数据为0xC4,你能看出来吗?
从图中很难看出来所传输的数据,这也说明了事先知道传输的速率对于接收端有多么重要。

RS-232发送模块
下面是我们所想要实现的:
FPGA:实现串行接口 <wbr>RS232
它应该能像这样工作:

· 发送器接收8位的数据,并将其串行输出。("TxD_start"置位后开始传输).

· 当有数传输的时候,使"busy"信号有效,此时“TxD_start”信号被忽略.

RS-232模块的参数是固定的: 8位数据, 2个停止位, 无奇偶校验.

数据串行化
假设我们已经有了一个115200波特的"BaudTick"信号.

我们需要产生开始位、8位数据以及停止位。
用状态机来实现看起来比较合适。

reg [3:0] state;
always @(posedge clk)
case(state)
4'b0000: if(TxD_start) state <= 4'b0100;
4'b0100: if(BaudTick) state <= 4'b1000; // 开始位
4'b1000: if(BaudTick) state <= 4'b1001; // bit 0
4'b1001: if(BaudTick) state <= 4'b1010; // bit 1
4'b1010: if(BaudTick) state <= 4'b1011; // bit 2
4'b1011: if(BaudTick) state <= 4'b1100; // bit 3
4'b1100: if(BaudTick) state <= 4'b1101; // bit 4
4'b1101: if(BaudTick) state <= 4'b1110; // bit 5
4'b1110: if(BaudTick) state <= 4'b1111; // bit 6
4'b1111: if(BaudTick) state <= 4'b0001; // bit 7
4'b0001: if(BaudTick) state <= 4'b0010; // 停止位1
4'b0010: if(BaudTick) state <= 4'b0000; // 停止位2
default: if(BaudTick) state <= 4'b0000;
endcase

注意看这个状态机是怎样实现当"TxD_start"有效就开始,但只在"BaudTick"有效的时候才转换状态的。.

现在,我们只需要产生"TxD"输出即可.
reg muxbit;
always @(state[2:0])
case(state[2:0])
0: muxbit <= TxD_data[0];
1: muxbit <= TxD_data[1];
2: muxbit <= TxD_data[2];
3: muxbit <= TxD_data[3];
4: muxbit <= TxD_data[4];
5: muxbit <= TxD_data[5];
6: muxbit <= TxD_data[6];
7: muxbit <= TxD_data[7];
endcase

//将开始位、数据以及停止位结合起来
assign TxD = (state<4) | (state[3] & muxbit);

RS232接收模块
下面是我们想要实现的模块:
FPGA:实现串行接口 <wbr>RS232
我们的设计目的是这样的:
1.当RxD线上有数据时,接收模块负责识别RxD线上的数据
2.当收到一个字节的数据时,锁存接收到的数据到"data"总线,并使"data_ready"有效一个周期。
注意:只有当"data_ready"有效时,"data"总线的数据才有效,其他的时间里不要使用"data"总线上的数据,因为新的数据可能已经改变了其中的部分数据。

过采样
异步接收机必须通过一定的机制与接收到的输入信号同步(接收端没有办法得到发送断的时钟)。这里采用如下办法。
1.为了确定新数据的到来,即检测开始位,我们使用几倍于波特率的采样时钟对接收到的信号进行采样。
2.一旦检测到"开始位",再将采样时钟频率降为已知的发送端的波特率。
典型的过采样时钟频率为接收到的信号的波特率的16倍,这里我们使用8倍的采样时钟。当波特率为115200时,采样时钟为921600Hz。(115200*8=921600

假设我们已经有了一个8倍于波特率的时钟信号 "Baud8Tick",其频率为 921600Hz。


 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值