xilinx FPGA 串口设计笔记

2024-06-24 07:32
文章标签 设计 笔记 串口 fpga xilinx

本文主要是介绍xilinx FPGA 串口设计笔记,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

xilinx FPGA  串口设计笔记
在设计中,需要用 FPGA 读取 GPS 内部的信息,GPS 的通信方式为串口,所以在 FPGA
中移植了串口程序。
本次移植的程序源代码是特权的串口程序,本以为移植应该很快就能完成, 但其中还是
出了一写小问题,耽误了不少的时间,下面将问题进行一个总结!
以下是串口的时序:
在设计中,耽误时间最长的问题就是数据老是出错,为了找出问题的所在,用示波器观察了
一下串口发送的数据!
串口发送的软件如图所示:
通过定时发送 hex 数据:0x55,如图:
其中绿色的为电脑发送的串口数据波形,紫色为波特率发生器产生的读数据的触发脉冲,
也就是说在上升沿的时候读取串口信号的数据,从图可以看出,在每个数据的中间段, FPGA
对信号进行了读取,也就是说 FPGA 的波特率设置是没有问题的。
为了进一步的验证,又发了一次 0xaa,进行了一次对比。
通过定时发送 hex 数据:0xaa,如图:
通过上面的测试可知,程序设计的波特率以及读写数据的时序是没有问题的,但是在读数据
的时候依然出现错误。
在此过程中,发了两个数据进行验证。
通过定时发送 hex 数据:0xff,0xff 如图:
在通过发送两个数据后发现,串口发送的一个数据的位数为 10 位,
1bit 下降沿的起始位+8bit 的数据位+1bit 的停止位。
也就是说串口发送的数据长度不是固定的,在没有校验位的情况下,其长度为 10bit,
而特权的程序的,他的串口设置的读取长度为 12bit,这样也就造成了数据的错位,最终导
致数据的整体出错!!
在对程序进行了修改过发现,程序运行正常。
module wi125_time(
input      clk,            // 48MHz 主时钟
input      rst_n,          //低电平复位信号
input      wi125_uart_rx,      // RS232 接收数据信号
output    wi125_data_ok,
output[7:0] wi125_rx_data,
output      ww
);
//----------------------------------串口波特率设置---------------------------------//
//功能:将串口的波特率设置为 38400bps
//----------------------------------------------------------reg[12:0] cnt;                      //分频计数
reg clk_bps;                      //波特率时钟寄存器
reg bps_start;
always @ (posedge clk or negedge rst_n)
if(!rst_n) cnt <= 13'd0;
else if((cnt == 1250) || !bps_start) 
cnt <= 13'd0;                  //波特率计数清零
else 
cnt <= cnt+1'b1;                //波特率时钟计数启动
always @ (posedge clk or negedge rst_n)
if(!rst_n) clk_bps <= 1'b0;
else if(cnt == 625) 
clk_bps <= 1'b1;                //  clk_bps_r 高电平为接收
数据位的中间采样点,同时也作为发送数据的数据改变点
else 
clk_bps <= 1'b0;
assign ww=clk_bps;
//----------------------------------串口波特率设置---------------------------------//
//功能:将串口的波特率设置为 38400bps
//----------------------------------------------------------reg rs232_rx0,rs232_rx1,rs232_rx2,rs232_rx3;  //接收数据寄存器,滤波用
wire neg_rs232_rx;                 //表示数据线接收到下降沿
reg rx_int1,rx_int2;
always @ (posedge clk or negedge rst_n) begin
if(!rst_n) 
begin
rs232_rx0 <= 1'b0;
rs232_rx1 <= 1'b0;
rs232_rx2 <= 1'b0;
rs232_rx3 <= 1'b0;
rx_int1    <= 1'b0;
rx_int2    <= 1'b0; 
end
else 
begin
rs232_rx0 <= wi125_uart_rx;
rs232_rx1 <= rs232_rx0;
rs232_rx2 <= rs232_rx1;
rs232_rx3 <= rs232_rx2;
rx_int1    <= rx_int;
rx_int2    <= rx_int1;
end
end
//下面的下降沿检测可以滤掉<20ns-40ns 的毛刺(包括高脉冲和低脉冲毛刺),
//这里就是用资源换稳定(前提是我们对时间要求不是那么苛刻,因为输入信号打
了好几拍)
//(当然我们的有效低脉冲信号肯定是远远大于 40ns 的)
assign neg_rs232_rx = rs232_rx3 & rs232_rx2 & ~rs232_rx1 & ~rs232_rx0;  // 接收到下降沿
后 neg_rs232_rx 置高一个时钟周期
assign wi125_data_ok = rx_int2&~rx_int1;
//----------------------------------------------------------------reg[3:0] num;                      //移位次数
reg rx_int;                        // 接收数据中断信号,
接收到数据期间始终为高电平
always @ (posedge clk or negedge rst_n)
if(!rst_n) 
begin
bps_start <= 1'bz;
rx_int <= 1'b0;
end
else if(neg_rs232_rx)                //接收到串口接收线 rs232_rx 的
下降沿标志信号
begin   
bps_start <= 1'b1;            //启动串口准备数据接收
rx_int <= 1'b1;              //接收数据中断信号使能
end
else if(num==4'd10)                  //接收完有用数据信息
begin     
bps_start <= 1'b0;            //数据接收完毕,释放波特率启
动信号
rx_int      <= 1'b0;                //接收数据中断信号关闭
end
//---------------------------------------------------------------- 
reg[7:0] rx_data_r;                  //串口接收数据寄存器,保存直
至下一个数据来到
//----------------------------------------------------------------reg[7:0] rx_temp_data;                //当前接收数据寄存器
always @ (posedge clk or negedge rst_n)
if(!rst_n) 
begin
rx_temp_data    <= 8'd0;
num          <= 4'd0;
rx_data_r      <= 8'd0;
end
else if(rx_int) 
begin                          //接收数据处理
if(clk_bps) 
begin                        // 读取并保 存数
据,接收数据为一个起始位,8bit 数据,1 或 2 个结束位
num <= num+1'b1;
case (num)
4'd1: rx_temp_data[0] <= wi125_uart_rx;  //锁存第 0bit
4'd2: rx_temp_data[1] <= wi125_uart_rx;  //锁存第 1bit
4'd3: rx_temp_data[2] <= wi125_uart_rx;  //锁存第 2bit
4'd4: rx_temp_data[3] <= wi125_uart_rx;  //锁存第 3bit
4'd5: rx_temp_data[4] <= wi125_uart_rx;  //锁存第 4bit
4'd6: rx_temp_data[5] <= wi125_uart_rx;  //锁存第 5bit
4'd7: rx_temp_data[6] <= wi125_uart_rx;  //锁存第 6bit
4'd8: rx_temp_data[7] <= wi125_uart_rx;  //锁存第 7bit
default: ;
endcase
end
else if(num == 4'd10)
begin    //我们的标准接收模式下只有 1+8+1(2)=10bit 的有效数据
num <= 4'd0;        //接收到 STOP 位后结束,num 清零
rx_data_r <= rx_temp_data;  //把数据锁存到数据寄存器 rx_data 中
end 
end
assign wi125_rx_data = rx_data_r; 
endmodule

这篇关于xilinx FPGA 串口设计笔记的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

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

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

【学习笔记】 陈强-机器学习-Python-Ch15 人工神经网络(1)sklearn

系列文章目录 监督学习:参数方法 【学习笔记】 陈强-机器学习-Python-Ch4 线性回归 【学习笔记】 陈强-机器学习-Python-Ch5 逻辑回归 【课后题练习】 陈强-机器学习-Python-Ch5 逻辑回归(SAheart.csv) 【学习笔记】 陈强-机器学习-Python-Ch6 多项逻辑回归 【学习笔记 及 课后题练习】 陈强-机器学习-Python-Ch7 判别分析 【学

系统架构师考试学习笔记第三篇——架构设计高级知识(20)通信系统架构设计理论与实践

本章知识考点:         第20课时主要学习通信系统架构设计的理论和工作中的实践。根据新版考试大纲,本课时知识点会涉及案例分析题(25分),而在历年考试中,案例题对该部分内容的考查并不多,虽在综合知识选择题目中经常考查,但分值也不高。本课时内容侧重于对知识点的记忆和理解,按照以往的出题规律,通信系统架构设计基础知识点多来源于教材内的基础网络设备、网络架构和教材外最新时事热点技术。本课时知识

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

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

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

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

论文阅读笔记: Segment Anything

文章目录 Segment Anything摘要引言任务模型数据引擎数据集负责任的人工智能 Segment Anything Model图像编码器提示编码器mask解码器解决歧义损失和训练 Segment Anything 论文地址: https://arxiv.org/abs/2304.02643 代码地址:https://github.com/facebookresear

数学建模笔记—— 非线性规划

数学建模笔记—— 非线性规划 非线性规划1. 模型原理1.1 非线性规划的标准型1.2 非线性规划求解的Matlab函数 2. 典型例题3. matlab代码求解3.1 例1 一个简单示例3.2 例2 选址问题1. 第一问 线性规划2. 第二问 非线性规划 非线性规划 非线性规划是一种求解目标函数或约束条件中有一个或几个非线性函数的最优化问题的方法。运筹学的一个重要分支。2

【C++学习笔记 20】C++中的智能指针

智能指针的功能 在上一篇笔记提到了在栈和堆上创建变量的区别,使用new关键字创建变量时,需要搭配delete关键字销毁变量。而智能指针的作用就是调用new分配内存时,不必自己去调用delete,甚至不用调用new。 智能指针实际上就是对原始指针的包装。 unique_ptr 最简单的智能指针,是一种作用域指针,意思是当指针超出该作用域时,会自动调用delete。它名为unique的原因是这个

SprinBoot+Vue网络商城海鲜市场的设计与实现

目录 1 项目介绍2 项目截图3 核心代码3.1 Controller3.2 Service3.3 Dao3.4 application.yml3.5 SpringbootApplication3.5 Vue 4 数据库表设计5 文档参考6 计算机毕设选题推荐7 源码获取 1 项目介绍 博主个人介绍:CSDN认证博客专家,CSDN平台Java领域优质创作者,全网30w+

查看提交历史 —— Git 学习笔记 11

查看提交历史 查看提交历史 不带任何选项的git log-p选项--stat 选项--pretty=oneline选项--pretty=format选项git log常用选项列表参考资料 在提交了若干更新,又或者克隆了某个项目之后,你也许想回顾下提交历史。 完成这个任务最简单而又有效的 工具是 git log 命令。 接下来的例子会用一个用于演示的 simplegit