quartus Ⅱ 12.1 使用教程(4) uart 测试

2023-05-16

开发板使用的是EP4CE15F23C8,软件使用的是quartus  12.1 ,工程实现的功能是使用uart进行回环测试

顶层

module uart_test(
    i_clk,
    i_rst_n,
    rx,
    tx
    
    );
    
input   i_clk;
input   i_rst_n;
input   rx;
output  tx;



wire    clk_out;
wire    wrsig;
wire    idle;
wire    tx;
wire    rx;
wire    [7:0] data_in;
wire    [7:0] data_out;
wire    rdsig;
wire    data_error;
wire    frame_error;

clk_div u1(
    .clk50(i_clk), 
    .rst_n(i_rst_n), 
    .clkout(clk_out)
    );
       
uart_tx u2(
    .clk(clk_out), 
    .rst_n(i_rst_n), 
    .datain(data_out), 
    .wrsig(rdsig), 
    .idle(idle), 
    .tx(tx)
    );
       
uart_rx u3(
    .clk(clk_out), 
    .rst_n(i_rst_n), 
    .rx(rx), 
    .dataout(data_out), 
    .rdsig(rdsig), 
    .dataerror(data_error), 
    .frameerror(frame_error)
    );      
    
endmodule

分频模块

`timescale 1ns / 1ps
//
// Module Name:    clkdiv 
//
module clk_div(clk50, rst_n, clkout);
input clk50;              //系统时钟
input rst_n;              //收入复位信号
output clkout;            //采样时钟输出
reg clkout;
reg [15:0] cnt;

/分频进程, 50Mhz的时钟326分频/
always @(posedge clk50 or negedge rst_n)   
begin
  if (!rst_n) begin
     clkout <=1'b0;
	  cnt<=0;
  end	  
  else if(cnt == 16'd162) begin
    clkout <= 1'b1;
    cnt <= cnt + 16'd1;
  end
  else if(cnt == 16'd325) begin
    clkout <= 1'b0;
    cnt <= 16'd0;
  end
  else begin
    cnt <= cnt + 16'd1;
  end
end
endmodule

发送模块

`timescale 1ns / 1ps
//
// Module Name:    uarttx 
// 说明:16个clock发送一个bit, 一个起始位,8个数据位,一个校验位,一个停止位
//
module uart_tx(clk, rst_n, datain, wrsig, idle, tx);
input clk;                //UART时钟
input rst_n;              //系统复位
input [7:0] datain;       //需要发送的数据
input wrsig;              //发送命令,上升沿有效
output idle;              //线路状态指示,高为线路忙,低为线路空闲
output tx;                //发送数据信号
reg idle, tx;
reg send;
reg wrsigbuf, wrsigrise;
reg presult;
reg[7:0] cnt;             //计数器
parameter paritymode = 1'b0;


//检测发送命令wrsig的上升沿

always @(posedge clk)
begin
   wrsigbuf <= wrsig;
   wrsigrise <= (~wrsigbuf) & wrsig;  
end


//启动串口发送程序

