FPGA串口通信Word下载.docx
- 文档编号:3912720
- 上传时间:2023-05-02
- 格式:DOCX
- 页数:37
- 大小:105.97KB
FPGA串口通信Word下载.docx
《FPGA串口通信Word下载.docx》由会员分享,可在线阅读,更多相关《FPGA串口通信Word下载.docx(37页珍藏版)》请在冰点文库上搜索。
reg
TxD;
reg[7:
0]
TxD_dataReg;
//寄存器发送模式,因为在串口发送过程中输入端不可能一直保持有效电平
reg[3:
state;
parameter
ClkFrequency=25000000;
//时钟频率-25MHz
Baud=115200;
//串口波特率-115200
//波特率产生
parameterBaudGeneratorAccWidth=16;
[BaudGeneratorAccWidth:
0]BaudGeneratorAcc;
wire[BaudGeneratorAccWidth:
0]BaudGeneratorInc=((Baud<
<
(BaudGeneratorAccWidth-4))+(ClkFrequency>
>
5))/(ClkFrequency>
4);
wireBaudTick=BaudGeneratorAcc[BaudGeneratorAccWidth];
wireTxD_busy;
always@(posedgeclkornegedgerst)
if(~rst)
BaudGeneratorAcc<
=0;
elseif(TxD_busy)
=BaudGeneratorAcc[BaudGeneratorAccWidth-1:
0]+BaudGeneratorInc;
//发送端状态
wire
TxD_ready=(state==0);
//当state=0时,处于准备空闲状态,TxD_ready=1
assignTxD_busy=~TxD_ready;
//空闲状态时TxD_busy=0
//把待发送数据放入缓存寄存器TxD_dataReg
TxD_dataReg<
=8'
b00000000;
elseif(TxD_ready&
TxD_start)
TxD_dataReg<
=TxD_data;
//发送状态机
if(~rst)
begin
state<
=4'
b0000;
//复位时,状态为0000,发送端一直发1电平
TxD<
=1'
b1;
end
else
case(state)
4'
b0000:
if(TxD_start)begin
b0100;
//接受到发送信号,进入发送状态
b0100:
if(BaudTick)begin
b1000;
//发送开始位-0电平
b0;
b1000:
b1001;
//bit0
=TxD_dataReg[0];
b1001:
b1010;
//bit1
=TxD_dataReg[1];
b1010:
b1011;
//bit2
=TxD_dataReg[2];
b1011:
b1100;
//bit3
=TxD_dataReg[3];
b1100:
b1101;
//bit4
=TxD_dataReg[4];
b1101:
b1110;
//bit5
=TxD_dataReg[5];
b1110:
b1111;
//bit6
=TxD_dataReg[6];
b1111:
b0010;
//bit7
=TxD_dataReg[7];
b0010:
b0011;
//stop1
b0011:
//stop2
default:
endcase
endmodule
接收端:
modulercv(clk,
RxD,
RxD_data,
RxD_data_ready,
RxD;
output[7:
0]RxD_data;
//接收数据寄存器
output
RxD_data_ready;
//接收完8位数据,RxD_data值有效时,RxD_data_ready输出读信号
//时钟频率-25MHz
//波特率-115200
reg[2:
bit_spacing;
reg
RxD_delay;
RxD_start;
reg[3:
reg[7:
RxD_data;
//波特率产生,使用8倍过采样
parameterBaud8=Baud*8;
parameterBaud8GeneratorAccWidth=16;
wire
[Baud8GeneratorAccWidth:
0]Baud8GeneratorInc=((Baud8<
(Baud8GeneratorAccWidth-7))+(ClkFrequency>
8))/(ClkFrequency>
7);
0]Baud8GeneratorAcc;
Baud8GeneratorAcc<
else
=Baud8GeneratorAcc[Baud8GeneratorAccWidth-1:
0]+Baud8GeneratorInc;
//Baud8Tick为波特率的8倍-115200*8=921600
Baud8Tick=Baud8GeneratorAcc[Baud8GeneratorAccWidth];
//next_bit为波特率-115200
if(~rst||(state==0))
bit_spacing<
elseif(Baud8Tick)
bit_spacing<
=bit_spacing+1;
wirenext_bit=(bit_spacing==7);
//检测到RxD有下跳沿时,RxD_start置1,准备接收数据
always@(posedgeclk)
if(Baud8Tick)
begin
RxD_delay<
=RxD;
RxD_start<
=(Baud8Tick&
RxD_delay&
(~RxD));
end
//状态机接收数据
always@(posedgeclkornegedgerst)
case(state)
4'
if(RxD_start)state<
//检测到下跳沿
if(next_bit)
b0001;
b0001:
//停止位
default:
endcase
//保存接收数据到RxD_data中
RxD_data<
elseif(Baud8Tick&
&
next_bit&
state[3])
RxD_data<
={RxD,RxD_data[7:
1]};
//RxD_data_ready置位信号
RxD_data_ready<
else
state==4'
b0001);
为了测试收发是否正常,写的TestBench
`timescale1ns/1ns
modulers232_test;
TxD_data;
wire[7:
RxD_data;
//RxD,
TxD_busy,
transtrans(.clk(clk),
.rst(rst),
.TxD_start(TxD_start),
.TxD_busy(TxD_busy),
.TxD_data(TxD_data),
.TxD(TxD)
);
rcvrcv(.clk(clk),
.RxD(TxD),
//收发相接时RxD=TxD
.RxD_data(RxD_data),
.RxD_data_ready(RxD_data_ready)
initial
TxD_start=0;
TxD_data=0;
clk=0;
rst=1;
#54rst=0;
#70rst=1;
#40TxD_start=1'
#10TxD_data=8'
b11011001;
#100TxD_start=1'
alwaysbegin
#30clk=~clk;
#10clk=~clk;
二、综合
三、
FPGA与PC串口自收发通信
串口通信其实简单实用,这里我就不多说,只把自己动手写的verilog代码共享下。
实现的功能如题,就是FPGA里实现从PC接收数据,然后把接收到的数据发回去。
使用的是串口UART协议进行收发数据。
上位机用的是老得掉牙的串口调试助手,如下:
发送数据的波特率可选9600bps,19200bps,38400bps,57600bps,115200bps等,是可调的。
发送格式为:
1bit起始位,8bit数据,1bit停止位,无校验位。
以下的代码有比较详细的注释,经过下载验证,存在误码率(<
5%),仅供学习!
代码如下:
(顶层模块):
modulemy_uart_top(clk,rst_n,rs232_rx,rs232_tx);
inputclk;
//50MHz主时钟
inputrst_n;
//低电平复位信号
inputrs232_rx;
//RS232接收数据信号
outputrs232_tx;
//RS232发送数据信号
wirebps_start;
//接收到数据后,波特率时钟启动信号置位
wireclk_bps;
//clk_bps的高电平为接收或者发送数据位的中间采样点
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),//接收数据模块
.rs232_rx(rs232_rx),
.clk_bps(clk_bps),
.rx_data(rx_data),
.rx_int(rx_int)
my_uart_txmy_uart_tx(.clk(clk),//发送数据模块
.rx_int(rx_int),
.rs232_tx(rs232_tx),
.bps_start(bps_start)
modulespeed_select(clk,rst_n,bps_start,clk_bps);
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;
//分频计数最大值
0]bps_para_2;
//分频计数的一半
0]cnt;
//分频计数
regclk_bps_r;
//波特率时钟寄存器
//----------------------------------------------------------
0]uart_ctrl;
//uart波特率选择寄存器
always@(posedgeclkornegedgerst_n)begin
if(!
rst_n)begin
uart_ctrl<
=3'
d0;
//默认波特率为9600bps
end
elsebegin
case(uart_ctrl)//波特率设置
3'
d0:
bps_para<
=bps9600;
bps_para_2<
=bps9600_2;
end
d1:
=bps19200;
=bps19200_2;
d2:
=bps38400;
bps_p
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- FPGA 串口 通信