[米联客-XILINX-H3_CZ08_7100] FPGA程序设计基础实验连载-30 RS485串口程序收发环路设计

本文主要是介绍[米联客-XILINX-H3_CZ08_7100] FPGA程序设计基础实验连载-30 RS485串口程序收发环路设计,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

软件版本:VIVADO2021.1

操作系统:WIN10 64bit

硬件平台:适用 XILINX A7/K7/Z7/ZU/KU 系列 FPGA

实验平台:米联客-MLK-H3-CZ08-7100开发板

板卡获取平台:https://milianke.tmall.com/

登录“米联客”FPGA社区 http://www.uisrc.com 视频课程、答疑解惑!

目录

1概述

2 RS485硬件电路设计

2.1 RS485驱动芯片介绍

2.2 RS485的应用电路设计

2.3 瞬态抑制器的使用

3 RS485的收发环路

3.1系统框图

3.2顶层模块源码

4 FPGA工程

5 RTL仿真

5.1仿真测试文件

5.2仿真结果

6下载演示


1概述

在前面的课程中,我们已经学习了UART串口程序的设计,在工业场合为了提高串口的抗干扰能力,以及传输距离,RS485/RS422会更加广泛应用。在本文的实验中我们通过调用前面已经编写好的UART收发IP模块,以及FIFO,实现RS485的单工通信测试。其中重点是关于RS485芯片在单工通信方式下的信号控制逻辑设计。

2 RS485硬件电路设计

2.1 RS485驱动芯片介绍

SP3485 器件是一款 3.3V 低功耗半双工收发器,符合 RS-485 和 RS-422 串行协议的规范。 SP3485 可以满足 RS-485 和 RS-422 串行协议的电气规范,负载下最高 10Mbps。

PIN

功能

功能描述

1

RO

数据接收输出

2

RE

接收输出使能,低电平有效

3

DE

输出使能,高电平有效

4

DI

数据发送输入

5

GND

6

A

同相驱动器输出/接收器输入

7

B

反相驱动器输出/接收器输入

8

VCC

供电

2.2 RS485的应用电路设计

实际设计的时候,把RE和DE接到一起,可以减少一个控制管脚,入下图

发送真值表:

INPUTS

OUTPUTS

RE

DE

DI

B

A

X

1

1

0

1

X

1

0

1

0

0

0

X

High-Z

1

0

X

关闭

可以看到,结合原理图设计:

当DE是高电平,RE是任何值,DI决定了A B的输出电平;

当DE和RE都是0,AB 输出为高阻,这个时候,RO可以作为输入

接收真值表:

INPUTS

OUTPUTS

RE

DE

Va~Vb

RO

0

X

-50mv

1

0

X

-200mv

0

X

X

Open/Shorted

1

1

1

X

High-Z

1

0

X

关闭

当DE是0,DE为任意值,RO输入有效:

当Va~Vb的差模电压>-50mv RO输出1;

当Va~Vb的差模电压<-200mv RO输出0

2.3 瞬态抑制器的使用

对于工业场合的工作环境,SMBJ6.0瞬态抑制器,可以抑制RS485总线的浪涌,过压,对RS485芯片起到保护作用。

3 RS485的收发环路

3.1系统框图

RS485采用的通信协议依然是UART串口协议,因此收发模块还是使用前面已经写好的UART收发IP模块。为了实现单工模式的环路测试功能,这里增加了1个FIFO以及1个收发模块控制器。默认情况下,RS485芯片工作于接收数据状态,当FIFO有数据,并且一段时间内没有新数据到达,控制器切换RS485芯片到发送状态,从FIFO中取出缓存的数据发出。

3.2顶层模块源码

以下代码中核心部分为如何实现RS485数据方向的切换,以及数据到FIFO的缓存。