always @(posedge clk)
begin
  if (wrsigrise &&  (~idle))  //当发送命令有效且线路为空闲时,启动新的数据发送进程
  begin
     send <= 1'b1;
  end
  else if(cnt == 8'd168)      //一帧数据发送结束
  begin
     send <= 1'b0;
  end
end


//串口发送程序, 16个时钟发送一个bit

always @(posedge clk or negedge rst_n)
begin
  if (!rst_n) begin
         tx <= 1'b0;
         idle <= 1'b0;
			cnt<=8'd0;
			presult<=1'b0;
  end		
  else if(send == 1'b1)  begin
    case(cnt)                 //产生起始位
    8'd0: begin
         tx <= 1'b0;
         idle <= 1'b1;
         cnt <= cnt + 8'd1;
    end
    8'd16: begin
         tx <= datain[0];    //发送数据0位
         presult <= datain[0]^paritymode;
         idle <= 1'b1;
         cnt <= cnt + 8'd1;
    end
    8'd32: begin
         tx <= datain[1];    //发送数据1位
         presult <= datain[1]^presult;
         idle <= 1'b1;
         cnt <= cnt + 8'd1;
    end
    8'd48: begin
         tx <= datain[2];    //发送数据2位
         presult <= datain[2]^presult;
         idle <= 1'b1;
         cnt <= cnt + 8'd1;
    end
    8'd64: begin
         tx <= datain[3];    //发送数据3位
         presult <= datain[3]^presult;
         idle <= 1'b1;
         cnt <= cnt + 8'd1;
    end
    8'd80: begin 
         tx <= datain[4];    //发送数据4位
         presult <= datain[4]^presult;
         idle <= 1'b1;
         cnt <= cnt + 8'd1;
    end
    8'd96: begin
         tx <= datain[5];    //发送数据5位
         presult <= datain[5]^presult;
         idle <= 1'b1;
         cnt <= cnt + 8'd1;
    end
    8'd112: begin
         tx <= datain[6];    //发送数据6位
         presult <= datain[6]^presult;
         idle <= 1'b1;
         cnt <= cnt + 8'd1;
    end
    8'd128: begin 
         tx <= datain[7];    //发送数据7位
         presult <= datain[7]^presult;
         idle <= 1'b1;
         cnt <= cnt + 8'd1;
    end
    8'd144: begin
         tx <= presult;      //发送奇偶校验位
         presult <= datain[0]^paritymode;
         idle <= 1'b1;
         cnt <= cnt + 8'd1;
    end
    8'd160: begin
         tx <= 1'b1;         //发送停止位            
         idle <= 1'b1;
         cnt <= cnt + 8'd1;
    end
    8'd168: begin
         tx <= 1'b1;             
         idle <= 1'b0;       //一帧数据发送结束
         cnt <= cnt + 8'd1;
    end
    default: begin
         cnt <= cnt + 8'd1;
    end
   endcase
  end
  else  begin
    tx <= 1'b1;
    cnt <= 8'd0;
    idle <= 1'b0;
  end
end
endmodule

接收模块

`timescale 1ns / 1ps
//
// Module name    uartrx.v
// 说明:          16个clock接收一个bit,16个时钟采样,取中间的采样值
//
module uart_rx(clk, rst_n, rx, dataout, rdsig, dataerror, frameerror);
input clk;             //采样时钟
input rst_n;           //复位信号
input rx;              //UART数据输入
output dataout;        //接收数据输出
output rdsig;
output dataerror;      //数据出错指示
output frameerror;     //帧出错指示
reg[7:0] dataout;
reg rdsig, dataerror;
reg frameerror;
reg [7:0] cnt;
reg rxbuf, rxfall, receive;
parameter paritymode = 1'b0;
reg presult, idle;

always @(posedge clk)   //检测线路的下降沿
begin
  rxbuf <= rx;
  rxfall <= rxbuf & (~rx);
end


//启动串口接收程序

always @(posedge clk)
begin
  if (rxfall && (~idle)) begin//检测到线路的下降沿并且原先线路为空闲,启动接收数据进程  
    receive <= 1'b1;
  end
  else if(cnt == 8'd168) begin //接收数据完成
    receive <= 1'b0;
  end
end


//串口接收程序, 16个时钟接收一个bit

always @(posedge clk or negedge rst_n)
begin
  if (!rst_n) begin
     idle<=1'b0;
	  cnt<=8'd0;
     rdsig <= 1'b0;	 
	  frameerror <= 1'b0; 
	  dataerror <= 1'b0;	  
	  presult<=1'b0;
  end	  
  else if(receive == 1'b1) begin
		case (cnt)
		8'd0:begin
			idle <= 1'b1;
			cnt <= cnt + 8'd1;
			rdsig <= 1'b0;
		end
		8'd24:begin                 //接收第0位数据
			idle <= 1'b1;
			dataout[0] <= rx;
			presult <= paritymode^rx;
			cnt <= cnt + 8'd1;
			rdsig <= 1'b0;
		end
		8'd40:begin                 //接收第1位数据  
			idle <= 1'b1;
			dataout[1] <= rx;
			presult <= presult^rx;
			cnt <= cnt + 8'd1;
			rdsig <= 1'b0;
		end
		8'd56:begin                 //接收第2位数据   
			idle <= 1'b1;
			dataout[2] <= rx;
			presult <= presult^rx;
			cnt <= cnt + 8'd1;
			rdsig <= 1'b0;
		end
		8'd72:begin               //接收第3位数据   
			idle <= 1'b1;
			dataout[3] <= rx;
			presult <= presult^rx;
			cnt <= cnt + 8'd1;
			rdsig <= 1'b0;
		end
		8'd88:begin               //接收第4位数据    
			idle <= 1'b1;
			dataout[4] <= rx;
			presult <= presult^rx;
			cnt <= cnt + 8'd1;
			rdsig <= 1'b0;
		end
		8'd104:begin            //接收第5位数据    
			idle <= 1'b1;
			dataout[5] <= rx;
			presult <= presult^rx;
			cnt <= cnt + 8'd1;
			rdsig <= 1'b0;
		end
		8'd120:begin            //接收第6位数据    
			idle <= 1'b1;
			dataout[6] <= rx;
			presult <= presult^rx;
			cnt <= cnt + 8'd1;
			rdsig <= 1'b0;
		end
		8'd136:begin            //接收第7位数据   
			idle <= 1'b1;
			dataout[7] <= rx;
			presult <= presult^rx;
			cnt <= cnt + 8'd1;
			rdsig <= 1'b1;
		end
		8'd152:begin            //接收奇偶校验位    
			idle <= 1'b1;
			if(presult == rx)
			  dataerror <= 1'b0;
			else
			  dataerror <= 1'b1;       //如果奇偶校验位不对,表示数据出错
			cnt <= cnt + 8'd1;
			rdsig <= 1'b1;
		end
		8'd168:begin
		  idle <= 1'b1;
		  if(1'b1 == rx)
			 frameerror <= 1'b0;
		  else
			 frameerror <= 1'b1;      //如果没有接收到停止位,表示帧出错
		  cnt <= cnt + 8'd1;
		  rdsig <= 1'b1;
		end
		default: begin
			cnt <= cnt + 8'd1;
		end
		endcase
   end	
   else begin
	  cnt <= 8'd0;
	  idle <= 1'b0;
	  rdsig <= 1'b0;	 
	end
end
endmodule

上面四个模块都是黑金提供的,程序比较简单所以也不用进行详细说明,基本能对模块进行仿真,并且

能在硬件上运行就差不多了

分配管脚

点击工具栏快捷按钮进行编译

找到编译后生成的sof文件,点击Open添加进来

将sof文件下载到开发板

连接开发板的串口,发送数据12,可以看到,每发送一次12开发板也同样会将接收到的12这个数据发出来

(这个串口比较简单,只需了解一下原理,并且仿真出来,再在硬件上测试成功就可以了,不用花大

量时间,来进行验证测试,这里仅记录一些简单的步骤)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

quartus Ⅱ 12.1 使用教程(4) uart 测试 的相关文章

  • 收藏!了解UART总线工作原理看这一篇就够了!

    原文 xff1a 玩转单片机 2019 08 24 16 50 29 越学到后面 xff0c 基础知识更加不能忘记 xff0c 温故而知新 还记得当年的打印机 xff0c 鼠标和调制解调器吗 xff1f 他们都有巨大笨重的连接器和粗电缆 x
  • 串行通信基础知识与UART驱动构件使用方法

    串行通信基础 串行通信接口 异步串行通信 UART 常称为 串口 或SCI xff0c 在USB未普及之前 xff0c 是PC机必备通信接口之一 通信方式为单字节通信 xff0c 是最简单的串行通信方式 RS232 RS485 接线简单 x
  • 串口发送通信---UART发送---STM32F4实现

    串口发送程序配置过程 xff08 HAL库 xff09 初始化串口相关参数 xff0c 使能串口 HAL StatusTypeDef span class token function HAL UART Init span span cla
  • FPGA uart串口收发verilog源码程序,适用于RS232 RS422

    FPGA uart串口收发verilog源码程序 xff0c 适用于RS232 RS422 xff0c 支持修改波特率 xff0c 数据位 xff0c 校验位 ID 3750670799663712
  • C51_day5:串口通信UART

    3 1 串口基本认知 串行接口简称串口 xff0c 也称串行通信接口或串行通讯接口 xff08 通常指COM接口 xff09 xff0c 是采用串行通信方式的扩展接口 串行接口 xff08 Serial Interface xff09 是指
  • UART串口通信协议详解

    UART xff1a 通信异步收发器 xff0c 串行 异步通信总线 xff0c 两条数据线 xff08 收发 xff09 xff0c 全双工 xff08 可以同时接收和发送 xff09 一 UART帧格式 xff08 UART协议 xff
  • 4.RTT-UART-中断接收及轮询发送

    本期博客开始分享RTT的UART xff0c 利用战舰V3的uart2来输入输出一些字符串 UART xff08 Universal Asynchronous Receiver Transmitter xff09 通用异步收发传输器 xff
  • 【教程】Edraw Max使用教程:Edraw Max快速入门指南

    Edraw Max是一款简单易用的快速制图软件 帮助你轻松创建流程图 网络拓扑图 组织结构图 商业图表 工程图 思维导图 软件设计图和平面布局图等 大多数用户一般不会花太多时间详细阅读用户手册 因此我们编辑了这个快速入门指南 为帮助你尽快开
  • RT-Thread记录(十一、I/O 设备模型之UART设备 — 源码解析)

    深入理解 RT Thread I O 设备模型 分析 UART设备源码 目录 前言 一 初识 UART 操作函数 应用程序 二 UART 的初始化 2 1 UART 设备初始化位置 2 2 UART 设备初始化函数分析 stm32 uart
  • 嵌入式Linux应用开发笔记:串口

    文章目录 目的 基础说明 开发准备 设备树 应用程序 应用程序与演示 代码 演示 总结 设备树文件 目的 串口 UART 是嵌入式设备中比较常用的功能 这篇文章将记录下应用程序中串口操作相关内容 这篇文章中内容均在下面的开发板上进行测试 新
  • UART通信原理

    UART 通信格式 串口全称叫做串行接口 通常也叫做 COM 接口 串行接口指的是数据一个一个的顺序传输 通信线路简单 使用两条线即可实现双向通信 一条用于发送 一条用于接收 串口通信距离远 但是速度相对会低 串口是一种很常用的工业接口 I
  • ESP32-C3入门教程 基础篇(三、UART模块 — 与Enocean无线模块串口通信)

    测试第三课 ESP32 C3的串口通信测试 老样子 使用Enocean无线模块和ESP32 C3进行串口通信 目录 前言 1 UART示例测试 1 1 UART 基础测试 1 2 与Enocean无线模块串口通信测试 2 ESP32 C3
  • Spire.XLS 图表系列教程:C# 设置 Excel 图表坐标轴格式

    更多资源查看 Spire XLS工作表教程 Spire Doc系列教程 Spire PDF系列教程 下载Spire XLS最新试用版 默认情况下 创建图表时 Excel会自动设置其坐标轴属性 这些属性包括坐标轴选项 例如边界最大值 边界最小
  • Python学习笔记综合

    一 安装和学习建议 1 使用的2 7 2 环境变量 python的根目录 3 cmd就可以运行 执行使用 python xxx py 4 编写代码可以直接python进入代码编辑 5 exit 退出编辑环境 安装与学习建议 pycharm专
  • ModelSim-Altera 错误

    我正在使用 Ubuntu Linux 14 04 LTS 和 Altera Quartus 15 0 网络版 由于许可错误 我很难模拟我的设计 我正在设计一个 LCD driverVEEK MT友晶科技的液晶触摸屏旋风 IV EP4CE11
  • STM32F4-Discovery (STM32F429ZIT6) 上的 RS232 (UART) 与 HAL 库?

    背景 这是我的一些背景 以便你们知道我有或没有哪些相关知识 我完全是这种嵌入式系统的新手 而且我对电子产品一无所知 我是一个纯粹的软件人员 我唯一的嵌入式系统经验是Raspberry Pi 它与STM32F4 Discovery有很大不同
  • 使用 read(...) 时在换行符处停止

    我需要从通过 UART 连接的 GPS 读取 NMEA 语句 操作系统是Debian 语言必须是C 为此 我使用以下命令打开文件open 并读取一个字符串read 但是 这样我必须指定字符串长度 这会分解句子 相反 我想读到 NMEA 句子
  • C语言UART通信(十六进制)

    我想向写入函数发送一个十六进制值 例如 0 90 这是因为需要通信的设备接收到的是十六进制数的命令 未使用的变量在测试时出现 并注释为丢失十六进制值 稍后将被删除 如何编写具有字符串以外的十六进制值的写入函数 对于初学者 请告诉我们如何通过
  • 如何将 microbit 与 BLE 连接并监听按钮按下事件?

    2021 年 11 月 28 日编辑 如果您需要使用蓝牙低功耗将 microbit 连接到计算机 并在单击按钮时执行操作 直接跳并跟随 ukBaz https stackoverflow com users 7721752 ukbaz的回答
  • 通过 USB 模拟 UART

    有谁知道是否可以通过 USB 模拟 UART 简单串行发送和接收 这将如何实现 我在 Microchip 网站上找到了这个链接 但不是很容易找到 http www microchip com forums m522571 print asp

随机推荐

  • g2o_a_general_framework_for_graph_optimaization

    g2o A General Framework for Graph Optimization NONLINEAR GRAPH OPTIMIZATION USING LEAST SQUARES 机器人和计算机视觉中的许多问题都可以用下列方程的
  • P5644 [PKUWC2018]猎人杀

    P5644 PKUWC2018 猎人杀 题目大意 一开始有 n n n 个猎人 xff0c 第 i i i 个猎人有仇恨度
  • 【Linux基础系列之】platform虚拟总线

    linux当中大多数的设备都是以paltform虚拟总线挂载上去的 xff0c 这里以kernel drivers net dm9000 c为例子分析一下 xff0c platform设备挂在过程 xff1b xff08 1 xff09 d
  • ARMv8-AArch64简述

    ARMv8是ARM版本升级以来最大的一次改变 xff0c ARMv8的架构继承以往ARMv7与之前处理器技术的基础 xff0c 除了现有的16 32bit的Thumb2指令支持外 xff0c 也向前兼容现有的A32 ARM 32bit 指令
  • ARMv8-AArch64寄存器和指令集

    xff08 一 xff09 简述 AArch拥有31个通用寄存器 xff0c 系统运行在64位状态下的时候名字叫Xn xff0c 运行在32位的时候就叫Wn xff1b AArch32与AArch64寄存器对应关系 xff1a xff08
  • ION框架学习(一)

    第一章介绍 xff1a ION的框架和buffer的分配 xff1b 第二章介绍 xff1a 如何使用ION buffer xff1b ION是google在Android4 0 为了解决内存碎片管理而引入的通用内存管理器 用来支持不同的内
  • 高通Camera 驱动调试要点(一)

    本文主要介绍QCOM camera调试的重要参数 xff1b xff08 1 xff09 Lane assign 和lane mask 现在摄像头基本都是mipi接口类型 xff0c 因为前后摄都对应到平台这边不同的mipi接口 xff0c
  • 高通Camera 驱动调试要点(二)

    这篇文章主要介绍数据流这边Camera ISP这块所遇到的问题 xff0c 主要介绍bus overflow和sof freeze xff1b xff08 一 xff09 bus overflow 摄像头传感器时钟通道 即 MIPI DDR
  • c/c++代码性能效率

    一 尽量减少值传递 xff0c 多用引用来传递参数 boolCompare xff08 span class hljs keyword string span s1 span class hljs keyword string span s
  • 6.Docker定制镜像

    当我们从docker镜像仓库中下载的镜像不能满足我们的需求时 xff0c 我们可以通过以下两种方式对镜像进行更改 1 从已经创建的容器中更新镜像 xff0c 并且提交这个镜像 2 使用 Dockerfile 指令来创建一个新的镜像 Dock
  • 全球最大成人网站公布年度榜单!原来lsp最爱看的是这种片……

    前几天 xff0c 那个号称全球最大的成人网站P hub xff0c 发布了 2022年度报告 别惊讶 xff0c 这已经是P某发布年度报告的第9个年头了 正所谓 xff0c 知己知彼百战不殆 不发年度报告 xff0c 怎么总结过去 xff
  • ROS学习篇(三)ROS系统的串口数据读取和解析(组合导航系统)

    一 Ubuntu下的串口助手cutecom 下载 xff1a sudo apt get install cutecom 打开 xff1a sudo cutecom 查看电脑链接的串口信息 xff08 名称 xff09 xff1a dmesg
  • VScode 结合clangd 构建linux源代码阅读环境

    1 背景介绍 上一篇文章 xff1a VScode 结合Global构建linux源代码阅读环境 xff0c 介绍了在VS Code工具中通过remote ssh远程登陆到Linux远程服务器 xff0c 使用Global构建linux源代
  • 信号量 PK 自旋锁

    信号量可能允许有多个持有者 xff0c 而自旋锁在任何时候只能允许一个持有者 xff0c 当然也有信号量叫互斥信号量 xff08 只能有一个持有者 xff09 xff0c 允许有多个持有者的信号量叫 计数信号量 信号量适合于保持时间较长的情
  • 【FreeRTOS】FreeRTOS 源码学习笔记 (4) 任务创建xTaskCreate + 常用结构体TCB、xLIST

    1 引言 经过第一节的移植 xff0c 我们已经拿到了一个可以用的工程 经过第二三节的基础知识 xff0c 我们对基本的数据结构 xff0c 列表 队列这些也有了一个了解 接下来就可以单步跟踪了 xff0c 看一下系统是怎么运行的 使用Fr
  • 【FreeRTOS】FreeRTOS 源码学习笔记 (5) 任务调度器 + vTaskStartScheduler、xPortPendSVHandler、xPortSysTickHandler

    1 引言 FreeRTOS的任务调度是个大头 xff0c 也是一个操作系统的核心 其实个人理解 xff0c FreeRTOS调度规则很好理解 xff0c 原则就是 优先级高抢占 xff0c 因为FreeRTOS是一个抢占式实时内核 xff0
  • [Qt入门篇]8 Qt的属性系统——总结

    QT常用的属性READ WRITE MEMBER NOTIFY RESET 1 QObject子类中使用Q PROPERTY宏声明属性 xff1b 2 Q PROPERTY宏中不能使用逗号 xff08 xff0c xff09 xff0c 只
  • [GIT] git打标签tag和分支branch的区别

    tag代表了当前的提交点 xff0c 是个点 xff0c tag是当前提交点的一个记录 xff0c tag名字是不能重复的 xff0c 就代表了唯一的这个点 branch代表里新的支线 xff0c 是个线 xff0c 可以继续延展 当在某个
  • 从社区贡献者到加入核心团队,开源给他带来了这些变化

    作者 尔悦 采访嘉宾 谭雪峰 就在今年六月份 xff0c 又一位社区Contributor成功入职涛思数据 xff0c 他的身份也从TDengine的社区贡献者转变为专职的研发人员 在身份变换的同时 xff0c 他对于自身的成长和发展 对于
  • quartus Ⅱ 12.1 使用教程(4) uart 测试

    开发板使用的是EP4CE15F23C8 xff0c 软件使用的是quartus 12 1 xff0c 工程实现的功能是使用uart进行回环测试 顶层 module uart test i clk i rst n rx tx input i