【小月电子】安路国产FPGA开发板系统学习教程-LESSON7串口通信

news/2024/5/15 18:23:29/文章来源:https://blog.csdn.net/Moon_3181961725/article/details/126819160

串口通信例程讲解

若要观看该博客配套的视频教程,可点击此链接

在这里插入图片描述
根据多年工作经验,总结出的FPGA的设计流程,概括起来总共有以上12步,其中根据项目难易度可省去其中一些步骤。比如非常简单的项目,我们可以省去虚线框里面的步骤,但是我们的入门级课程,即使再简单,也按照这12个步骤来进行讲解。

1. 需求解读

1.1 需求

通过串口控制8个LED灯,波特率9600,比如通过串口下发8’h55,开发板上亮4盏LED灯,灭4盏LED灯。同时串口助手上会收到8’h55

1.2 知识背景

    串口是“串行接口”的简称,即采用串行通信方式的接口。串行通信将数据字节分成一位一位的形式在一条数据线上逐个传送,其特点是通信线路简单,但传输速度较慢。因此串口广泛应用于嵌入式、工业控制等领域中对数据传输速度要求不高的场合。
    串行通信分为两种方式:同步串行通信和异步串行通信。同步串行通信需要通信双方在同一时钟的控制下,同步传输数据;异步串行通信是指通信双方使用各自的时钟控制数据的发送和接收过程。
    UART是一种采用异步串行通信方式的通用异步收发传输器(universal asynchronous receiver-transmitter),它在发送数据时将并行数据转换成串行数据来传输,在接收数据时将接收到的串行数据转换成并行数据。
    UART串口通信需要两根信号线来实现,一根用于串口发送,另外一根负责串口接收。 UART在发送或接收过程中的一帧数据由4部分组成,起始位、数据位、 奇偶校验位和停止位,具体时序如图1所示。其中,起始位标志着一帧数据的开始,停止位标志着一帧数据的结束,数据位是一帧数据中的有效数据。校验位分为奇校验和偶校验,用于检验数据在传输过程中是否出错。奇校验时,发送方应使数据位中1的个数与校验位中1的个数之和为奇数;接收方在接收数据时,对1的个数进行检查,若不为奇数,则说明数据在传输过程中出了差错。同样,偶校验则检查1的个数是否为偶数。
    UART通信过程中的数据格式及传输速率是可设置的,为了正确的通信,收发双方应约定并遵循同样的设置。数据位可选择为5、 6、 7、 8位,其中8位数据位是最常用的, 在实际应用中一般都选择8位数据位;校验位可选择奇校验、偶校验或者无校验位;停止位可选择1位(默认),1.5或2位。串口通信的速率用波特率表示,它表示每秒传输二进制数据的位数,单位是bps( 位/秒),常用的波特率有9600、19200、38400、57600以及115200等。
    在设置好数据格式及传输速率之后,UART负责完成数据的串并转换,而信号的传输则由外部驱动电路实现。电信号的传输过程有着不同的电平标准和接口规范, 针对异步串行通信的接口标准有RS232、RS422、RS485等,它们定义了接口不同的电气特性,如RS-232是单端输入输出,而RS-422/485为差分输入输出等。
    RS232接口标准出现较早, 可实现全双工工作方式,即数据发送和接收可以同时进行。在传输距离较短时(不超过15m),RS232是串行通信最常用的接口标准,本章主要介绍针对RS-232标准的UART串口通信。
    RS-232标准的串口最常见的接口类型为DB9,样式如图2所示,工业控制领域中用到的工控机一般都配备多个串口,很多老式台式机也都配有串口。但是笔记本电脑以及较新一点的台式机都没有串口,它们一般通过USB转串口线(图3)来实现与外部设备的串口通信。
在这里插入图片描述

图1. 异步串口时序图

在这里插入图片描述

图2. DB9接头

在这里插入图片描述

图3. USB串口线

DB9接口定义以及各引脚功能说明如图 16.1.4所示,我们一般只用到其中的2(RXD)、3(TXD)、5(GND)引脚,其他引脚在普通串口模式下一般不使用。
在这里插入图片描述

图4. DB9接口定义
波特率9600bps:每秒传输9600bit。 传输1bit的时间为:1/9600(秒)=104167ns 也就是5208个时钟周期,需要采集1次 以上只是介绍串口相关的知识,我们XLOGIC开发板上板载了USB转TTL芯片(CH340),只用一根USB线即可与电脑进行串口通信。

1.3 硬件设计

在这里插入图片描述

图5.有源晶振

在这里插入图片描述

图6.串口芯片电路

在这里插入图片描述