/*************RS485 半双工测试*************
--使用到了UART 发送和接收驱动
--通过FIFO缓存数据,并且检测到接收总线一段时间没有时间达到,进入发送模式,发送之前接收到的数据。
*********************************************************************/
`timescale 1ns / 1ns //仿真时间刻度/精度module rs485_top(
input       I_sysclk_p,
input       I_sysclk_n,//系统时钟输入
output      O_rs485_de, // 485 de控制,控制输入 输出方向,0 输入 1输出
input       I_rs485_rx, // 485 RX输入总线
output      O_rs485_tx  // 485 TX输出总线
);localparam  SYSCLKHZ = 100_000_000;wire I_clk;
IBUFGDS CLK_U(
.I(I_sysclk_p),
.IB(I_sysclk_n),
.O(I_clk)
);
wire        reset_n;  //内部上电延迟复位
wire        rs485_rx; //内部RX 接收 
wire        rs485_fifo_empty;  //FIFO空
wire        rs485_fifo_rd_en;  //FIFO 读使能
wire        rs485_rvalid;      //读数据有效
wire [7:0]  rs485_rdata;       //串口读数据(接收)
wire [7:0]  rs485_wdata;       //串口写数据(发送)
wire        rs485_wbusy;       //写忙
reg         rs485_de;          //485芯片的DE控制0 输入 1输出
reg         rs485_wreq = 1'b0; //串口写请求
wire        rs485_tx_start;    //发送启动
reg         rs485_tx_start_r = 1'b0; //发送启动寄存
reg [17:0]  T_dcnt; //延迟计数器
reg [11:0]  rstn_cnt = 12'd0; //复位计数器//当rs485_de=0,设置rs485内部逻辑准备接收总线数据
assign rs485_rx         = (rs485_de == 1'b0) ? I_rs485_rx : 1'b1;
//当FIFO中有数据,并且串口发送不忙,启动发送
assign rs485_tx_start   = rs485_de&&(rs485_wbusy == 1'b0)&&(!rs485_fifo_empty);
//读FIFO使能,用rs485_tx_start的上升沿触发读FIFO
assign rs485_fifo_rd_en = (rs485_tx_start_r == 1'b0 & rs485_tx_start == 1'b1);//read fifo enable
//当rs485_de=0,设置rs485内部逻辑准备接收总线数据,否则,可以发送数据
assign O_rs485_de       = rs485_de; assign reset_n = rstn_cnt[11];//上电延迟复位//复位计数器
always @(posedge I_clk)beginif(rstn_cnt[11] == 1'b0)rstn_cnt <= rstn_cnt + 1'b1;else rstn_cnt <= rstn_cnt;
end//T_dcnt用于一段时间内,判断接收总线是否空闲
always @(posedge I_clk or negedge reset_n)beginif(reset_n == 1'b0)T_dcnt <= 17'd0; else if(rs485_rx && (!rs485_fifo_empty))//如果RX总线是高电平,并且FIFO非空(有数据)T_dcnt <= (T_dcnt[17] == 1'b1) ? T_dcnt : T_dcnt + 1'b1; //计数器累加else T_dcnt <= 0; //否则重置归零end//当rs485_de=0,设置rs485内部逻辑准备接收总线数据,否则,可以发送数据
always @(posedge I_clk )beginif(reset_n ==1'b0)//if(rs485_de | reset_n ==1'b0)rs485_de <= 1'b0;//重置rs485_de,切换到接收else if((T_dcnt[17]==1'b1)|rs485_wreq|rs485_wbusy)//当T_dcnt延迟计数器到达计数值,或者串口发送控制器正在发送(rs485_wreq,rs485_wbusy有效)rs485_de <= 1'b1;//设置rs485_deelsers485_de <= 1'b0;//设置rs485_de
end//打拍寄存一次
always @(posedge I_clk) rs485_tx_start_r <= rs485_tx_start;//rs485_wreq,延迟于rs485_fifo_rd_en,1个时钟,用于数据同步
always @(posedge I_clk) rs485_wreq <= rs485_fifo_rd_en;//例化FIFO IP,FIFO设置标准模式,用户缓存接收到的帧
fifo_generator_0 inst_fifo (.wr_clk(I_clk),          //写时钟输入.wr_rst(reset_n == 1'b0),   //写复位.rd_clk(I_clk),          //读时钟输入.rd_rst(reset_n == 1'b0),   //读复位.din(rs485_rdata),          //RX接收到的数据.wr_en(rs485_rvalid&(rs485_de==1'b0)), // 写FIFO 使能,当rs485_rvalid有效,写入数据.rd_en(rs485_fifo_rd_en),   //FIFO读使能.dout(rs485_wdata),         //写数据.empty(rs485_fifo_empty)    //FIFO 空
); 
//例化串口发送模块
uiuart_tx#
(
.BAUD_DIV(SYSCLKHZ/115200 -1)  //设置波特率  
)
uiuart_tx_u 
(
.I_clk(I_clk),           //系统时钟
.I_uart_rstn(reset_n),      //系统复位
.I_uart_wreq(rs485_wreq),   //串口发送驱动器发送请求
.I_uart_wdata(rs485_wdata), //串口发送,数据
.O_uart_wbusy(rs485_wbusy), //串口发送总线忙
.O_uart_tx(O_rs485_tx)      //串口发送总线
);//例化串口接收模块
uiuart_rx#
(
.BAUD_DIV(SYSCLKHZ/115200 -1) //设置波特率      
)
uiuart_rx_u 
(
.I_clk(I_clk),           //系统时钟
.I_uart_rstn(reset_n),   //系统复位
.I_uart_rx(rs485_rx),       //串口接收总线
.O_uart_rdata(rs485_rdata), //串口接收数据
.O_uart_rvalid(rs485_rvalid)//串口接收数据有效
);   endmodule

4 FPGA工程

fpga工程的创建过程不再重复

米联客的代码管理规范,在对应的FPGA工程路径下创建uisrc路径,并且创建以下文件夹

01_rtl:放用户编写的rtl代码

02_sim:仿真文件或者工程

03_ip:放使用到的ip文件

04_pin:放fpga的pin脚约束文件或者时序约束文件

05_boot:放编译好的bit或者bin文件(一般为空)

06_doc:放本一些相关文档(一般为空)

5 RTL仿真

5.1仿真测试文件

`timescale 1ns/1ns  //定义仿真时间刻度/精度
module uart_top_tb();localparam      BPS          = 'd115200 ;             //波特率
localparam      CLK_FRE    = 'd100_000_000  ;     //系统频率
localparam    CLK_TIME   = 'd1000_000_000 /CLK_FRE;//计算系统时钟周期,以ns为单位
localparam      BIT_TIME   = 'd1000_000_000/ BPS ;  //计算出传输每个bit所需要的时间以ns为单位
localparam    NUM_BYTES  = 3;               //需要发送的BYTESreg               I_sysclk_p;
reg               I_sysclk_n;               //系统时钟
reg         bsp_clk ;     //波特率时钟
reg               uart_tx;      //uart 数据发送,该信号接入到,FPGA的uart 接收
wire        uart_rx;      //uart 数据接收,该信号接入到,FPGA的uart 发送
reg [8*NUM_BYTES-1:0] uart_send_data;   //需要发送的数据
reg [7:0]                 uart_send_data_r; //寄存每次需要发送的BYTEinteger i,j;//例化顶层模块
rs485_top rs485_top
(
.I_sysclk_p     (I_sysclk_p),
.I_sysclk_n     (I_sysclk_n),
.O_rs485_de   (O_rs485_de),
.I_rs485_rx   (uart_tx),
.O_rs485_tx   (uart_rx)
);
//仿真初始化
initial begin 
//初始化REG寄存器
I_sysclk_p =0;
I_sysclk_n =1;
bsp_clk  = 0;  
uart_tx  = 1;
i=0;
j=0;uart_send_data   =0;
uart_send_data_r =0;#40000;//延迟40000ns,等待uart测试代码中的复位延迟
uart_send_data[(0*8) +: 8] = 8'b1001_0101;//初始化需要发送的第1个BYTE
uart_send_data[(1*8) +: 8] = 8'b0000_0101;//初始化需要发送的第2个BYTE
uart_send_data[(2*8) +: 8] = 8'b1000_0100;//初始化需要发送的第3个BYTE
//uart tx 发送数据for(i=0; i<NUM_BYTES;i=i+1)Beginuart_send_data_r = uart_send_data[(i*8) +: 8];//寄存需要发送的数据到寄存器$display("uart_send_data : 0x%h",uart_send_data_r);//打印准备发送的数据@(posedge bsp_clk);  //发送起始位1bituart_tx = 1'b0;for(j=0;j<8;j=j+1)begin//发送数据8bits@(posedge bsp_clk);  //发送uart_tx = uart_send_data_r[j];end@(posedge bsp_clk);//发送停止位1bituart_tx = 1'b1;  end@(posedge bsp_clk); #2000000 $finish;            
endalways #(CLK_TIME/2) I_sysclk_p = ~I_sysclk_p;
always #(CLK_TIME/2) I_sysclk_n = ~I_sysclk_n;    //产生主时钟
always #(BIT_TIME/2) bsp_clk  = ~bsp_clk;       //产生波特率时钟endmodule

