框图
-
THR:发送保持寄存器
- 定义了两种状态:空,满
- 数据写入端口地址:00H
- 状态读出端口地址:00H
- 当THR不满时,可以向THR写入数据
-
TSR:发送移位寄存器
- 一旦TSR空而THR中有数据时,THR中的数据就送到TSR
- RSR中的数据以串行方式从TxD段发送,高位在前,低位在后
- 在TxD端的bit流中,若连续出现5个’1‘,则在第5个’1‘之后自动插入一个’0’。注意:相邻两个字节之间也会出现5个连续的‘1’
-
发送时许
- 代码
module p2s_tramsmitter (RST,CLK2M,CS,FS,WR,RD,A0,D,TxD
);input RST,CLK2M,CS,WR,RD,FS;input A0;inout [7:0] D;output TxD;reg TxD;wire [7:0] D;reg [7:0] THR_Status,THR,TSR,R_Shifter;// R_Shifter 最低为TxD_1;reg [2:0] Count8;reg [2:0] Count5;reg [4:0] Count32;reg TSR_Shift_EN;reg Mux_Sel1,Mux_Sel2;reg TxD_2;reg Load_EN;reg THR_Read;// 移位寄存器,load操作为:每当移完一个字节的数据并且THR不空时,// 就从THR加载一个数据// 在TSR_Shift_EN信号有效时,TSR做移位操作always @(posedge RST or posedge CLK2M) beginif (RST) TSR <= 8'b00000000;else if (Count8 ==3'b000&&THR_Status[0] == 1) beginTSR <= THR;end else if (TSR_Shift_EN == 1'b1) TSR <= {TSR[6:0],1'b0};end//连续5个‘1’的检测及插‘0’。always @(posedge RST or posedge CLK2M) beginif (RST) Count5 = 3'b100;else if (TSR[7] == 1'b0) Count5 = 3'b100;else Count5 = Count5 - 1;endalways @(TSR or Mux_Sel1) beginif (Mux_Sel1) TxD_2 = 1'b0;else TxD_2 = TSR[7];endalways @(Count5) beginif (Count5 == 3'b000) Mux_Sel1 = 1'b1;else Mux_Sel1 = 1'b0;end//在发送5个连续的‘1’之后要插入一个‘0’,此时TSR不移位。// always @(Count5) begin// if (Count5 == 3'b000) // TSR_Shift_EN = 1'b0;// else // TSR_Shift_EN = 1'b1;// end 等价于always @(Mux_Sel1) beginTSR_Shift_EN = ~Mux_Sel1;end//正常数据与发送7EH的处理always @(Mux_Sel1 or TxD or R_Shifter) beginif (Mux_Sel2) TxD = R_Shifter[7];else TxD = TxD_2;endalways @(posedge RST or posedge CLK2M) beginif (RST) R_Shifter = 8'b01111110;else if (Load_EN) R_Shifter = 8'b01111110;//7EHelse R_Shifter = {R_Shifter[6:0],R_Shifter[7]};endalways @(posedge RST or posedge CLK2M) beginif (RST)Count32 = 5'b11111;else if (~FS) Count32 = 5'b11111;else if (TSR_Shift_EN) Count32 = Count32 - 1;end// 对TSR移位32次,即进入空闲态,因此Count32对TSR_Shift_EN进行计数always @(Count32) beginif (Count32 == 5'b00000)Load_EN = 1'b1;else Load_EN = 1'b0;endalways @(Load_EN) beginMux_Sel2 = Load_EN;endalways @(posedge RST or posedge CLK2M) beginif (RST)THR = 8'b00000000;else if (CS == 1'b0&&WR == 1'b0&&A0 == 1'b0) THR = D;end//THR_Status是一个状态信号,由于该状态最终可以被处理器通过总线读取,因此可以将它设置为//8bits,当THR中有数据时为00000001,否则为00000000;// 该信号应该是寄存器信号,无论THR中是否有数据,只要TSR发出一个读信号,那么在// 读信号有效的下一个时钟沿,该信号为空always @(posedge RST or posedge CLK2M) beginif (RST) THR_Status = 8'b00000000;else if (WR == 1'b0 && THR_Read == 1'b1 &&A0 == 1'b0) THR_Status = 8'b00000001;else if (WR == 1'b1 && THR_Read == 1'b0) THR_Status = 8'b00000000;endalways @(Count8) beginif (Count8 == 3'b000) THR_Read = 1'b0;else THR_Read = 1'b1;endalways @(posedge RST or posedge CLK2M) beginif (RST) Count8 = 3'b000;else if (~FS) Count8 = 3'b111;else if (TSR_Shift_EN)Count8 = Count8 - 1;endassign D = (RD == 1'b0 &&A0 == 1'b0)?THR_Status:8'bzzzzzzzz;endmodule