logo资料库

RS232串口设计详细揭秘.pdf

第1页 / 共10页
第2页 / 共10页
第3页 / 共10页
第4页 / 共10页
第5页 / 共10页
第6页 / 共10页
第7页 / 共10页
第8页 / 共10页
资料共10页,剩余部分请下载后查看
一、文档说明
1.1编写目的
1.2适用范围
1.3版本说明
1.4对应程序版本
1.5参考文档
项目说明
2.1功能概括
2.2项目设计思路
2.2.1串口接收模块设计
2.2.2串口发送模块设计
2.3项目代码
特别提醒 #1
特别提醒 #2
【开源骚客(微信号:OpenSoc)】公众号 免费分享 FPGA 项目 RS-232 接口设计 一、文档说明 1.1 编写目的 建立通用 RS-232 接口模块,增强移植性。 1.2 适用范围 1.3 版本说明 版本号 V1.0 日期 2016-01-19 作者 Kevin 历史记录 初次版本 1.4 对应程序版本 1.5 参考文档 二、项目说明 2.1 功能概括 串口设置:9600bps,数据位 8 位,停止位 1 位,无校验位。 该项目代码已实现串口的收发功能,可以实现回环测试,并可移植到其他应 用 RS232 接口的项目,可移植性良好。 新手学习 FPGA 成长日记:http://dengkanwen.com
【开源骚客(微信号:OpenSoc)】公众号 免费分享 FPGA 项目 2.2 项目设计思路 2.2.1 串口接收模块设计 1) 串口接收模块时序设计 2) 串口接收模块思路介绍 a. rx 表示 PC 端的串口发送端(对于 FPGA 端,为串口的接收端),在串口 空闲状态时,rx 一直处于高电平。若 PC 端需要通过串口发送数据,则需 要将 rx 从高拉低,表示串口发送的起始位,接着依次发送 8bit 的数据(最 低位优先),发送完最后 1bit 数据后,rx 保持高电平(无校验位); b. 由于 PC 端与 FPGA 端处于两个时钟域,所以在 FPGA 端需要进行跨时钟 域处理,即对 rx 进行打两拍处理(rx_t,rx_tt),rx_ttt 是 rx 的 3 级寄存 器; rx_flag 是串口处于接收状态的标志信号,rx_flag 拉高的条件是 rx 从空闲 状态发送起始位的下降沿,拉低条件是接收完一帧串口数据(8bit); c. d. baud_cnt 为波特率计数器,FPGA 使用时钟为 50MHz,所以串口发送 1bit 的数据占用的时钟周期为:(1/9600)x109÷20≈5208,该计数器自加的 条件为 rx_flag 为高,当计数满 5207 时,自动清零; f. e. bit_flag 为检测 rx 上串口数据的标志信号,只有当 baud_cnt 计数到 2603 时,bit_flag 才会拉高。选在 baud_cnt 计数器的中间值来检测串口数据, 是为提高检测数据的可靠性; bit_cnt 为已接收一帧串口数据的 bit 数,其自加条件为 bit_flag,当计数 到 8,即表示接收完一帧数据后清零; rx_data 是接收串口数据的寄存器,位宽为 8,该寄存器使用了位拼接操 作,其目的是对接收到的串口数据进行移位,将接收到的 1bit 数据构造 成 8bit 的数据,也可以理解成串转并的一个操作; g. 新手学习 FPGA 成长日记:http://dengkanwen.com
【开源骚客(微信号:OpenSoc)】公众号 免费分享 FPGA 项目 h. po_flag 为接收完一帧串口数据的标志信号,用于提供给外部模块检测接 收到的串口数据,即 rx_data 寄存器的值。 2.2.2 串口发送模块设计 对于串口发送模块,其设计思路与接收模块大同小异,稍微将接收模块的思 想反一下就 OK 了,在此不作介绍,Kevin 将代码分享出来,供读者参考。 2.3 项目代码 1) 顶层模块代码 // ************************************************************************ // Project Name : RS-232 // Author // E-mail : Kevin : deng.kanwen@163.com // Blog Website : http://dengkanwen.com // Create Time : 22:33 2016/01/12 // File Name : // Module Name : uart_top // Called By // Abstract : : // // CopyRight(c) 2016, OpenSoc Studio.. // All Rights Reserved // // ************************************************************************ module uart_top( // system signals input input // UART interface input sclk s_rst_n rx_data , , , output wire tx_data ); //================================================================\ // ========== Define Parameter and Internal Signals =========== //================================================================/ wire [ 7:0] po_data ; 新手学习 FPGA 成长日记:http://dengkanwen.com
【开源骚客(微信号:OpenSoc)】公众号 免费分享 FPGA 项目 wire po_flag ; //============================================================================= //************** Main Code ************** //============================================================================= uart_rx uart_rx_inst( (sclk (s_rst_n (rx_data (po_data (po_flag (sclk (s_rst_n (po_data (po_flag (tx_data .sclk .s_rst_n .rx_data .po_data .po_flag ); uart_tx uart_tx_inst( .sclk .s_rst_n .pi_data .pi_flag .tx_data ); endmodule 2) 串口接收模块代码 ), ), ), ), ) ), ), ), ), ) // ************************************************************************ // Project Name : RS-232 // Author // E-mail : Kevin : deng.kanwen@163.com // Blog Website : http://dengkanwen.com // Create Time : 22:43 2016/01/12 // File Name : // Module Name : uart_top // Called By // Abstract : : // // CopyRight(c) 2016, OpenSoc Studio.. // All Rights Reserved // // ************************************************************************ module uart_rx( // system signals input input sclk s_rst_n , , 新手学习 FPGA 成长日记:http://dengkanwen.com
【开源骚客(微信号:OpenSoc)】公众号 免费分享 FPGA 项目 // others input rx_data output output reg reg [7:0] po_data po_flag ); , , //================================================================\ // ========== Define Parameter and Internal Signals =========== //================================================================/ localparam localparam BAUD_CNT_END = 5207 BAUD_CNT_M = (BAUD_CNT_END+1)/2-1 reg reg reg reg reg reg reg [12:0] [ 3:0] rx1 rx2 rx2_reg rx_flag baud_cnt bit_flag bit_cnt ; ; ; ; ; ; ; ; ; //============================================================================= //************** Main Code ************** //============================================================================= always @(posedge sclk) begin rx1 rx2 <= <= rx2_reg <= rx_data; rx1; rx2; end //定义 rx_flag always @(posedge sclk or negedge s_rst_n) begin if(s_rst_n == 1'b0) rx_flag <= 1'b0; else if(bit_cnt == 4'd8 && bit_flag == 1'b1) rx_flag <= 1'b0; else if(rx2 == 1'b0 && rx2_reg == 1'b1) rx_flag <= 1'b1; end //定义 baud_cnt always @(posedge sclk or negedge s_rst_n) begin if(s_rst_n == 1'b0) 新手学习 FPGA 成长日记:http://dengkanwen.com
【开源骚客(微信号:OpenSoc)】公众号 免费分享 FPGA 项目 baud_cnt <= 13'd0; else if(rx_flag == 1'b1 && baud_cnt == BAUD_CNT_END) baud_cnt <= 13'd0; else if(rx_flag == 1'b1) else baud_cnt baud_cnt <= <= baud_cnt + 1'b1; 13'd0; end //定义 bit_flag always @(posedge sclk or negedge s_rst_n) begin if(s_rst_n == 1'b0) bit_flag <= 1'b0; else if(baud_cnt == BAUD_CNT_M) else bit_flag bit_flag <= <= 1'b1; 1'b0; end //定义 bit_cnt always @(posedge sclk or negedge s_rst_n) begin if(s_rst_n == 1'b0) bit_cnt <= 4'd0; else if(bit_cnt == 4'd8 && bit_flag == 1'b1) bit_cnt <= 4'd0; else if(bit_flag == 1'b1) bit_cnt <= bit_cnt + 1'b1; end //定义 po_data always @(posedge sclk or negedge s_rst_n) begin if(s_rst_n == 1'b0) po_data <= 8'd0; else if(bit_flag == 1'b1 && bit_cnt <= 4'd8 && bit_cnt >= 4'd1) po_data <= {rx2, po_data[7:1]}; end //定义 po_flag always @(posedge sclk or negedge s_rst_n) begin if(s_rst_n == 1'b0) po_flag <= 1'b0; else if(bit_cnt == 4'd8 && bit_flag == 1'b1) po_flag <= 1'b1; else 新手学习 FPGA 成长日记:http://dengkanwen.com
【开源骚客(微信号:OpenSoc)】公众号 免费分享 FPGA 项目 po_flag <= 1'b0; end endmodule 3) 串口发送模块代码 // ************************************************************************ // Project Name : RS-232 // Author // E-mail : Kevin : deng.kanwen@163.com // Blog Website : http://dengkanwen.com // Create Time : 22:43 2016/01/12 // File Name : // Module Name : uart_tx // Called By // Abstract : : // // CopyRight(c) 2016, OpenSoc Studio.. // All Rights Reserved // // ************************************************************************ module uart_tx( // system signals input input // others input input wire wire sclk s_rst_n [ 7:0] pi_data pi_flag output reg tx_data ); , , , , //================================================================\ // ========== Define Parameter and Internal Signals =========== //================================================================/ localparam localparam BAUD_CNT_END BAUD_CNT_M = = 5207 2603 reg reg reg reg reg [12:0] [ 3:0] [ 7:0] tx_flag baud_cnt bit_flag bit_cnt pi_data_reg 新手学习 FPGA 成长日记:http://dengkanwen.com ; ; ; ; ; ; ;
【开源骚客(微信号:OpenSoc)】公众号 免费分享 FPGA 项目 //============================================================================= //************** Main Code ************** //============================================================================= //定义 pi_data_reg always @(posedge sclk or negedge s_rst_n) begin if(s_rst_n == 1'b0) pi_data_reg <= 8'd0; else if(pi_flag == 1'b1) pi_data_reg <= pi_data; end //定义 tx_flag always @(posedge sclk or negedge s_rst_n) begin if(s_rst_n == 1'b0) tx_flag <= 1'b0; else if(baud_cnt == BAUD_CNT_END && bit_cnt == 4'd8) tx_flag <= 1'b0; else if(pi_flag == 1'b1) tx_flag <= 1'b1; end //定义 baud_cnt always @(posedge sclk or negedge s_rst_n) begin if(s_rst_n == 1'b0) baud_cnt <= 13'd0; else if(baud_cnt == BAUD_CNT_END) baud_cnt <= 13'd0; else if(tx_flag == 1'b1) else baud_cnt baud_cnt <= <= baud_cnt + 1'b1; 13'd0; end //定义 bit_flag always @(posedge sclk or negedge s_rst_n) begin if(s_rst_n == 1'b0) bit_flag <= 1'b0; else if(baud_cnt == BAUD_CNT_END) bit_flag <= 1'b1; else end bit_flag <= 1'b0; 新手学习 FPGA 成长日记:http://dengkanwen.com
分享到:
收藏