首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

FPGA实现RS232 串口通信(2)

FPGA实现RS232 串口通信(2)

两个频率很接近,可以采 用下面程序产生我们要的波特率。

// 10 bits for the accumulator ([9:0]), and one  extra bit for the accumulator carry-out ([10])
reg [10:0] acc;   
// 11 bits  total!

always @(posedge clk)
  acc <=  acc[9:0] + 59;


// use  only 10 bits from the previous result, but save the full 11 bits

wire  BaudTick = acc[10]; // so that the 11th bit  is the carry-out

当系统时钟为2MHz的时候,计算得到的波特率的值为115234,与115200只有0.03%的误差。

我们怎么得到“59”呢,可以看下面的推导



其中Baud<<BaudGeneratorAccWidthBaud左移BaudGeneratorAccWidth位,相当于Baud乘以2BaudGeneratorAccWidth次方。

参照上面的程序与公式推导可以把程序修改如下:

parameter ClkFrequency = 25000000; // 25MHz
parameter  Baud = 115200;
parameter BaudGeneratorAccWidth = 16;
parameter  BaudGeneratorInc = (Baud<<BaudGeneratorAccWidth)/ClkFrequency;

reg  [BaudGeneratorAccWidth:0] BaudGeneratorAcc;
always @(posedge  clk)
  BaudGeneratorAcc <=  BaudGeneratorAcc[BaudGeneratorAccWidth-1:0] + BaudGeneratorInc;

wire  BaudTick = BaudGeneratorAcc[BaudGeneratorAccWidth];



当要注意的是,上面程序中BaudGeneratorInc的计算公式出错,因为在Verilog语言中中间结果只能32位,而这个公式计算的结果超过了32位。所以要把这行改为

parameter BaudGeneratorInc =  ((Baud<<(BaudGeneratorAccWidth-4))+(ClkFrequency>>5))/(ClkFrequency>>4);  







程序改变,得到的波 特率不变。



RS232发 送接收模块


可以参考下面文档,这里就不贴出来了。

http://attach.baisi.net/getattach.php?a=RS-232%B7%A2%CB%CD%C4%A3%BF%E9.rar&b=forumid_218%2F20080615_0eac2a17adb0faa0cae54LXO9jwRbJpE.rar&c=application%2Foctet-stream  


RS232发送模块(Verilog

RS232接收模块(Verilog

以上程序均标注了J



调用串口发送接收模块

`timescale  1ns / 1ps


module  serialfun(clk, RxD, TxD);
input  clk;
//系统时钟



input  RxD;
output  TxD;


//////////////////////////////////////////////////
wire  RxD_data_ready;
wire  [7:0] RxD_data;


async_receiver  deserializer(
//RS-232接收模块


.clk(clk),


.RxD(RxD),  


.RxD_data_ready(RxD_data_ready),  

//当接收到一个字节的数据时,"RxD_data_ready"有效一个周期


.RxD_data(RxD_data)
//接收一个字节数据


);



///////////////////////////////////////////////////
async_transmitter  serializer(
//RS-232发送模块


.clk(clk),



.TxD(TxD),


.TxD_start(RxD_data_ready),

//"TxD_start"置位后开始传输


.TxD_data(RxD_data)
//发送一个字节数据


);



endmodule


这个程序的结果是在从计算机发送 八个字节到FPGAFPGA再把这八个字节转发回计算机。

要注意是如果以十六进制发送的话,就要以十六进制显示,8个字节可以发送2个字符(0~F)。如果没选以十六进制发送的话,会以ASCII码发送,只能发送一个字符(一个字符的ASCII8个字节)。
继承事业,薪火相传
返回列表