当前位置:首页 >> 信息与通信 >>

串口通信设计


本 科

实 验

报 告

实验名称: 姓名: 专业: 指导教员: 实验室:

串口通信设计 学号: 队别: 职称: 实验日期: 6 月 9 日

电子技术实验中心制

一、 实验目的
? ?
?

熟悉串口通信的基本

原理; 学习数据串并转换方法; 熟练分频电路实现方法。

二、 实验内容
? ? PC 机以不同波特率(9600B,19200B,38400B)与 FPGA 之间进行数据收 发通信; 通过键盘输入数据给 PC 机, 然后通过串口发送给 FPGA, FPGA 收到数据后 在数码管显示该数据,再将该数据回传给计算机,通过超级终端(或串口小 精灵)显示出来。

三、 实验原理与设计
1. 串行通信的原理
根据同步方式的不同,串行通信又分为两类,异步通信和同步通信。同步通 信时除了需要发送数据线, 接收数据线和信号地线以外, 还需要一根时钟信号线, 时钟信号用于同步数据的发送和接收,传送时是先读取同步位,两设备的同步模 式一样时数据开始传送, 直到送完数据块,发送大的数据块时要周期性的重发同 步字符。同步通信主要是应用于高速数据传送场合。异步通信,数据或字符是一 帧一帧地传送,帧定义为一个字符完整的通信格式,也称为帧格式。它用占用一 位的起始位表示字符的开始,其后是 5 到 8 位数据,规定低位在前,高位在后; 再是奇偶校验位,通过对数据奇偶性的检查,用于判别字符传输的正确性,可选 择三种方式即奇校验、偶校验和无校验;最后用停止位表示字符的结束,可以是 1 位、1.5 位或 2 位。从起始位开始到停止位结束构成完整的一帧,由于异步通 信每传送一帧都有固定的格式,通信双方只要按约定的帧格式来发送和接受数 据,所以硬件结构比同步通信方式简单。此外,它还能利用校验位检测错误,所 以这种通信方式应用较为广泛。 在单片机中主要采用异步通信方式。串行通信的 数据传送速率可以用波特率表示,其意义是每秒传送多少位二进制数。 串行通信时, 要求通讯双方都采用一个物理接口标准,使不同厂家生产的各 种设备可以方便地连接起来进行通讯, 目前应用最为广泛的有 RS-232 和 RS-485 两种。RS-232 是美国电子工业协会 EIA(Electronic Industry Association)制定的 一种串行物理接口标准,是数据终端设备(DTE)和数据通信设备(DCE)之间的接 口标准。该标准规定采用一个 9 引脚的 DB-9 接口,对接口的每个引脚的信号内

容加以规定,还对各种信号的电平加以规定。在日常应用中,一般使用的只有 1 到 4 个引脚,RS-232 标准 9 个引脚 DB-9 的引脚定义如下图所示。

信号地 GND 数据终端就绪 DTR 发送数据 TXD 接收数据 RXD 数据载波检测 CD

5 9 4 8 3 7 2 6 1 RTS 请求发送 DSR 数据设备就绪 RI CTS 振铃指示 允许发送

DB-9 引脚定义图

2. 串口通信的设计 根据 RS232 异步通讯的帧格式 FPGA 数据接收模块中采用的每一帧格式 为:1 位开始位+8 位数据位+1 位结束位,波特率为 9600。该模块首先检测串口数 据的起始位, 在检测到起始位后,每隔一个波特率的时间对串口数据进行一次采 样,并存入寄存器的相应位置,当每一帧的 8 位数据全部写入寄存器后,再统一 输出。

四、 实验结果与分析
将设计程序下载到实验板上运行调试后,最终结果与预期效果基本一致,用 键盘输入字符到串口调试软件, 从串口调试软件发送到实验版上,板上数码管能 正常显示。 此次的 RS232 串行通信设计重在各个模块代码的编写, 虽然能把各个模块的 代码编写出来, 并能正常显示, 但对于各个模块的优化设计还有一定的缺陷和不 足。 总的来说, 通过这次的设计实验更进一步地增强了实验的动手能力, 对 RS232 串行通信的工作原理也有了更加透彻的理解。