5.2仿真结果

6下载演示

(硬件不支持,本课不展示下载演示结果)

这篇关于[米联客-XILINX-H3_CZ08_7100] FPGA程序设计基础实验连载-30 RS485串口程序收发环路设计的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1139343

相关文章

不懂推荐算法也能设计推荐系统

本文以商业化应用推荐为例,告诉我们不懂推荐算法的产品,也能从产品侧出发, 设计出一款不错的推荐系统。 相信很多新手产品,看到算法二字,多是懵圈的。 什么排序算法、最短路径等都是相对传统的算法(注:传统是指科班出身的产品都会接触过)。但对于推荐算法,多数产品对着网上搜到的资源,都会无从下手。特别当某些推荐算法 和 “AI”扯上关系后,更是加大了理解的难度。 但,不了解推荐算法,就无法做推荐系

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟&nbsp;开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚&nbsp;第一站:海量资源,应有尽有 走进“智听

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]

30常用 Maven 命令

Maven 是一个强大的项目管理和构建工具,它广泛用于 Java 项目的依赖管理、构建流程和插件集成。Maven 的命令行工具提供了大量的命令来帮助开发人员管理项目的生命周期、依赖和插件。以下是 常用 Maven 命令的使用场景及其详细解释。 1. mvn clean 使用场景:清理项目的生成目录,通常用于删除项目中自动生成的文件(如 target/ 目录)。共性规律:清理操作

