大作业RS232串口驱动.docx
- 文档编号:30446997
- 上传时间:2023-08-15
- 格式:DOCX
- 页数:14
- 大小:135.63KB
大作业RS232串口驱动.docx
《大作业RS232串口驱动.docx》由会员分享,可在线阅读,更多相关《大作业RS232串口驱动.docx(14页珍藏版)》请在冰豆网上搜索。
大作业RS232串口驱动
大作业:
RS232串口驱动
Verilog设计
实验报告
计算机学院
1203121857
闫林
周六晚上机——第五批
1.1实验内容
本实验要为最后一次大实验。
为自选实验。
本人选择驱动TerasicDE0开发板上的RS232串口作为最后一次大的作业。
本实验使用友晶科技的De0开发板进行实验。
使用cycloneIIIEP3C16F484FPGA芯片。
1.2试验要求
使用Verilog语言驱动开发板上的rs232模块,使之能够与计算机进行通信。
串口的通信速率设为9600HZ,每次传送8bit,没有校验位,空闲位的长度为1。
1.3设计说明
RS232使用如下的电平标准进行通信。
图1RS232通信协议
空闲状态下,电路一直保持低电平,当有数据需要发送时,电平拉高一个周期。
接下来为8个数据位,最后为一个周期的结束低电平。
这一过程可以用状态机进行表示。
由于DE0开发版的空间有限,所以并没有RS232使用的标准DB9口
只保留了引脚进行使用
。
因此试验中使用到了USB转TTL的转换线进行与计算机的连接。
如下图所示。
在试验过程中,为简便实验的实现过程,只是用了发送(TXD)和接收(TXD)两条线。
也就是下图中的第2、3两根线。
为了验证程序的正确性,程序将接收到的数据传送到发送端。
因此,在FPGA开发板和计算机之间形成了一个回环的网络。
网络拓补如下图所示:
1.4源程序
●顶层测试模块:
modulers232_tb(
inputCLK_50M,
inputRX,
outputTX,
output[9:
0]LEDG
);
wirerx_vld;
wire[7:
0]rx_data;
assignLEDG[7:
0]=rx_data[7:
0];
assignLEDG[9]=rx_vld;
RS232_RX#(.baud(9600),.mhz(50))rx_232
(
.clock(CLK_50M),
.reset(0),
.RS232_DCE_RXD(RX),
.rx_vld(rx_vld),
.receive_data(rx_data)
);
wiretx_vld;
wire[7:
0]tx_data;
assigntx_vld=rx_vld;
assigntx_data=rx_data;
RS232_TX#(.baud(9600),.mhz(50))tx_232
(
.clock(CLK_50M),
.reset(0),
.RS232_DCE_TXD(TX),
.tx_vld(tx_vld),
.transmit_data(tx_data),
.tx_rdy(LEDG[8])
);
endmodule
●发送模块:
moduleRS232_TX
#(
parameterbaud=9600,mhz=50
)
(
inputclock,
inputreset,
outputregRS232_DCE_TXD,
input[7:
0]transmit_data,
inputtx_vld,
outputregtx_rdy
);
parametertxd_bit_per=(mhz*1_000_000)/baud;
//--StateDefinitions--
parameterst_ready=2'b00;
parameterst_start_bit=2'b01;
parameterst_data_bits=2'b10;
parameterst_stop_bit=2'b11;
reg[1:
0]state=st_ready;
reg[1:
0]n_state=st_ready;
reg[31:
0]counter;
reg[31:
0]n_counter;
reg[2:
0]data_bit_count;
reg[2:
0]n_data_bit_count;
reg[7:
0]tx_data;
//transmitproc
always@(*)
begin
n_state<=state;
n_counter<=counter;
n_data_bit_count<=data_bit_count;
if(reset==1'b1)
RS232_DCE_TXD<=1'b0;
else
case(state)
st_ready:
begin
if(tx_vld==1'b1)begin
tx_rdy<=1'b0;
tx_data<=transmit_data;
n_state<=st_start_bit;
end
elsebegin
RS232_DCE_TXD<=1'b0;
tx_rdy<=1'b1;
n_state<=st_ready;
n_counter<=0;
n_data_bit_count<=0;
end
end
st_start_bit:
begin
if(counter==txd_bit_per)begin
n_counter<=0;
n_state<=st_data_bits;
n_data_bit_count<=0;
end
elsebegin
RS232_DCE_TXD<=1'b1;
n_state<=st_start_bit;
n_counter<=counter+1;
end
end
st_data_bits:
begin
if(counter==txd_bit_per)begin
n_counter<=0;
n_data_bit_count<=data_bit_count+1;
if(data_bit_count==7)begin
n_state<=st_stop_bit;
endelse
n_state<=st_data_bits;
end
elsebegin
n_counter<=counter+1;
RS232_DCE_TXD<=~tx_data[data_bit_count];
n_state<=st_data_bits;
end
end
st_stop_bit:
begin
if(counter==txd_bit_per)
n_state<=st_ready;
elsebegin
RS232_DCE_TXD<=1'b0;
n_state<=st_stop_bit;
n_counter<=counter+1;
end
end
endcase
end
//clockproc
always@(posedgeclockorposedgereset)begin
if(reset==1)begin
state<=st_ready;
counter<=0;
data_bit_count<=0;
end
elsebegin
state<=n_state;
counter<=n_counter;
data_bit_count<=n_data_bit_count;
end
end
endmodule
●接收模块:
moduleRS232_RX
#(
parameterbaud=9600,mhz=50
)
(
inputclock,
inputreset,
inputRS232_DCE_RXD,
output[7:
0]receive_data,
outputregrx_vld
);
parameterrcv_bit_per=(mhz*1_000_000)/baud;
parameterhalf_rcv_bit_per=rcv_bit_per/2;
//--StateDefinitions--
parameterst_ready=2'b00;
parameterst_start_bit=2'b01;
parameterst_data_bits=2'b10;
parameterst_stop_bit=2'b11;
reg[31:
0]counter;
reg[31:
0]n_counter;
reg[2:
0]data_bit_count;
reg[2:
0]n_data_bit_count;
reg[7:
0]rcv_sr;
reg[7:
0]n_rcv_sr;
reg[1:
0]state;
reg[1:
0]n_state;
assignreceive_data=rcv_sr;
//receiveproc
always@(*)
begin
n_rcv_sr<=rcv_sr;
n_state<=state;
n_counter<=counter;
n_data_bit_count<=data_bit_count;
rx_vld<=0;
if(reset==1)
n_rcv_sr<=0;
else
case(state)
st_ready:
begin
n_counter<=0;
n_data_bit_count<=0;
if(RS232_DCE_RXD==1)
n_state<=st_start_bit;
end
st_start_bit:
begin
if(counter==half_rcv_bit_per)begin
n_counter<=0;
n_state<=st_data_bits;
n_data_bit_count<=0;
end
elsebegin
n_counter<=counter+1;
end
end
st_data_bits:
begin
if(counter==rcv_bit_per)begin
n_counter<=0;
n_rcv_sr<={~RS232_DCE_RXD,rcv_sr[7:
1]};
n_data_bit_count<=data_bit_count+1;
if(data_bit_count==7)begin
rx_vld<=1'b1;
n_state<=st_stop_bit;
end
end
else
n_counter<=counter+1;
end
st_stop_bit:
begin
if(counter==rcv_bit_per)//shouldbe1/2stop_bitperiod
n_state<=st_ready;
else
n_counter<=counter+1;
end
endcase
end
//clockproc
always@(posedgeclockorposedgereset)begin
if(reset==1)begin
state<=st_ready;
rcv_sr<=0;
counter<=0;
data_bit_count<=0;
end
elsebegin
state<=n_state;
rcv_sr<=n_rcv_sr;
counter<=n_counter;
data_bit_count<=n_data_bit_count;
end
end
endmodule
1.5程序结果
使用USB转串口TTL线进行连接之后,就可以进行数据传送接收的验证。
上图为数据的发送和接收验证结果。
发送端(Transmit)的结果被接收端所接收。
1.6总结体会
RS232串口是试验中经常用到的器件,使用RS232串口能够随时输出试验中的结果,对进行相应的调试是非常有帮助的。
实验中遇到了最棘手的问题是:
通常情况下,串口的空闲时会保持高电平,开始发送时才会改变为一个周期的低电平,接下来便是数据的传送。
但这只是的情况,我就遇到了‘不通常’的情况(串口的空闲时会保持低电平,开始发送时才会发送为一个周期的高电平,接下来是数据的传送)。
如果没有解决这个问题的话,保持高电平,就会持续接收到数据。
解决了这个问题后又有了新的问题,发送和接收的数据的每一个bit位都是翻转的,解决这个问题并不复杂(只需要进行翻转即可),但为什么空闲时的翻转也会造成数据的翻转?
查阅了很多资料都没有找到合理的解释,很有可能是器件的原因。
所以还希望老师给与解答!
早在大二的《计算机组成原理》课程的学习时,我就了解了RS232串口的相关知识,当时感觉232的通信协议很简单,没有什么复杂的地方,知道实现了才发现并不是那么简单,当然,这也有我Verilog编程经验不足的因素。
正如古人说的那样“纸上来得终觉浅,绝知此事要躬行”。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 作业 RS232 串口 驱动