五、 总结与结论
通过本实验的学习, 我们获得了不少的知识,为我们后续的学习生活指引了 方向。 回顾这学期, 我从对 QuartusII 不了解到进一步掌握 QuartusII 的使用全 过程, 并进一步懂得了多层次的设计方法,掌握了基本的 Verilog 语言的设计方 法。在这次串口通信实验中,从开始读题到最后完成,期间遇到了好多问题。在 资料收集过程中, 由于我们对串口通信也不是很熟悉,所以需要对串口通信进行 全新的学习。虽然网上资料很多,不过还是都必须要自己能够看得熟悉,理解了 之后才能自己拿来用。最后就是在程序的调试阶段,由于对软件的不熟悉,这个

也花了很长的时间来弄。 不过最终还是得出了满意的结果。 由于自身实力的问题, 没能实现单片机到 PC 机这个方向上的通信, 只能简单的通过 PC 机上的串口调试 助手让数码管显示。这个就是本实验需要改进的地方。通过这次实验设计,让我 进一步熟悉和掌握了 Verilog 语言。除了课本上的知识之外,在人际交流沟通协 作方面也有一定的提升,增强了团队协作能力。

六、 附录(源代码等)
module my_uart_top(clk,rst_n,rs232_rx,rs232_tx,com,shuma);

input clk; // 50MHz 主时钟 input rst_n; //低电平复位信号 input rs232_rx; // RS232 接收数据信号 output rs232_tx; // RS232 发送数据信号 output[3:0] com; // 4 位数码管的 4 个公共端,分别控制 4 个数码管是否 显示 output[7:0] shuma;// 连接到数码管的 7a 6b 5c 4d 3e 2f 1g 0h

wire bps_start; //接收到数据后,波特率时钟启动信号置位 wire clk_bps; // clk_bps 的高电平为接收或者发送数据位的中间采样点 wire[7:0] rx_data; //接收数据寄存器,保存直至下一个数据来到 wire rx_int; //接收数据中断信号,接收到数据期间始终为高电平 //----------------------------------------------------