图7.对应的FPGA管脚

1.4 接口说明

信号名方向FPGA管脚号说明
CLK50M输入B10时钟信号,50MHZ
FPGA_RX输入H14串口信号输入
FPGA_TX输出F14串口信号输出

    总结:通过上述说明,可以将需求解读成, 串口助手按波特率9600下发一个数,通过串口发送端口发送给FPGA,FPGA根据串口时序将这个数解析出来,然后将这个数赋值给8个LED即可。同时,FPGA再通过串口发送端口将这个数发送出去,这样串口助手上便可显示发送出去的数据。

2. 绘制理论波形图

在这里插入图片描述

程序框图

在这里插入图片描述

串口接收理论波形图

在这里插入图片描述

串口发送理论波形图

3.新建TD工程

为了让工程看起来整洁,同时方便工程移植。我们新建4个文件夹,分别是Project,Source,Sim,Doc。
Project — 工程文件夹,里面放的TD工程
Source — 源代码文件夹,里面放的工程源码(.v文件或.vhd文件)
Sim — 仿真文件夹,里面放的仿真相关的文件
Doc — 存放相关资料,比如数据手册,需求文档等

4.编写代码

4.1 串口接收模块代码

///
//QQ:3181961725
//TEL/WX:13540738439
//作者:Mr Wang
//模块介绍:实现异步串口接收功能
///
module async_uart_rev(input				rst_n	,//复位信号,低电平有效input				clk		,//时钟信号,50MHZinput				rxd		,//串行接收数据output	reg	[7:0]	rev_data,//并行数据output	reg			rev_dvld //并行数据有效标志);parameter	baud_num=5207;//1/9600*1000000000/20parameter	IDLE		=4'd0;parameter	START_ST    =4'd1;parameter	STOP_ST     =4'd2;reg	[12:0]	baud_cnt;reg			baud_cnt_en;wire		sample_en;reg	[3:0]	sample_num;reg			rxd_ff1;reg			rxd_ff2;reg	[3:0]	curr_st;//打两拍操作always@(posedge clk)rxd_ff2<=rxd_ff1;always@(posedge clk)rxd_ff1<=rxd;assign	sample_en=(baud_cnt==baud_num[12:1])?1'b1:1'b0;//状态机跳转程序always@(posedge clk or negedge rst_n)beginif(!rst_n)curr_st<=IDLE;else case(curr_st)IDLE:beginif(rxd_ff2==0)curr_st<=START_ST;else;endSTART_ST:beginif(sample_num==8&&sample_en)curr_st<=STOP_ST;else;endSTOP_ST:beginif(rxd_ff2==1&&sample_en)curr_st<=IDLE;else;enddefault:;endcaseendalways@(posedge clk or negedge rst_n)beginif(!rst_n)baud_cnt<=0;else if(curr_st==START_ST||curr_st==STOP_ST)beginif(baud_cnt==baud_num)baud_cnt<=0;else baud_cnt<=baud_cnt+1;end elsebaud_cnt<=0;endalways@(posedge clk or negedge rst_n)beginif(!rst_n)	sample_num<=0;else if(sample_en&&sample_num==9)sample_num<=0;else if(sample_en)sample_num<=sample_num+1;else;endalways@(posedge clk or negedge rst_n)beginif(!rst_n)rev_data<=0;else if(sample_en)case(sample_num)1:rev_data[0]<=rxd_ff2;2:rev_data[1]<=rxd_ff2;3:rev_data[2]<=rxd_ff2;4:rev_data[3]<=rxd_ff2;5:rev_data[4]<=rxd_ff2;6:rev_data[5]<=rxd_ff2;7:rev_data[6]<=rxd_ff2;8:rev_data[7]<=rxd_ff2;default:;endcaseendalways@(posedge clk or negedge rst_n)beginif(!rst_n)	rev_dvld<=0;else if(sample_num==9&&sample_en)rev_dvld<=1;elserev_dvld<=0;end
endmodule

4.2 串口发送模块代码

///
//QQ:3181961725
//TEL/WX:13540738439
//作者:Mr Wang
//模块介绍:实现异步串口发送功能
///
module async_uart_tran(input			rst_n		,//复位信号,低电平有效input			clk			,//时钟,50MHZinput	[7:0]	tran_data	,//输入的并行数据input			tran_dvld	,//输入的并行数据有效标志output	reg		txd          //串行输出数据);parameter	baud_num=5207;//1/9600*1000000000/20parameter	IDLE		=4'd0;parameter	DATA_ST    =4'd1;parameter	START_ST    =4'd2;parameter	STOP_ST     =4'd3;reg	[12:0]	baud_cnt;reg			baud_cnt_en;wire		sample_en;reg	[3:0]	sample_num;reg	[3:0]	curr_st;assign	sample_en=(baud_cnt==baud_num)?1'b1:1'b0;always@(posedge clk or negedge rst_n)beginif(!rst_n)curr_st<=IDLE;else case(curr_st)IDLE:beginif(tran_dvld==1)curr_st<=START_ST;else;endSTART_ST:beginif(sample_en==1)curr_st<=DATA_ST;endDATA_ST:beginif(sample_en&&sample_num==8)curr_st<=STOP_ST;else;endSTOP_ST:beginif(sample_en==1)curr_st<=IDLE;else;enddefault:;endcaseendalways@(posedge clk or negedge rst_n)beginif(!rst_n)baud_cnt<=0;else if(curr_st==START_ST||curr_st==DATA_ST||curr_st==STOP_ST)beginif(baud_cnt==baud_num)baud_cnt<=0;else baud_cnt<=baud_cnt+1;end elsebaud_cnt<=0;endalways@(posedge clk or negedge rst_n)beginif(!rst_n)	sample_num<=0;else if(curr_st==IDLE)sample_num<=0;else if(sample_en)sample_num<=sample_num+1;else;endalways@(posedge clk or negedge rst_n)beginif(!rst_n)txd<=1;else if(sample_en)case(sample_num)0:txd<=1'b0;1:txd<=tran_data[0];2:txd<=tran_data[1];3:txd<=tran_data[2];4:txd<=tran_data[3];5:txd<=tran_data[4];6:txd<=tran_data[5];7:txd<=tran_data[6];8:txd<=tran_data[7];9:txd<=1'b1;default:txd<=1;endcaseend
endmodule

4.3 顶层模块代码

///
//QQ:3181961725
//TEL/WX:13540738439
//作者:Mr Wang
//模块介绍:顶层模块,例化接收和发送模块
///
module async_uart_top(input	clk			,//时钟,50MHZinput	rst_n		,//复位信号,低电平有效input	rxd			,//串行接收数据output	txd			,//串行发送数据output	[7:0] led);wire	[7:0]	rev_data;wire			rev_dvld;assign	led=rev_data;async_uart_rev Uasync_uart_rev(.rst_n		(rst_n),.clk		(clk),.rxd		(rxd),.rev_data	(rev_data),.rev_dvld   (rev_dvld));async_uart_tran async_uart_tran(.rst_n		(rst_n),.clk		(clk),.tran_data	(rev_data),.tran_dvld	(rev_dvld),.txd        (txd));
endmodule

5.编写仿真测试激励文件

在这里插入图片描述

仿真框图

仿真测试激励文件(TB文件)

`timescale 1ns/1ns
module async_uart_top_tb;reg					clk		;reg					rst_n	;wire				rxd		;wire				tran_dvld;reg	[17:0]	cnt=0;
initial
beginclk = 0;rst_n=0;#1000rst_n=1;
end
always #10 clk=~clk;
always@(posedge clk)cnt<=cnt+1;
assign	tran_dvld=(cnt==100)?1'b1:1'b0;
async_uart_tran Uasync_uart_tran(.rst_n		(rst_n),.clk		(clk),.tran_data	(8'h55),.tran_dvld	(tran_dvld),.txd        (rxd));
async_uart_top async_uart_top(.clk	(clk),.rst_n	(rst_n),.rxd	(rxd),.txd	(),.led    ());
endmodule

6.Modelsim仿真

Modelsim仿真一般有两种方法

  1. 图形化界面仿真,即所有的操作都是在Modelsim软件界面上来完成,该方式的优点是,简单易学,适用于简单的项目,缺点是操作步骤繁琐。

  2. 批处理仿真,这种方式在仿真前需要编写相应的脚本文件,该方式的优点是,一键即可完成仿真,省时省力,缺点是前期需要编写脚本文件。前两讲采用的是图形化界面仿真的方式;为了更贴近工程实际,从第三讲开始,我们就采用批处理方式仿真。具体操作步骤可参考我们的视频教程
    仿真出的波形如下图所示:
    在这里插入图片描述

7.对比波形图

将第二步绘制的理论波形图与第六步Modelsim仿真出来的波形图进行对比,结果一致,说明我们的逻辑设计是正确的。如果发现比对结果不一致,就需要找到不一致的原因,最终要保证对比结果一致。通过对比,理论波形与仿真波形一致,说明功能符合设计要求。

8 添加.v文件

在这里插入图片描述

9 绑定管脚并保存约束文件(.adc)

在这里插入图片描述
在这里插入图片描述

10 编译综合生成BIT文件

在这里插入图片描述

11.下载BIT文件

在这里插入图片描述
在这里插入图片描述

下载成功后,便可以观察到开发板上的实验现象,如果实验现象与设计需求相符,那说明我们的设计是没有问题的,即可进行下一步固化配置文件。

12 固化配置文件

FPGA有一个特性,就是掉电后配置信息会丢失,所以我们需要将配置信息存储在配置芯片(FLASH)中,待开发板上电后,FPGA便会读取配置芯片中的配置信息,这样开发板掉电再上电后同样可正常工作
在这里插入图片描述

固化成功后,开发板断电再重新上电,可以观察到开发板仍然可以执行刚刚的功能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_6531.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【数据结构】二叉树的遍历

文章目录 5.3 二叉树的遍历 5.3.1 概述 5.3.2 遍历方式【重点】 5.3.3 遍历方式&#xff1a;递归实现【重点】 5.3.4 遍历方式&#xff1a;非递归实现 5.3 二叉树的遍历 5.3.1 概述 二叉树的遍历&#xff1a;沿着某条搜索路径对二叉树中的结点进行访问&#xff0c;使得每…

grpc|protobuf的安装、编译、运行笔记(C++)

一、下载grpc源码 如果你的电脑/服务器可以做代理&#xff0c;然后稳定链接上 GitHub 那么完全可以按照 GitHub 的官方文档来操作&#xff0c;我这里采用 Gitee 镜像来操作 git clone https://gitee.com/jiangxy__loey/grpc.git二、下载依赖库 进入grpc目录&#xff0c;然后…

为什么残差连接的网络结构更容易学习?

为什么残差连接的网络结构更容易学习&#xff1f; 【写在前面】 不仅仅在resnet中&#xff0c;在各种网络结构中大家都喜欢使用残差连接的设计&#xff0c;并声称这有利于网络的优化&#xff0c;这是为什么呢&#xff1f;能给出一个有说服力的答案吗&#xff1f; Why the re…

1.数据校验-拦截器-全局异常-json数据处理

目录 1.数据校验-拦截器-全局异常-json数据处理 1. JSR303 2. JSR303中含有的注解 3. spring中使用JSR303进行服务端校验 3.1 导入依赖包 3.2 添加验证规则 3.3执行校验 3.4 错误信息的展示 4. SpringMVC定义Restfull接口 5.1 增加spring配置 5.2 Controller 5.3 格…

Mstsc(远程桌面连接)命令的高级用法

Mstsc远程桌面连接,这个是微软操作系统自带的一个命令,相信很多人都用过,但是如果说这个命令还有高级用法,估计很多人都没有用过,其实这个命令还是很强大的,今天咱们就来说一下mstsc的高级用法Mstsc远程桌面连接,这个是微软操作系统自带的一个命令,相信很多人都用过,但…

20220912--CSP-S模拟4

A. 石子游戏 B. 大鱼吃小鱼 C. 黑客 D. 黑客-续A. 石子游戏 首先了解一个叫做 \(\operatorname{Nim}\) 游戏的玩意 通常的 \(\operatorname{Nim}\) 游戏的定义是这样的: 有若干堆石子,每堆石子的数量都是有限的,合法的移动是“选择一堆石子并拿走若干颗(不能不拿)” 如果轮…

自制操作系统日志——第十二天

自制操作系统日志——第十二天 从今天开始&#xff0c;我们将花费两天的时间来进行计算机中定时器的制作。有了定时器后&#xff0c;才能够为程序和cpu更加便利的进行计时。可能会稍难一些了&#xff01;&#xff01;&#xff01; 做好准备&#xff0c;冲&#xff01;&#xf…

ConcurrentLinkedQueue解析

概述 ConcurrentLinkedQueue实际对应的是LinkedList,是一个线程安全的无界队列&#xff0c;但LinkedList是一个双向链表&#xff0c;而ConcurrentLinkedQueue是单向链表。ConcurrentLinkedQueue线程安全在于设置head、tail以及next指针时都用的cas操作&#xff0c;而且node里的…

00Android studio安装

目录一.下载Android studio二.安装Android studio三.打开软件一.下载Android studio 官网&#xff1a;https://developer.android.google.cn/studio 下载&#xff1a;由于是国外的网站&#xff0c;国内下载会比较慢 二.安装Android studio 打开&#xff1a; 点击【Next】 点击…

猿创征文|瑞吉外卖——管理端_员工管理

个人名片&#xff1a; 博主&#xff1a;酒徒ᝰ. 专栏&#xff1a;瑞吉外卖 个人简介&#xff1a;沉醉在酒中&#xff0c;借着一股酒劲&#xff0c;去拼搏一个未来。 本篇励志&#xff1a;一本好书&#xff0c;就像高级武功秘籍一样&#xff0c;哪怕只是从里面领悟到个一招半势&…

C# StringBuilder 底层深入原理分析以及使用详解

目录前言什么是StringBuilderStringBuilder的成员StringBuilder增加元素原理StringBuilder扩容原理Capacity&#xff1a;1&#xff0c;元素数量&#xff1a;0Capacity&#xff1a;1&#xff0c;元素数量&#xff1a;1Capacity&#xff1a;2&#xff0c;元素数量&#xff1a;2Ca…

开学季征文|卷生卷死之新学期大学生自救指南!!!

你好&#xff0c;这里是前情提要 正所谓 “ 宁可卷死自己&#xff0c;也要卷死同学 ” &#xff0c;在这个万物皆卷的时代&#xff0c;“卷”似乎早已与我们变得不可分割血脉相融&#xff0c;有道是卷卷更健康。我也知道卷卷更好&#xff0c;可是天不遂人愿&#xff0c;因为疫情…

Redis_09_Redis集群实现Sentinel哨兵应对高可用

文章目录一、前言二、Sentinel原理2.1 Sentinel原理2.2 Sentinel选主2.3 Sentinel功能小结三、Sentinel实践3.1 Sentinel配置3.2 实践&#xff1a;Sentinel基本使用3.2.1 实践&#xff1a;Sentinel搭建3.2.2 实践&#xff1a;主节点宕机之后的选主过程(Sentinel保证高可用)3.2.…

ERROR 2003 (HY000) Can‘t connect to MySQL server on ‘localhost3306‘ (10061)解决办法

这个解决办法是我根据网上一系列的方法准备突然成功的&#xff0c;所以我想可能是由于本身其不稳定造成的 首先&#xff0c;我在官网上下载了mysql文件&#xff0c;这个网上随便找都能找到怎么下载的 然后打开文件后&#xff0c;发现没有my.ini 所以我就找了一个文档放了进去…

【线性代数】MIT Linear Algebra Lecture 6: Column space and nullspace

Author&#xff5c; Rickyの水果摊 Time &#xff5c; 2022.9.12 Lecture 6: Column space and nullspace Lecture Info Instructor: Prof. Gilbert Strang Course Number: 18.06 Topics: Linear Algebra Official Lecture Resource: Resource Index of Linear Algebra …

HCIP-双机热备

一,双机热备原理 1.1双机热备简介FW部署在网络出口位置时,如果发生故障会影响到整网业务。为提升网络的可靠性,需要部署两台FW并组成双机热备。双机热备需要两台硬件和软件配置均相同的FW。两台FW之间通过一条独立的链路连接,这条链路通常被称之为“心跳线”。两台FW通过心…

美团面试官:高并发、任务执行时间短的业务怎样使用线程池?

前言 无论是互联网大厂还是一些中游公司的面试基本都会问到多线程与并发编程的知识&#xff0c;所以今天小编在这里做了关于这方面知识的一个笔记分享送给即将面试跳槽的程序员朋友们&#xff01; 首先关于多线程与并发的知识总结了一个思维导图&#xff0c;分享给大家 如果你…

【Pytorch】2022 Pytorch基础入门教程(完整详细版)

一、Pytorch 1.1 简介 Pytorch是torch的python版本&#xff0c;是由Facebook开源的神经网络框架&#xff0c;专门针对 GPU 加速的深度神经网络&#xff08;DNN&#xff09;编程。Torch 是一个经典的对多维矩阵数据进行操作的张量&#xff08;tensor &#xff09;库&#xff0…

从校园智能门锁预见万物互联的未来

随着物联网、移动互联网、大数据、云计算等信息技术的创新发展&#xff0c;被信息化驱动的教育行业实现了技术深化融合&#xff0c;智慧校园正逐步落地生根、开花结果。校园智能门锁是智慧校园的基础载体&#xff0c;也是实现教育信息化的基础载体。 NO.1校园智能门锁构建一体化…

【CSDN竞赛第五期】“三而竭”采用等比求和公式法的思考

原题题目 一鼓作气再而衰三而竭。 小艺总是喜欢把任务分开做。小艺接到一个任务&#xff0c;任务的总任务量是n。 第一天小艺能完成x份任务&#xff0c;第二天能完成x/k ... ...第t天能完成x/(k^(t-1))。 小艺想知道自己第一天至少完成多少才能完成最后的任务。 公式推导 第一…