fpga板子怎么和电脑连_使用UART实现FPGA板与PC通信

(一) UART 介绍

略……(后续会补上)

(二) UART 软件

PC 端使用的软件为“串口调试助手 ComAssistant”

(三) UART 模块介绍

下面先介绍 UART 关键的3个模块,可以先不理解其中的工作原理,先了解这几个模块的作用与效果。

1. Uart_ClkDiv

/* Uart时钟信号 */

module Uart_ClkDiv(

input Sys_CLK, //50Mhz系统时钟

output Uart_CLK //9600bps

);

上述 Uart_ClkDiv 用来生成 Uart 传输所需要的时钟信号,输入 50Mhz 系统时钟,输出 Uart 时钟

2. Uart_Rx

/* Uart_Rx 用于接收数据 */

module Uart_Rx(

input Uart_CLK,//采样时钟

input RST,//复位信号

input Signal_Rx,//UART数据输入

output reg [7:0] Data_Rx,//接收数据输出

output reg Rdsig,//置1时表示上层模块已经可以读8位数据了

output reg DataError_Flag,//数据出错指示

output reg FrameError_Flag//帧出错指示

);

上述 Uart_Rx 用于接收数据,输入的 Uart_CLK 为模块 Uart_ClkDiv 生成的 Uart 时钟信号,RST 为复位键信号(低电平有效),Signal_Rx 为 Uart 数据输入信号

8bit 输出 Data_Rx 为一次接收获取的数据,Rdsig 为低电平表示正在接收数据,当一次数据接收完毕后会置成一段时间的高电平

DataError_Flag 和 FrameError_Flag 都是出错提示,当接收数据过程发送错误会被置成高电平,需要注意此处的校验位为偶校验位(Even)

3. Uart_Tx

/* Uart_Tx发送数据 */

module Uart_Tx(

input Uart_CLK,

input RST,

input [7:0] Data_Tx,//8位待发送数据

input Wrsig,

output reg Idle,//空闲状态,0表示空闲,1表示忙碌

output reg Signal_Tx//并转串,1位输出

);

上述 Uart_Tx 用于发送数据,输入的 Uart_CLK 为模块 Uart_ClkDiv 生成的 Uart 时钟信号,RST 为复位键信号(低电平有效)

Data_Tx 为 8bit 待发送数据,Wrsig 上升沿时开始发送

Idle 是 Uart_Tx 发送器的状态,0表示空闲,1表示忙碌, Signal_Tx 是数据输出信号

上述三个模块是 UART 发送的核心,但要实现超过 8 位的数据传输,单靠上面还不够

(四) 实现多比特数据传输

由于 UART 的资料位(数据位)一般是8位,但实际应用中需要传输多位数据。

根据 Uart_Rx 和 Uart_Tx 各接口的效果,使用时钟周期进行循环接收与发送

此处以接收 64bit 数据,并将接收到的数据发送为例,演示多位数据传输的原理

注意:图中的校验位为EVEN,应该为偶校验,猜测软件将EVEN(偶)错误标记成EVEN(奇)

1. 顶层模块

/* 顶层模块 */

module uart_top(

input sys_clk,//系统时钟

input sys_rst,//复位键

input signal_rx,//接收信号rx

input enable,//使能信号

output isEnable,//是否能够运行

output Err,//错误信号

output busy,//忙碌信号

output finish,//完成信号

output signal_tx//tx发送信号

);

上述为顶层模块的接口,由于代码实现的原因,在每次发送数据至 FPGA 板子前需要按下复位键,否则将无法正常接收

运行中信号,错误信号,忙碌信号,完成信号分别绑在 FPGA 的 4 个 LED 灯中,作为 FPGA 传输数据时的反馈

使能信号 enable 绑于一个拨码开关上,高电平运行

2. 循环接收模块

2.1 接口定义

/* 循环接收模块 */

module Uart_Receive_Top(

input sys_clk,//系统时钟

input sys_rst,//系统复位键

input signal_rx,//接收信号rx

input enable,//使能信号

output reg[63:0] data_input,//数据输入

output reg Err,//报错,高电平出错

output reg finish,//接收完成信号

output reg busy//高电平忙碌

);

上述是接收模块的接口定义,在此模块中实现循环接收数据,接收完毕后会将 finish 信号置1,表示接收完成

如果接收未完成,busy 信号为1,如果接收出错,Err信号为1

2.2 核心代码

/* 循环接收模块 */

case(state)

4'd00 : begin

if(Rdsig && !DataError && !FrameError) begin

data_input[64-0*8-1:64-(0+1)*8] <= data_rx;

busy <= 1'b1;

state <= state + 1;

end

else if(DataError || FrameError) begin

Err <= 1;

state <= 4'b1111;

end

end

4'd01 : begin

if(!Rdsig)state <= state + 1;

end

4'd02 : begin

if(Rdsig && !DataError && !FrameError) begin

data_input[64-1*8-1:64-(1+1)*8] <= data_rx;

busy <= 1'b1;

state <= state + 1;

end

else if(DataError || FrameError) begin

Err <= 1;

state <= 4'b1111;

end

end

4'd03 : begin

if(!Rdsig)state <= state + 1;

end

...

4'd14 : begin

if(Rdsig && !DataError && !FrameError) begin

data_input[64-7*8-1:64-(7+1)*8] <= data_rx;

finish <= 1;

busy <= 0;

state <= state;

end

else if(DataError || FrameError) begin

Err <= 1;

state <= 4'b1111;

end

end

//报错

4'b1111:Err<=1;

default:;

endcase

上述是接收过程的其中几个状态,每两个状态完成一次接收操作

第一个状态进行接收,当 Rwsig 为 1 时表示接收完毕,DataError 和 FrameError 都不为 0 表示未发生错误

故一次接收完成,进行 data_input 的赋值,并让 state + 1 跳转至下一个状态;如果发生错误,将状态跳转到报错状态

第二个状态等待下一次接收的开始,当 Rwsig 为 0 后表明接收开始,跳转到下一个状态等待接收完毕

当最后一个数据接收完毕后,将 finish 置 1,busy 置 0,表明接收完毕

3. 发送模块

3.1 接口定义

module Uart_Send_Top(

input sys_clk,//系统时钟50MHz

input sys_rst,//重置键rst

input [63:0] data_output,//待发送数据

input enable,//发送使能,1为可以发送

output wire signal_tx,//uart发送信号tx

output reg Err,//报错,高电平出错

output reg finish,//完成信号

output reg busy//高电平时表示忙碌

);

上述是循环发送模块的接口定义,与接收接口类似

3.2 核心代码

/* 循环发送模块 */

case(state)

4'd00 : begin

if(!Busy_Tx) begin

Data_Tx <= data_output[64-0*8-1:64-(0+1)*8];

Wrsig <= 1;

state <= state + 1;

wait_cnt <= 12'd0;

wait_finished <= 1'b0;

end

end

4'd01 : begin

if(Busy_Tx) begin

Wrsig <= 0;

end

else begin

wait_cnt <= wait_cnt + 1;

if(wait_cnt == 12'hA00) begin

wait_cnt <= 12'd0;

wait_finished <= 1'b1;

end

else if(wait_cnt == 12'd0 && wait_finished) state <= state + 1;

end

end

4'd02 : begin

if(!Busy_Tx) begin

Data_Tx <= data_output[64-1*8-1:64-(1+1)*8];

Wrsig <= 1;

state <= state + 1;

wait_

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值