设计目标:设计一个串口IP,要求1:输入时钟频率任意,如0-400M时钟频率;要求2:波特率超过常见的115200,要求达到4M.

设计核心思路:波特率计算公式,divp10x = (10 * fsysclk) / (16 * baud),divp10x 是10倍分频系数,当给定一个参考时钟和波特率,那么分频系数就定了,这里16指16倍波特率时钟采样。

为何进行16倍过采样,防止误采样数据,即一般采样时钟频率大于波特率时钟频率的16倍,数据一般不出错。本次为了便于在实际中应用,采用8倍采样,故采样时钟仅为16倍的一半。波特率4M,本次的采样时钟仅需64M,此时分频系数为2.

做设计的思路:一:先搭建仿真环境,即能够测试串口IP,同时仿真包含顶层模块,主机的串口发送(调用串口IP),从机的串口发送和接收,SDRAM存储器给串口IP的相应寄存器地址和读写命令。看出仿真模块是重要的,并且模块众多和功能全面。二:仿真测试串口IP能够实现的功能和各模块的驱动逻辑。即波特率能支持到几兆,并且数据不出错。例如,刚开始测量常见波特率9600,115200等都能达到,后面上网一查才知道波特率和波特率参考时钟有对应关系,必须符合才能正确发送。还发现了高波特率低误差的实现,需要的条件,根据波特率计算公式,串口系数必须大于2等要求。第三步,在仿真测得相应参数,时钟 频率和波特率值后,下载程序到开发板验证,分别是发送端和接受端波特率都能达到4M,或者连接逻辑分析仪,设置触发条件和观察对应的数据波形。

核心代码:

module baudset(
rst,
sysclk,
rxclk
);

input rst ;
input sysclk;
output rxclk ;

reg rxclk;

parameter fsysclk = 64_000_000;
parameter baud = 115_200;
parameter divp10x = (10 * fsysclk) / (16 * baud);
parameter divp1x = fixv(divp10x);
parameter N = wordsize(divp1x);
parameter divp = fixv2(divp1x);
parameter low = 1'b0;
parameter hi = 1'b1;

