差别
这里会显示出您选择的修订版和当前版本之间的差别。
两侧同时换到之前的修订记录 前一修订版 | 上一修订版 两侧同时换到之后的修订记录 | ||
rs-232 [2017/03/26 19:48] gongyu [接收器] |
rs-232 [2017/03/26 19:51] gongyu [接收器] |
||
---|---|---|---|
行 231: | 行 231: | ||
Our implementation works like that: | Our implementation works like that: | ||
- | The module assembles data from the RxD line as it comes. | + | * The module assembles data from the RxD line as it comes. |
- | As a byte is being received, it appears on the "data" bus. Once a complete byte has been received, "data_ready" is asserted for one clock. | + | * As a byte is being received, it appears on the "data" bus. Once a complete byte has been received, "data_ready" is asserted for one clock. |
Note that "data" is valid only when "data_ready" is asserted. The rest of the time, don't use it as new data may come that shuffles it. | Note that "data" is valid only when "data_ready" is asserted. The rest of the time, don't use it as new data may come that shuffles it. | ||
- | Oversampling | + | ===== Oversampling ===== |
An asynchronous receiver has to somehow get in-sync with the incoming signal (it normally doesn't have access to the clock used by the transmitter). | An asynchronous receiver has to somehow get in-sync with the incoming signal (it normally doesn't have access to the clock used by the transmitter). | ||
行 245: | 行 246: | ||
Let's assume that we have a "Baud8Tick" signal available, asserted 921600 times a second. | Let's assume that we have a "Baud8Tick" signal available, asserted 921600 times a second. | ||
- | The design | + | ===== The design ===== |
First, the incoming "RxD" signal has no relationship with our clock. | First, the incoming "RxD" signal has no relationship with our clock. | ||
We use two D flip-flops to oversample it, and synchronize it to our clock domain. | We use two D flip-flops to oversample it, and synchronize it to our clock domain. | ||
+ | <code verilog> | ||
reg [1:0] RxD_sync; | reg [1:0] RxD_sync; | ||
always @(posedge clk) if(Baud8Tick) RxD_sync <= {RxD_sync[0], RxD}; | always @(posedge clk) if(Baud8Tick) RxD_sync <= {RxD_sync[0], RxD}; | ||
- | We filter the data, so that short spikes on the RxD line aren't mistaken with start bits. | + | </code> |
+ | We filter the data, so that short spikes on the RxD line aren't mistaken with start bits. | ||
+ | <code verilog> | ||
reg [1:0] RxD_cnt; | reg [1:0] RxD_cnt; | ||
reg RxD_bit; | reg RxD_bit; | ||
行 268: | 行 272: | ||
if(RxD_cnt==2'b11) RxD_bit <= 1; | if(RxD_cnt==2'b11) RxD_bit <= 1; | ||
end | end | ||
- | A state machine allows us to go through each bit received, once a "start" is detected. | + | </code> |
+ | A state machine allows us to go through each bit received, once a "start" is detected. | ||
+ | <code verilog> | ||
reg [3:0] state; | reg [3:0] state; | ||
行 287: | 行 293: | ||
default: state <= 4'b0000; | default: state <= 4'b0000; | ||
endcase | endcase | ||
- | Notice that we used a "next_bit" signal, to go from bit to bit. | + | </code> |
+ | Notice that we used a "next_bit" signal, to go from bit to bit. | ||
+ | <code verilog> | ||
reg [2:0] bit_spacing; | reg [2:0] bit_spacing; | ||
行 303: | 行 311: | ||
reg [7:0] RxD_data; | reg [7:0] RxD_data; | ||
always @(posedge clk) if(Baud8Tick && next_bit && state[3]) RxD_data <= {RxD_bit, RxD_data[7:1]}; | always @(posedge clk) if(Baud8Tick && next_bit && state[3]) RxD_data <= {RxD_bit, RxD_data[7:1]}; | ||
- | The complete code can be found here. | + | </code> |
- | It has a few improvements; follow the comments in the code. | + | |
- | Links | ||
- | More details on Asynchronous Communication | ||
====== 应用案例 ====== | ====== 应用案例 ====== |