怎么让1台电脑共享给7人同时流畅设计

在当今的创意设计与数字内容生产领域,图形工作站以其强大的计算能力、专业的图形处理能力和稳定的系统性能,成为了众多设计师、动画师、视频编辑师等创意工作者的必备工具。 设计团队面临资源有限,比如只有一台高性能电脑时,如何高效地让七人同时流畅地进行设计工作,便成为了一个亟待解决的问题。 一、硬件升级与配置 1.高性能处理器(CPU):选择多核、高线程的处理器,例如Intel的至强系列或AMD的Ry

2024网安周今日开幕,亚信安全亮相30城

2024年国家网络安全宣传周今天在广州拉开帷幕。今年网安周继续以“网络安全为人民,网络安全靠人民”为主题。2024年国家网络安全宣传周涵盖了1场开幕式、1场高峰论坛、5个重要活动、15场分论坛/座谈会/闭门会、6个主题日活动和网络安全“六进”活动。亚信安全出席2024年国家网络安全宣传周开幕式和主论坛,并将通过线下宣讲、创意科普、成果展示等多种形式,让广大民众看得懂、记得住安全知识,同时还

【Linux 从基础到进阶】Ansible自动化运维工具使用

Ansible自动化运维工具使用 Ansible 是一款开源的自动化运维工具,采用无代理架构(agentless),基于 SSH 连接进行管理,具有简单易用、灵活强大、可扩展性高等特点。它广泛用于服务器管理、应用部署、配置管理等任务。本文将介绍 Ansible 的安装、基本使用方法及一些实际运维场景中的应用,旨在帮助运维人员快速上手并熟练运用 Ansible。 1. Ansible的核心概念

AI基础 L9 Local Search II 局部搜索

Local Beam search 对于当前的所有k个状态,生成它们的所有可能后继状态。 检查生成的后继状态中是否有任何状态是解决方案。 如果所有后继状态都不是解决方案,则从所有后继状态中选择k个最佳状态。 当达到预设的迭代次数或满足某个终止条件时,算法停止。 — Choose k successors randomly, biased towards good ones — Close

EMLOG程序单页友链和标签增加美化

单页友联效果图: 标签页面效果图: 源码介绍 EMLOG单页友情链接和TAG标签,友链单页文件代码main{width: 58%;是设置宽度 自己把设置成与您的网站宽度一样,如果自适应就填写100%,TAG文件不用修改 安装方法:把Links.php和tag.php上传到网站根目录即可,访问 域名/Links.php、域名/tag.php 所有模板适用,代码就不粘贴出来,已经打

基于51单片机的自动转向修复系统的设计与实现

文章目录 前言资料获取设计介绍功能介绍设计清单具体实现截图参考文献设计获取 前言 💗博主介绍:✌全网粉丝10W+,CSDN特邀作者、博客专家、CSDN新星计划导师,一名热衷于单片机技术探索与分享的博主、专注于 精通51/STM32/MSP430/AVR等单片机设计 主要对象是咱们电子相关专业的大学生,希望您们都共创辉煌!✌💗 👇🏻 精彩专栏 推荐订阅👇🏻 单片机