speed_select speed_select( .clk(clk), //波特率选择模块, 接收和发送模块 复用,不支持全双工通信 .rst_n(rst_n), .bps_start(bps_start), .clk_bps(clk_bps) );

my_uart_rx

my_uart_rx(

.clk(clk), //接收数据模块 .rst_n(rst_n), .rs232_rx(rs232_rx), .clk_bps(clk_bps), .bps_start(bps_start), .rx_data(rx_data), .rx_int(rx_int) );

my_uart_tx

my_uart_tx(

.clk(clk), //发送数据模块 .rst_n(rst_n), .clk_bps(clk_bps), .rx_data(rx_data), .rx_int(rx_int), .rs232_tx(rs232_tx), .bps_start(bps_start) ); .clk(clk), //xianshi --- shumaguan .rst_n(rst_n), .rx_data(rx_data), .com(com), .shuma(shuma) );

my_board_display my_board_display(

endmodule

///////////////////////////////////// my_board_display ///////////////////////////////////// module my_board_display(clk,rst_n,rx_data,com,shuma);

input clk; // 50MHz 主时钟 input rst_n; //低电平复位信号 input[7:0] rx_data; output[6:0] com; output[7:0] shuma;

//数码管显示 0~9 对应段选输出 parameter num0 = 8'b11000000, num1 = 8'b11111001, num2 = 8'b10100100, num3 = 8'b10110000, num4 = 8'b10011001,

num5 num6 num7 num8 num9 reg[6:0] com; reg[7:0] shuma;

= 8'b10010010, = 8'b10000010, = 8'b11111000, = 8'b10000000, = 8'b10010000;

always @ (posedge clk or negedge rst_n) begin if(!rst_n) begin com<= 7'b1111111; end else if(rx_data) begin case (rx_data) 8'h30:shuma<=num0; 8'h31:shuma<=num1; 8'h32:shuma<=num2; 8'h33:shuma<=num3; 8'h34:shuma<=num4; 8'h35:shuma<=num5; 8'h36:shuma<=num6; 8'h37:shuma<=num7; 8'h38:shuma<=num8; 8'h39:shuma<=num9; endcase end else begin shuma<=shuma; com<=7'b1111110; end end

endmodule

///////////////////////////////////// speed_select ///////////////////////////////////// module speed_select(clk,rst_n,bps_start,clk_bps);

input clk; // 50MHz 主时钟 input rst_n; //低电平复位信号 input bps_start; //接收到数据后,波特率时钟启动信号置位 output clk_bps; // clk_bps 的高电平为接收或者发送数据位的中间采样点

parameter

parameter

bps9600 = 5207, //波特率为 9600bps bps19200 = 2603, //波特率为 19200bps bps38400 = 1301, //波特率为 38400bps bps57600 = 867, //波特率为 57600bps bps115200 = 433; //波特率为 115200bps bps9600_2 = 2603, bps19200_2 = 1301, bps38400_2 = 650, bps57600_2 = 433, bps115200_2 = 216;

reg[12:0] bps_para; //分频计数最大值 reg[12:0] bps_para_2; //分频计数的一半 reg[12:0] cnt; //分频计数 reg clk_bps_r; //波特率时钟寄存器

//----------------------------------------------------------

reg[2:0] uart_ctrl; // uart 波特率选择寄存器 //----------------------------------------------------------

always @ (posedge clk or negedge rst_n) begin if(!rst_n) begin uart_ctrl <= 3'd0; //默认波特率为 9600bps end else begin case (uart_ctrl) //波特率设置 3'd0: begin bps_para <= bps9600; bps_para_2 <= bps9600_2; end 3'd1: begin bps_para <= bps19200;

bps_para_2 <= bps19200_2; end 3'd2: begin bps_para <= bps38400; bps_para_2 <= bps38400_2; end 3'd3: begin bps_para <= bps57600; bps_para_2 <= bps57600_2; end 3'd4: begin bps_para <= bps115200; bps_para_2 <= bps115200_2; end default: ; endcase end end

always @ (posedge clk or negedge rst_n) if(!rst_n) cnt <= 13'd0; else if(cnt<bps_para && bps_start) cnt <= cnt+1'b1; 启动 else cnt <= 13'd0;

//波特率时钟计数

always @ (posedge clk or negedge rst_n) if(!rst_n) clk_bps_r <= 1'b0; else if(cnt==bps_para_2 && bps_start) clk_bps_r <= 1'b1; 高电平为接收或者发送数据位的中间采样点 else clk_bps_r <= 1'b0;

// clk_bps_r

assign clk_bps = clk_bps_r; endmodule ///////////////////////////////////////// my_uart_rx ///////////////////////// module my_uart_rx(clk,rst_n,rs232_rx,clk_bps,bps_start,rx_data,rx_int);

input clk; // 50MHz 主时钟 input rst_n; //低电平复位信号

input rs232_rx; // RS232 接收数据信号 input clk_bps; // clk_bps 的高电平为接收或者发送数据位的中间采样点 output bps_start; //接收到数据后,波特率时钟启动信号置位 output[7:0] rx_data; //接收数据寄存器,保存直至下一个数据来到 output rx_int; //接收数据中断信号,接收到数据期间始终为高电平

//---------------------------------------------------------------reg rs232_rx0,rs232_rx1,rs232_rx2; //接收数据寄存器,滤波用 wire neg_rs232_rx; //表示数据线接收到下降沿

always @ (posedge clk or negedge rst_n) begin if(!rst_n) begin rs232_rx0 <= 1'b1; rs232_rx1 <= 1'b1; rs232_rx2 <= 1'b1; end else begin rs232_rx0 <= rs232_rx; rs232_rx1 <= rs232_rx0; rs232_rx2 <= rs232_rx1; end end assign neg_rs232_rx = rs232_rx2 & ~rs232_rx1; // 接 收 到 下 降 沿 后 neg_rs232_rx 置高一个时钟周期

//---------------------------------------------------------------reg bps_start_r; reg[3:0] num; //移位次数 reg rx_int; //接收数据中断信号,接收到数据期间始终为高电平 always @ (posedge clk or negedge rst_n) begin if(!rst_n) begin bps_start_r <= 1'bz; rx_int <= 1'b0; end else if(neg_rs232_rx) begin bps_start_r <= 1'b1; //启动接收数据 rx_int <= 1'b1; //接收数据中断信号使能 end else if(num==4'd12) begin

bps_start_r <= 1'bz; //数据接收完毕 rx_int <= 1'b0; //接收数据中断信号关闭 end end

assign bps_start = bps_start_r;

//---------------------------------------------------------------reg[7:0] rx_data_r; //接收数据寄存器,保存直至下一个数据来到 //---------------------------------------------------------------reg[7:0] rx_temp_data; //但前接收数据寄存器 reg rx_data_shift; //数据移位标志

always @ (posedge clk or negedge rst_n) begin if(!rst_n) begin rx_data_shift <= 1'b0; rx_temp_data <= 8'd0; num <= 4'd0; rx_data_r <= 8'd0; end else if(rx_int) begin //接收数据处理 if(clk_bps) begin //读取并保存数据,接收数据为一个起始位,8bit 数 据,一个结束位 rx_data_shift <= 1'b1; num <= num+1'b1; if(num<=4'd8) rx_temp_data[7] <= rs232_rx; //锁存 9bit (1bit 起始位,8bit 数据) end else if(rx_data_shift) begin //数据移位处理 rx_data_shift <= 1'b0; if(num<=4'd8) rx_temp_data <= rx_temp_data >> 1'b1; //移 位 8 次,第 1bit 起始位移除,剩下 8bit 正好时接收数据 else if(num==4'd12) begin num <= 4'd0; //接收到 STOP 位后结束,num 清零 rx_data_r <= rx_temp_data; //把数据锁存到数据寄 存器 rx_data 中 end end end end

assign rx_data = rx_data_r;

endmodule

///////////////////////////////////// my_uart_tx /////////////////////////////////// module my_uart_tx(clk,rst_n,clk_bps,rx_data,rx_int,rs232_tx,bps_start);

input clk; // 50MHz 主时钟 input rst_n; //低电平复位信号 input clk_bps; // clk_bps 的高电平为接收或者发送数据位的中间采样 点 input[7:0] rx_data; //接收数据寄存器 input rx_int; // 接收数据中断信号,接收到数据期间始终为高电平 ,在次 利用它的下降沿来启动发送数据 output rs232_tx; // RS232 发送数据信号 output bps_start; //接收或者要发送数据,波特率时钟启动信号置位

//--------------------------------------------------------reg rx_int0,rx_int1,rx_int2; //rx_int 信号寄存器,捕捉下降沿滤波用 wire neg_rx_int; // rx_int 下降沿标志位

always @ (posedge clk or negedge rst_n) begin if(!rst_n) begin rx_int0 <= 1'b0; rx_int1 <= 1'b0; rx_int2 <= 1'b0; end else begin rx_int0 <= rx_int; rx_int1 <= rx_int0; rx_int2 <= rx_int1; end end

assign neg_rx_int = ~rx_int1 & rx_int2; 保持一个主时钟周期

//捕捉到下降沿后,neg_rx_int 拉地

//--------------------------------------------------------reg[7:0] tx_data; //待发送数据的寄存器 //--------------------------------------------------------reg bps_start_r; reg tx_en; //发送数据使能信号,高有效 reg[3:0] num;

always @ (posedge clk or negedge rst_n) begin if(!rst_n) begin bps_start_r <= 1'bz; tx_en <= 1'b0; tx_data <= 8'd0; end else if(neg_rx_int) begin //接收数据完毕,准备把接收到的数据发回 去 bps_start_r <= 1'b1; tx_data <= rx_data; //把接收到的数据存入发送数据寄存器 tx_en <= 1'b1; //进入发送数据状态中 end else if(num==4'd11) begin //数据发送完成,复位 bps_start_r <= 1'bz; tx_en <= 1'b0; end end

assign bps_start = bps_start_r; //---------------------------------------------------------

reg rs232_tx_r;

always @ (posedge clk or negedge rst_n) begin if(!rst_n) begin num <= 4'd0; rs232_tx_r <= 1'b1; end else if(tx_en) begin if(clk_bps) begin num <= num+1'b1;

case (num) 4'd0: rs232_tx_r <= 1'b0; //发送起始位 4'd1: rs232_tx_r <= tx_data[0]; //发送 bit0 4'd2: rs232_tx_r <= tx_data[1]; //发送 bit1 4'd3: rs232_tx_r <= tx_data[2]; //发送 bit2 4'd4: rs232_tx_r <= tx_data[3]; //发送 bit3 4'd5: rs232_tx_r <= tx_data[4]; //发送 bit4 4'd6: rs232_tx_r <= tx_data[5]; //发送 bit5 4'd7: rs232_tx_r <= tx_data[6]; //发送 bit6 4'd8: rs232_tx_r <= tx_data[7]; //发送 bit7 4'd9: rs232_tx_r <= 1'b0; //发送结束位 default: rs232_tx_r <= 1'b1; endcase end else if(num==4'd11) num <= 4'd0; end end //复位

assign rs232_tx = rs232_tx_r;

endmodule


相关文章:
串口通信设计
本科 实验 报告 实验名称: 姓名: 专业: 指导教员: 实验室: 串口通信设计 学号: 队别: 职称: 实验日期: 6 月 9 日 电子技术实验中心制 一、 实验目的 ? ...
单片机串口通信课程设计
然后掌握了单片机串口通信、定时器、 数码管动态扫描的原理与应用,学会了 51 单片机常用的寄存器的使用。总体来说,这次课 设我学到了很多。在设计过程中,加深了对...
串口通信程序设计
串口通信程序设计_信息与通信_工程科技_专业资料。 目录 1 引言...目录1 引言......
UART串口通信设计实例
UART串口通信设计实例_电子/电路_工程科技_专业资料。很实用,大家可以验证一下~应该有帮助 2.5 UART 串口通信设计实例(1) 接下来用刚才采用的方法设计一个典型实例...
单片机串口通讯设计
单片机课程设计说明书 1、 设计内容和要求 1.1 设计内容 本设计采用 AT89S52 单片机以及 MAX232 通信芯片配合使用与上位机 (计算 机) 进行串口通讯, 根据上位...
串口通信电路设计
第十一章 制作 PCB 11.1 11.2 设计任务 创建项目文件及工作环境,在右 使用 Protel2004 设计串口通信电路。画出电路原理图和 PCB 板,并生成制造文件。 打开...
基于单片机的串口通信模块设计_图文
基于单片机的串口通信模块设计_电子/电路_工程科技_专业资料。中北大学信息商务学院 2012 届毕业设计说明书 1 绪论 1.1 研究背景 通信是指不同的独立系统利用线路...
嵌入式串口通信设计
湖南文理学院课程设计报告 课程名称: 嵌入式系统课程设计 专业班级: 通信工程 11101 班 学号(2 位) 学生姓名: 指导教师: 完成时间: 报告成绩: 石春波 王丽娟 ...
嵌入式串口通信的设计
嵌入式串口通信设计_信息与通信_工程科技_专业资料。*** 实践教学 *** 兰州理工大学计算机与通信学院 2013 年春季学期 嵌入式系统开发技术课程设计 题 目:嵌入...
嵌入式串口通信的设计
嵌入式串口通信的设计_信息与通信_工程科技_专业资料。串口通信设计*** 实践教学 *** 兰州理工大学计算机与通信学院 2013 年春季学期 嵌入式系统开发技术课程设计...
更多相关标签:
串口通信协议设计 | 串口通信协议的设计 | 串口通信课程设计 | 串口通信 | c 串口通信 | c 串口通信实例 | 串口通信协议 | java 串口通信 |