串口通信设计.docx
- 文档编号:11275467
- 上传时间:2023-02-26
- 格式:DOCX
- 页数:18
- 大小:34.21KB
串口通信设计.docx
《串口通信设计.docx》由会员分享,可在线阅读,更多相关《串口通信设计.docx(18页珍藏版)》请在冰豆网上搜索。
串口通信设计
本科实验报告
实验名称:
串口通信设计
姓名:
学号:
专业:
队别:
指导教员:
职称:
实验室:
实验日期:
6月9日
电子技术实验中心制
一、
实验目的
●熟悉串口通信的基本原理;
●学习数据串并转换方法;
●熟练分频电路实现方法。
二、实验内容
●PC机以不同波特率(9600B,19200B,38400B)与FPGA之间进行数据收发通信;
●通过键盘输入数据给PC机,然后通过串口发送给FPGA,FPGA收到数据后在数码管显示该数据,再将该数据回传给计算机,通过超级终端(或串口小精灵)显示出来。
三、实验原理与设计
1.串行通信的原理
根据同步方式的不同,串行通信又分为两类,异步通信和同步通信。
同步通信时除了需要发送数据线,接收数据线和信号地线以外,还需要一根时钟信号线,时钟信号用于同步数据的发送和接收,传送时是先读取同步位,两设备的同步模式一样时数据开始传送,直到送完数据块,发送大的数据块时要周期性的重发同步字符。
同步通信主要是应用于高速数据传送场合。
异步通信,数据或字符是一帧一帧地传送,帧定义为一个字符完整的通信格式,也称为帧格式。
它用占用一位的起始位表示字符的开始,其后是5到8位数据,规定低位在前,高位在后;再是奇偶校验位,通过对数据奇偶性的检查,用于判别字符传输的正确性,可选择三种方式即奇校验、偶校验和无校验;最后用停止位表示字符的结束,可以是1位、1.5位或2位。
从起始位开始到停止位结束构成完整的一帧,由于异步通信每传送一帧都有固定的格式,通信双方只要按约定的帧格式来发送和接受数据,所以硬件结构比同步通信方式简单。
此外,它还能利用校验位检测错误,所以这种通信方式应用较为广泛。
在单片机中主要采用异步通信方式。
串行通信的数据传送速率可以用波特率表示,其意义是每秒传送多少位二进制数。
串行通信时,要求通讯双方都采用一个物理接口标准,使不同厂家生产的各种设备可以方便地连接起来进行通讯,目前应用最为广泛的有RS-232和RS-485两种。
RS-232是美国电子工业协会EIA(ElectronicIndustryAssociation)制定的一种串行物理接口标准,是数据终端设备(DTE)和数据通信设备(DCE)之间的接口标准。
该标准规定采用一个9引脚的DB-9接口,对接口的每个引脚的信号内容加以规定,还对各种信号的电平加以规定。
在日常应用中,一般使用的只有1到4个引脚,RS-232标准9个引脚DB-9的引脚定义如下图所示。
DB-9引脚定义图
2.串口通信的设计
根据RS232异步通讯的帧格式FPGA数据接收模块中采用的每一帧格式为:
1位开始位+8位数据位+1位结束位,波特率为9600。
该模块首先检测串口数据的起始位,在检测到起始位后,每隔一个波特率的时间对串口数据进行一次采样,并存入寄存器的相应位置,当每一帧的8位数据全部写入寄存器后,再统一输出。
四、实验结果与分析
将设计程序下载到实验板上运行调试后,最终结果与预期效果基本一致,用键盘输入字符到串口调试软件,从串口调试软件发送到实验版上,板上数码管能正常显示。
此次的RS232串行通信设计重在各个模块代码的编写,虽然能把各个模块的代码编写出来,并能正常显示,但对于各个模块的优化设计还有一定的缺陷和不足。
总的来说,通过这次的设计实验更进一步地增强了实验的动手能力,对RS232串行通信的工作原理也有了更加透彻的理解。
五、总结与结论
通过本实验的学习,我们获得了不少的知识,为我们后续的学习生活指引了方向。
回顾这学期,我从对QuartusII不了解到进一步掌握QuartusII的使用全过程,并进一步懂得了多层次的设计方法,掌握了基本的Verilog语言的设计方法。
在这次串口通信实验中,从开始读题到最后完成,期间遇到了好多问题。
在资料收集过程中,由于我们对串口通信也不是很熟悉,所以需要对串口通信进行全新的学习。
虽然网上资料很多,不过还是都必须要自己能够看得熟悉,理解了之后才能自己拿来用。
最后就是在程序的调试阶段,由于对软件的不熟悉,这个也花了很长的时间来弄。
不过最终还是得出了满意的结果。
由于自身实力的问题,没能实现单片机到PC机这个方向上的通信,只能简单的通过PC机上的串口调试助手让数码管显示。
这个就是本实验需要改进的地方。
通过这次实验设计,让我进一步熟悉和掌握了Verilog语言。
除了课本上的知识之外,在人际交流沟通协作方面也有一定的提升,增强了团队协作能力。
六、附录(源代码等)
modulemy_uart_top(clk,rst_n,rs232_rx,rs232_tx,com,shuma);
inputclk;//50MHz主时钟
inputrst_n;//低电平复位信号
inputrs232_rx;//RS232接收数据信号
outputrs232_tx;//RS232发送数据信号
output[3:
0]com;//4位数码管的4个公共端,分别控制4个数码管是否显示
output[7:
0]shuma;//连接到数码管的7a6b5c4d3e2f1g0h
wirebps_start;//接收到数据后,波特率时钟启动信号置位
wireclk_bps;//clk_bps的高电平为接收或者发送数据位的中间采样点
wire[7:
0]rx_data;//接收数据寄存器,保存直至下一个数据来到
wirerx_int;//接收数据中断信号,接收到数据期间始终为高电平
//----------------------------------------------------
speed_selectspeed_select(.clk(clk),//波特率选择模块,接收和发送模块复用,不支持全双工通信
.rst_n(rst_n),
.bps_start(bps_start),
.clk_bps(clk_bps)
);
my_uart_rxmy_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_txmy_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)
);
my_board_displaymy_board_display(.clk(clk),//xianshi---shumaguan
.rst_n(rst_n),
.rx_data(rx_data),
.com(com),
.shuma(shuma)
);
endmodule
/////////////////////////////////////my_board_display/////////////////////////////////////
modulemy_board_display(clk,rst_n,rx_data,com,shuma);
inputclk;//50MHz主时钟
inputrst_n;//低电平复位信号
input[7:
0]rx_data;
output[6:
0]com;
output[7:
0]shuma;
//数码管显示0~9对应段选输出
parameternum0=8'b11000000,
num1=8'b11111001,
num2=8'b10100100,
num3=8'b10110000,
num4=8'b10011001,
num5=8'b10010010,
num6=8'b10000010,
num7=8'b11111000,
num8=8'b10000000,
num9=8'b10010000;
reg[6:
0]com;
reg[7:
0]shuma;
always@(posedgeclkornegedgerst_n)
begin
if(!
rst_n)
begin
com<=7'b1111111;
end
elseif(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/////////////////////////////////////
modulespeed_select(clk,rst_n,bps_start,clk_bps);
inputclk;//50MHz主时钟
inputrst_n;//低电平复位信号
inputbps_start;//接收到数据后,波特率时钟启动信号置位
outputclk_bps;//clk_bps的高电平为接收或者发送数据位的中间采样点
parameterbps9600=5207,//波特率为9600bps
bps19200=2603,//波特率为19200bps
bps38400=1301,//波特率为38400bps
bps57600=867,//波特率为57600bps
bps115200=433;//波特率为115200bps
parameterbps9600_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;//分频计数
regclk_bps_r;//波特率时钟寄存器
//----------------------------------------------------------
reg[2:
0]uart_ctrl;//uart波特率选择寄存器
//----------------------------------------------------------
always@(posedgeclkornegedgerst_n)begin
if(!
rst_n)begin
uart_ctrl<=3'd0;//默认波特率为9600bps
end
elsebegin
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@(posedgeclkornegedgerst_n)
if(!
rst_n)cnt<=13'd0;
elseif(cnt elsecnt<=13'd0; always@(posedgeclkornegedgerst_n) if(! rst_n)clk_bps_r<=1'b0; elseif(cnt==bps_para_2&&bps_start)clk_bps_r<=1'b1;//clk_bps_r高电平为接收或者发送数据位的中间采样点 elseclk_bps_r<=1'b0; assignclk_bps=clk_bps_r; endmodule /////////////////////////////////////////my_uart_rx///////////////////////// modulemy_uart_rx(clk,rst_n,rs232_rx,clk_bps,bps_start,rx_data,rx_int); inputclk;//50MHz主时钟 inputrst_n;//低电平复位信号 inputrs232_rx;//RS232接收数据信号 inputclk_bps;//clk_bps的高电平为接收或者发送数据位的中间采样点 outputbps_start;//接收到数据后,波特率时钟启动信号置位 output[7: 0]rx_data;//接收数据寄存器,保存直至下一个数据来到 outputrx_int;//接收数据中断信号,接收到数据期间始终为高电平 //---------------------------------------------------------------- regrs232_rx0,rs232_rx1,rs232_rx2;//接收数据寄存器,滤波用 wireneg_rs232_rx;//表示数据线接收到下降沿 always@(posedgeclkornegedgerst_n)begin if(! rst_n)begin rs232_rx0<=1'b1; rs232_rx1<=1'b1; rs232_rx2<=1'b1; end elsebegin rs232_rx0<=rs232_rx; rs232_rx1<=rs232_rx0; rs232_rx2<=rs232_rx1; end end assignneg_rs232_rx=rs232_rx2&~rs232_rx1;//接收到下降沿后neg_rs232_rx置高一个时钟周期 //---------------------------------------------------------------- regbps_start_r; reg[3: 0]num;//移位次数 regrx_int;//接收数据中断信号,接收到数据期间始终为高电平 always@(posedgeclkornegedgerst_n)begin if(! rst_n)begin bps_start_r<=1'bz; rx_int<=1'b0; end elseif(neg_rs232_rx)begin bps_start_r<=1'b1;//启动接收数据 rx_int<=1'b1;//接收数据中断信号使能 end elseif(num==4'd12)begin bps_start_r<=1'bz;//数据接收完毕 rx_int<=1'b0;//接收数据中断信号关闭 end end assignbps_start=bps_start_r; //---------------------------------------------------------------- reg[7: 0]rx_data_r;//接收数据寄存器,保存直至下一个数据来到 //---------------------------------------------------------------- reg[7: 0]rx_temp_data;//但前接收数据寄存器 regrx_data_shift;//数据移位标志 always@(posedgeclkornegedgerst_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 elseif(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 elseif(rx_data_shift)begin//数据移位处理 rx_data_shift<=1'b0; if(num<=4'd8)rx_temp_data<=rx_temp_data>>1'b1;//移位8次,第1bit起始位移除,剩下8bit正好时接收数据 elseif(num==4'd12)begin num<=4'd0;//接收到STOP位后结束,num清零 rx_data_r<=rx_temp_data;//把数据锁存到数据寄存器rx_data中 end end end end assignrx_data=rx_data_r; endmodule /////////////////////////////////////my_uart_tx/////////////////////////////////// modulemy_uart_tx(clk,rst_n,clk_bps,rx_data,rx_int,rs232_tx,bps_start); inputclk;//50MHz主时钟 inputrst_n;//低电平复位信号 inputclk_bps;//clk_bps的高电平为接收或者发送数据位的中间采样点 input[7: 0]rx_data;//接收数据寄存器 inputrx_int;//接收数据中断信号,接收到数据期间始终为高电平,在次利用它的下降沿来启动发送数据 outputrs232_tx;//RS232发送数据信号 outputbps_start;//接收或者要发送数据,波特率时钟启动信号置位 //--------------------------------------------------------- regrx_int0,rx_int1,rx_int2;//rx_int信号寄存器,捕捉下降沿滤波用 wireneg_rx_int;//rx_int下降沿标志位 always@(posedgeclkornegedgerst_n)begin if(! rst_n)begin rx_int0<=1'b0; rx_int1<=1'b0; rx_int2<=1'b0; end elsebegin rx_int0<=rx_int; rx_int1<=rx_int0; rx_int2<=rx_int1; end end assignneg_rx_int=~rx_int1&rx_int2;//捕捉到下降沿后,neg_rx_int拉地保持一个主时钟周期 //--------------------------------------------------------- reg[7: 0]tx_data;//待发送数据的寄存器 //--------------------------------------------------------- regbps_start_r; regtx_en;//发送数据使能信号,高有效 reg[3: 0]num; always@(posedgeclkornegedgerst_n)begin if(! rst_n)begin bps_start_r<=1'bz; tx_en<=1'b0; tx_data<=8'd0; end elseif(neg_rx_int)begin//接收数据完毕,准备把接收到的数据发回去 bps_start_r<=1'b1; tx_data<=rx_data;//把接收到的数据存入发送数据寄存器 tx_en<=1'b1;//进入发送数据状态中 end elseif(num==4'd11)begin//数据发送完成,复位 bps_start_r<=1'bz; tx_en<=1'b0; end end assignbps_start=bps_start_r; //--------------------------------------------------------- regrs232_tx_r; always@(posedgeclkornegedgerst_n)begin if(! rst
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 串口 通信 设计
![提示](https://static.bdocx.com/images/bang_tan.gif)