reg [N-1:0] cnt1 = {N{1'b0}};
// reg [3:0] cnt2 = 4'd0;

//------------function-----------//
function [31:0]fixv;
input [31:0]value10x;
fixv = value10x % 10 < 5 ? value10x / 10 : (value10x / 10) + 1;
endfunction

function [N-1:0]fixv2;
input [31:0]value;
fixv2 = value;
endfunction

function [5:0]wordsize;
input [31:0]value;
begin
wordsize = 1'b1;
while((32'b1 << (wordsize - 1'b1)) < value) wordsize = wordsize + 1'b1;
end
endfunction
//---------------------------------//

always @(posedge sysclk or negedge rst)
begin
if(rst == low)
begin
cnt1 <= {N{1'b0}};
rxclk <= hi;
end
else if(cnt1 == (divp >> 1'b1))
begin
cnt1 <= cnt1 + 1'b1;
rxclk <= low;
end
else if(cnt1 == (divp - 1'b1))
begin
cnt1 <= {N{1'b0}};
rxclk <= hi;
end
else
begin
cnt1 <= cnt1 + 1'b1;
end
end

/*
assign txclk = cnt2[3];

always @(posedge rxclk or negedge rst) begin
if(rst == low) begin
cnt2 <= 4'd0;
end
else begin
cnt2 <= cnt2 + 1'b1;
end
end
*/
endmodule

问题及解决办法:

问题一:仿真测得波特率达到4M的参考时钟且数据正确接收时,下载到开发板出错:

方法是,首先得看看硬件支不支持,原来是开发板的串口模块不支持,RS232只能到115200,然后查阅资料直到USB转串口芯片CH340能够到2M,用网络调试助手测试还是发现出错,但仿真没有问题,原来多种方法测试,由于软件的问题,那就换成官方CH340的软件串口助手,发现波特率能够到达2M。启示:用一个电子器件时或学一样东西,用官方芯片的驱动和软件,才是最正确的。要到4M,又得换一个更强的硬件芯片,即USB2XX,一个串口转芯片,能到4M,并且看了这个芯片的手册和装了它的软件。再烧写程序到开发板验证,果然可以到4M,后面就是发现对应的时钟频率为200M,得用锁相环产生这个频率。

问题二:16倍波特率采样,波特率达到4M对应的时钟频率太高,得降一半才行。

仔细分析了一下,主要是这个波特率计算公式:divp10x = (10 * fsysclk) / (16 * baud);即参考时钟至少是波特率的16倍,那要波特率不变,降低参考时钟频率,只需将16倍改成8倍采样即可。首先就得找出实现16倍样的逻辑。看了模块的代码,波特率产生模块,产生了一个16倍波特率分频时钟Clk16X,传递给其他模块作为时钟信号。主要是在四个模块中用到:sram_slave(其实可忽略,没用到),Rxcver(做了很多模块的驱动时钟,)Txmitt(核心应用模块)baudset(波特率产生模块)。要看懂16倍波特率采样逻辑,那就得看懂baudset和Txmitt的代码。

问题三;怎么看懂源码?

步骤一:先画出这个模块的框图(区别输入输出),看看输出怎么被驱动,能大概找到输入与输出的逻辑。步骤二:关键一步,仿真。通过仿真看看数据流动,输入输出信号的关系。(很重要,自己理解往往不准确,波形很直观准确反映驱动条件和执行逻辑)。步骤三(学习的心态),在看懂别人的思路后,自己动手写,不断调试直到实现功能。

问题四:从机串口接收和发送模块的数据错误为为8'b8.正确该为8'6c

解决过程:

刚开始完全乱猜,就胡乱修改代码,以为是波特率问题或者divclk_en该延迟一个时钟周期,即主观臆断瞎蒙。改来改去发现还是错的。

后面觉得这种做法是错误的,又不是写作文或做梦,全凭自己胡乱想,正确的做法,该是看看世界是怎样的,自己怎么想不重要。即该认真看波形,数据出错,那就看看到底是哪个代码驱动条件导致它错的。即根据现象找到原因,逻辑分析,依据客观世界去活,而不是自己的主观世界。我就一级级找,根据驱动逻辑分析,直到Txmitt模块,TxCNT_R模块和uart_rxs模块的cnt_bit信号,两个模块的计数器信号没有对齐延迟了7个周期。(找到出错的地方)

3.11日,第二天,我又继续分析,,发现这两个计数信号的计数加一规律不一样,TxCNT_R一个是16个时钟周期。uart_rxs模块的cntbit信号是12个时钟。原来是这样的,那改成一样的加一规律即可。然后我再分析他们加一的驱动条件是啥,再次改成都是同样的驱动条件即可。

待发送的数据是8‘h6c,可以从波形看出,接受模块的发送线tx,发送的数据是从低位开始,直到最高位,故发送线是0011_0110.从波形看出,8位数据位计数器cnt_bit与发送线对应的数据相合,而且数据也是待发送的8‘h6c。

通过这次调试程序,最大感悟是:以分析现象明确原因,找出逻辑关系为原则(仿真,追根溯源,不断由输出到驱动条件一级级分析)。而不是自己猜想和胡乱改的。

参考博客:

长弓的坚持----为什么UART串口通信要16倍过采样数据

https://blog.csdn.net/wordwarwordwar/article/details/80178708?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522163028678816780264043616%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=163028678816780264043616&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_v2~rank_v29-1-80178708.pc_v2_rank_blog_default&utm_term=%E4%B8%BA%E4%BB%80%E4%B9%88%E4%B8%B2%E5%8F%A3%E8%A6%8116%E5%80%8D%E8%BF%87%E9%87%87%E6%A0%B7&spm=1018.2226.3001.4450

实习项目1-串口IP升级调试的更多相关文章

  1. React-Native项目在Android真机上调试

    目录 1.确保你的设备已经成功连接.可以终端输入adb devices来查看: 2.终端运行npm start 开启本地服务,成功后运行react-native run-android来在设备上安装并 ...

  2. Vue项目无法使用局域网IP直接访问的配置方法

    一般使用 vue-cli 下来的项目是可以直接访问局域网 IP 打开的,比如 192.168.1.11:8080 .但是最近公司的一个项目只可以通过 localhost 访问. 需要配置一下,才可直接 ...

  3. 七. jenkins部署springboot项目(4)-linux环境--远程调试

    前提:linux环境,jenkins服务器和springboot服务器不在一台机器. linux环境,jenkins这里就不说了,主要说下和windows环境的不同. 1. jenkins服务器连接s ...

  4. Qt小项目之串口助手控制LED

    Qt小项目之串口助手控制LED 前言 最近刚学了一点Qt开发上位机,尝试着做个小软件练练手.查找了很多资料,做了一个简单的串口助手,可以实现串口基本发送和接收功能,支持中文显示,还可以控制STM32开 ...

  5. Linux中一个网卡含有多个IP,将从IP升级为主IP的方法

    今天在查看虚拟机的时候,发现某一网卡含有多个IP地址: eno16777736: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu qdisc pfifo_fas ...

  6. vs2008 c#项目调试dll源码,问题:“若要调试此模块,请将其项目生成配置更改为“调试”模式” 的解决方案

    情况: 1:有程序 Trans.exe 的vs2008 c#源码:Trans.exe项目里引用了 Water.dll: 2:有Water.dll的项目源码: 3:想在Trans.exe里调试Water ...

  7. Delphi 使用串口模拟工具进行串口程序开发调试

      版权声明:本文为博主原创文章,如需转载请注明出处及作者. 本文由小李专栏原创,转载需注明出处:[http://blog.csdn.net/softwave/article/details/8907 ...

  8. 串口WIF简单调试

    /*********************************************************************** Title:Wifi串口调试 Hardware: Wi ...

  9. 数据调试~~TCP转串口、串口转TCP调试

    Android socket开发了一个socket客户端,当输入服务器ip以及端口,建立连接之后,Android可以发送数据到电脑接收服务器端. 如果电脑端没有socket服务器怎么办?方法如下: 1 ...

随机推荐

  1. MXNet学习-第一个例子:训练MNIST数据集

    一个门外汉写的MXNET跑MNIST的例子,三层全连接层最后验证率是97%左右,毕竟是第一个例子,主要就是用来理解MXNet怎么使用. #导入需要的模块 import numpy as np #num ...

  2. Solution -「SDOI 2018」「洛谷 P4606」战略游戏

    \(\mathcal{Description}\)   Link.   给定一个 \(n\) 个点 \(m\) 条边的无向连通图,\(q\) 次询问,每次给出一个点集 \(s\),求至少在原图中删去多 ...

  3. Solution -「HEOI/TJOI 2016」「洛谷 P2824」排序

    \(\mathcal{Description}\)   Link.   给定排列 \(\{p_n\}\) 和 \(m\) 次局部排序操作,求操作完成后第 \(q\) 位的值.   \(n,m\le10 ...

  4. [LeetCode]7. 整数反转(Java)

    原题地址: reverse-integer 题目描述: 给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果. 如果反转后整数超过 32 位的有符号整数的范围 [−2^31,  ...

  5. Word 模板注入

      要实现word模板注入,需要一个被注入的文档,以及一个注入用的模板. 1.创建一个启用宏的模板   打开word,alt+f8创建编辑宏,在Project->Microsoft Word对象 ...

  6. windows mysql数据存储路径更改

    背景:之前服务器磁盘很小,随着数据量的不断增加,磁盘不够,所以新申请了更大的磁盘,然后需要将旧路径下的数据迁移到新磁盘上. 1.任务管理器-打开服务,找到mysql的启动项,停止服务,属性查看可执行文 ...

  7. for循环例子2

    代码 点击查看[ForTest2.java]代码 //package com.d; import java.util.Scanner; /** * for循环例子2 * @date: 2022.2.2 ...

  8. 【C#基础概念】编程语言:弱类型、强类型、动态类型、静态类型

    一.看图区别编程语言 一般来讲,看第一个图就够了 这图是引用的,有错误,Python是强类型,但是图片中却归为弱类型了. 业界堆静态和动态的区分达到共识. 但是堆强类型和弱类型语言还未达成共识.我个人 ...

  9. 二叉树的N中遍历方式和拓展应用

    (一)创建二叉树,如下图所示,一个标准的二叉树是所有位于根节点的左侧的子节点都是比根节点小的,右侧则都是大于根节点的. public class BinaryNode { public int val ...

  10. Qt:打包成可执行文件(exe文件)后出现Driver not Loaded的解决方法

    问题 在当前电脑上打包为exe可以正常执行,发送给另一台电脑后却无法执行,并且出现"Driver not loaded"的提示框. 可能原因 1.另一台电脑上没有MySQL(或ex ...