当前位置: 首页 > news >正文

12 ABC串口接收原理与思路

1. 串口接收原理

基本原理:通过数据起始位判断要是否要开始接收的数据,通过采样的方式确定每一位数据是0还是1。

如何判断数据起始位到来:通过边沿检测电路检测起始信号的下降沿

如何采样:一位数据采多次,统计得到高电平出现的次数,次数多的就是该位的电平值

2. 自己写的代码(不完善)

设计代码

module uart_byte_rx(clk,rstn,uart_byte_rx,blaud_set,data,rx_done
);input clk;input rstn;input uart_byte_rx;input blaud_set;output reg [7:0] data;output reg rx_done;//Blaud_set = 0时,波特率 = 9600;//Blaud_set = 1时,波特率 = 19200;//Blaud_set = 2时,波特率 = 38400;//Blaud_set = 3时,波特率 = 57600;//Blaud_set = 4时,波特率 = 115200;reg[17:0] bps_dr;always@(*)case(blaud_set)0: bps_dr = 1000000000/9600/20;1: bps_dr = 1000000000/19200/20;2: bps_dr = 1000000000/38400/20;3: bps_dr = 1000000000/57600/20;4: bps_dr = 1000000000/115200/20;endcasereg [1:0] test;reg get_en;always@(posedge clk or negedge rstn) //边沿检测,使能后续的采样if(!rstn) begindata <= 0;test <= 0;get_en <= 0;rx_done <= 0;endelse begintest[0] <= uart_byte_rx;test[1] <= test[0];if((test[0] ==0 )&&(test[1] == 1))get_en <= 1;rx_done <= 0;endreg [17:0] div_cnt;reg [3:0] counter;reg [3:0] tx_counter;always@(posedge clk or negedge rstn) //计数时钟,一个计数周期代表一位数据if(!rstn) div_cnt <= 0;else if(get_en)beginif(div_cnt == 434 - 1)div_cnt <= 0;elsediv_cnt <= div_cnt + 1'd1;end        wire bps_clk;assign bps_clk = (div_cnt == 1);always@(posedge clk or negedge rstn) //数据段,包含起始位和终止位,共十段if(!rstn) tx_counter <= 0;else if(get_en)beginif(tx_counter == 11)tx_counter <= 0;else if(div_cnt == 1)tx_counter <= tx_counter + 1'd1;end       always@(posedge clk or negedge rstn) //数据采样,每段数据采样8次。if(!rstn)counter <= 0;else if(div_cnt == 3)counter <= 0;else if((div_cnt == 1*433/8 - 10)||(div_cnt == 2*433/8 - 10)||(div_cnt == 3*433/8 - 10)||(div_cnt == 4*433/8 - 10)||(div_cnt == 5*433/8 - 10)||(div_cnt == 6*433/8 - 10)||(div_cnt == 7*433/8 - 10)||(div_cnt == 8*433/8 - 10))counter <= counter + uart_byte_rx;always@(posedge clk or negedge rstn) //if(!rstn) counter <= 0;else if(div_cnt == 2)case(tx_counter)2:if(counter > 4 )data[0] <= 1; else if(counter <4) data[0] <= 0;3:if(counter > 4 )data[1] <= 1; else if(counter <4) data[1] <= 0; 4:if(counter > 4 )data[2] <= 1; else if(counter <4) data[2] <= 0; 5:if(counter > 4 )data[3] <= 1; else if(counter <4) data[3] <= 0; 6:if(counter > 4 )data[4] <= 1; else if(counter <4) data[4] <= 0; 7:if(counter > 4 )data[5] <= 1; else if(counter <4) data[5] <= 0; 8:if(counter > 4 )data[6] <= 1; else if(counter <4) data[6] <= 0; 9:if(counter > 4 )data[7] <= 1; else if(counter <4) data[7] <= 0;11:begin rx_done <= 1; get_en <= 0; div_cnt <= 0; enddefault: begin rx_done <= 0; data <= data; endendcase        
endmodule

仿真波形

3. 看完视频后写的代码(完善)

设计代码

3.1 需学习的点:

1.将div_cnt划分为最小时间段

2.某些判断信号直接用assign利用,而不需要利用寄存器

3.仿真代码中task的使用

module uart_byte_rx1(clk,rstn,blaud_set,uart_rx,data,rx_done
);input clk;input rstn;input [2:0]blaud_set;input uart_rx;output reg [7:0] data;output rx_done;reg [8:0] bps_dr;always@(*)case(blaud_set)0:bps_dr = 1000000000/9600/16/20;1:bps_dr = 1000000000/19200/16/20;2:bps_dr = 1000000000/38400/16/20;3:bps_dr = 1000000000/57600/16/20;4:bps_dr = 1000000000/115200/16/20;default : bps_dr = 1000000000/9600/16/20;endcase//边沿信号检测reg [1:0] uart_rx_r; //用两位寄存器分别存储两个时间沿的uart_rx信号always@(posedge clk) beginuart_rx_r[0] <= uart_rx;uart_rx_r[1] <= uart_rx_r[0];end//将两位寄存器的值直接通过导线输出进行判断(不需要再使用寄存器)wire nedge_uart_rx;  //掌握一下这个方法,之前一直使用的是寄存器//法一://assign nedge_uart_rx = ((uart_rx_r[0] == 0)&&(uart_rx_r == 1));//法二:assign nedge_uart_rx = (uart_rx_r == 2'b10);reg rx_en;always@(posedge clk or negedge rstn)if(!rstn)rx_en <= 0;else if(nedge_uart_rx)rx_en <= 1;else if(rx_done)rx_en <= 0;//周期计数器reg [8:0] div_cnt;always@(posedge clk or negedge rstn)if(!rstn)div_cnt <= 0;else if(rx_en) beginif(div_cnt == bps_dr - 1)div_cnt <= 0;elsediv_cnt <= div_cnt + 1'd1;endelsediv_cnt <= 0;wire [3:0]bps_clk_16x; //(一定要记得加位宽)采样信号,这种写法很灵活assign bps_clk_16x = bps_dr/2; //采样每一段的中点值,同时也可以用它来计数。//发送一字节的数据有需要十个数据位,每位数据有16个小段供采样,共160reg [7:0]bps_cnt;always@(posedge clk or negedge rstn)if(!rstn)bps_cnt <= 0;else if(rx_en) beginif(bps_cnt == 159)bps_cnt <= 0;else if(div_cnt ==bps_clk_16x)bps_cnt <= bps_cnt + 1'd1; endelse  bps_cnt <= 0;reg[2:0] r_data[7:0];//二维数据,代表八个r_data,每个r_data有3位寄存器存储数值。reg[2:0] sta_data;reg[2:0] sto_data;always@(posedge clk or negedge rstn)if(!rstn)beginsta_data <= 0;sto_data <= 0;r_data[0] <= 0; //语法规定,二维数组赋值要分开赋值r_data[1] <= 0;    r_data[2] <= 0;r_data[3] <= 0;    r_data[4] <= 0;  r_data[5] <= 0;    r_data[6] <= 0; r_data[7] <= 0;        endelse if(div_cnt == bps_clk_16x - 1)case(bps_cnt) //下面合在一起的写法是允许的0:beginr_data[0] <= 0; r_data[1] <= 0;    r_data[2] <= 0;r_data[3] <= 0;    r_data[4] <= 0;  r_data[5] <= 0;    r_data[6] <= 0; r_data[7] <= 0;end   5,6,7,8,9,10,11: sta_data <= sta_data + uart_rx;21,22,23,24,25,26,27: r_data[0] <= r_data[0] + uart_rx;37,38,39,40,41,42,43: r_data[1] <= r_data[1] + uart_rx;53,54,55,56,57,58,59: r_data[2] <= r_data[2] + uart_rx;69,70,71,72,73,74,75: r_data[3] <= r_data[3] + uart_rx;85,86,87,88,89,90,91: r_data[4] <= r_data[4] + uart_rx;101,102,103,104,105,106,107: r_data[5] <= r_data[5] + uart_rx;117,118,119,120,121,122,123: r_data[6] <= r_data[6] + uart_rx;133,134,135,136,137,138,139: r_data[7] <= r_data[7] + uart_rx;149,150,151,152,153,154,155: sto_data <= sto_data + uart_rx;default:;endcase        reg rx_done;always@(posedge clk or negedge rstn)if(!rstn)rx_done <= 0;else if(bps_cnt == 159) beginrx_done <= 1;endelserx_done <= 0;//数据接收完成后赋值给data输出always@(posedge clk or negedge rstn)if(!rstn)data <= 0;else if(rx_done)begindata[0] <= (r_data[0] >= 4 ) ? 1 : 0; //可换种写法,写法如下data[1] <= (r_data[1] >= 4 ) ? 1 : 0;data[2] <= (r_data[2] >= 4 ) ? 1 : 0;data[3] <= (r_data[3] >= 4 ) ? 1 : 0;data[4] <= (r_data[4] >= 4 ) ? 1 : 0;data[5] <= (r_data[5] >= 4 ) ? 1 : 0;data[6] <= (r_data[6] >= 4 ) ? 1 : 0;data[7] <= (r_data[7] >= 4 ) ? 1 : 0;end// data[1] <= r_data[1][2]// 0:3'd000// 1:3'd001// 2:3'd010// 4:3'd100// 5:3'd101// 6:3'd110// 7:3'd111 利用第3位的区别给data赋值endmodule

仿真代码

`timescale 1ns/1nsmodule uart_byte_rx1_tb();reg clk;reg rstn;reg uart_rx;wire [2:0]blaud_set;wire [7:0]data;wire rx_done;uart_byte_rx1 uart_byte_rx_inst1(.clk(clk),.rstn(rstn),.blaud_set(blaud_set),.uart_rx(uart_rx),.data(data),.rx_done(rx_done));assign blaud_set = 3'd4;initial clk = 1;always #10 clk = ~clk;initial beginrstn = 0;uart_rx = 1;#201;rstn = 1;#200;uart_tx_byte(8'h5a);@(posedge rx_done)#5000;uart_tx_byte(8'ha5);@(posedge rx_done)#5000;uart_tx_byte(8'h86);@(posedge rx_done)#5000;$stop;endtask uart_tx_byte;input [7:0] tx_data;beginuart_rx = 1;#20;uart_rx = 0;#8680;uart_rx = tx_data[0];#8680;uart_rx = tx_data[1];#8680;uart_rx = tx_data[2];#8680;uart_rx = tx_data[3];#8680;uart_rx = tx_data[4];#8680;uart_rx = tx_data[5];#8680;uart_rx = tx_data[6];#8680;uart_rx = tx_data[7];endendtaskendmodule

仿真波形

相关文章:

12 ABC串口接收原理与思路

1. 串口接收原理 基本原理&#xff1a;通过数据起始位判断要是否要开始接收的数据&#xff0c;通过采样的方式确定每一位数据是0还是1。 如何判断数据起始位到来&#xff1a;通过边沿检测电路检测起始信号的下降沿 如何采样&#xff1a;一位数据采多次&#xff0c;统计得到高…...

leetcode(二分查找)34.在排序数组中查找元素的第一个和最后一个位置(C++详细解释)DAY11

文章目录 1.题目示例提示 2.解答思路3.实现代码结果 4.总结 1.题目 给你一个按照非递减顺序排列的整数数组 nums&#xff0c;和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。 如果数组中不存在目标值 target&#xff0c;返回 [-1, -1]。 你必须设计…...

算法刷题框架

前言&#xff1a;最近积累了一些算法题量&#xff0c;正在刷东神的算法笔记&#xff0c;监督自己记录下读后启发&#xff0c;顺便帮助道友们阅读 数据结构 这一部分老生常谈&#xff0c;数据的存储方式只有顺序存储和链式存储。 最基本的数组和链表对应这两者&#xff0c;栈…...

跟着cherno手搓游戏引擎【24】开启2D引擎前的项目总结(包括前置知识汇总)

前置技术&#xff1a; c动态链接和静态链接&#xff1a; 隐藏的细节&#xff1a;编译与链接_哔哩哔哩_bilibili 【底层】动态链接库(dll)是如何工作的&#xff1f;_哔哩哔哩_bilibili 预编译&#xff0c;编译&#xff0c;汇编&#xff0c;链接 预编译头文件&#xff1a; 为…...

石子合并+环形石子合并+能量项链+凸多边形的划分——区间DP

一、石子合并 (经典例题) 设有 N 堆石子排成一排&#xff0c;其编号为 1,2,3,…,N。 每堆石子有一定的质量&#xff0c;可以用一个整数来描述&#xff0c;现在要将这 N 堆石子合并成为一堆。 每次只能合并相邻的两堆&#xff0c;合并的代价为这两堆石子的质量之和&#xff0c;…...

IMX6ULL移植U-Boot 2022.04

目录 目录 1.编译环境以及uboot版本 2.默认编译测试 3.uboot中新增自己的开发板 3.编译测试 4.烧录测试 5.patch文件 1.编译环境以及uboot版本 宿主机Debian12u-boot版本lf_v2022.04 ; git 连接GitHub - nxp-imx/uboot-imx: i.MX U-Boot交叉编译工具gcc-arm-10.3-2021.0…...

ES实战-高级聚合

多桶型聚合 1.词条聚合–terms 2.范围聚合–range 3,直方图聚合–histogram/日期直方图 4.嵌套聚合 5.地理距离聚合 include(包含)exclude(不包含) GET /get-together/_search?pretty {"size": 0,"aggs": {"tags": {"terms": {"…...

网络安全产品之认识蜜罐

文章目录 一、什么是蜜罐二、蜜罐的主要类型三、蜜罐的主要功能四、蜜罐的主要组成及核心技术五、蜜罐的优缺点六、蜜罐如何与其他安全工具协同工作&#xff1f;七、什么是“蜜网”&#xff1f;与蜜罐的联系和区别是什么&#xff1f; 蜜罐的概念首次由Clifford Stoll在其1988年…...

推荐《架构探险:从零开始写Java Web框架》

版权声明 本文原创作者&#xff1a;谷哥的小弟作者博客地址&#xff1a;http://blog.csdn.net/lfdfhl 春节读了《架构探险&#xff1a;从零开始写Java Web框架》&#xff0c;一本大概10年前的好书。 本书的作者是阿里巴巴架构师黄勇。黄勇对分布式服务架构与大数据技术有深入…...

Go教程-Go语言简介

这篇文章我们来聊聊Go语言。 Go语言发展历史 以下是Go语言发展的几个里程碑节点&#xff1a; Go一开始是Google内部的一个项目&#xff0c;由三位大佬Rob Pike、Robert Griesemer、Ken Thompson早2007年发起。在2009年11月&#xff0c;Go语言正式对外开源。在2010年&#xf…...

React + SpringBoot + Minio实现文件的预览

思路&#xff1a;后端提供接口&#xff0c;从minio获取文件的预览链接&#xff0c;返回给前端&#xff0c;前端使用组件进行渲染展示 这里我从minio获取文件预览地址用到了一个最近刚开源的项目&#xff0c;挺好用的&#xff0c;大伙可以试试&#xff0c;用法也很简单 官网&am…...

心法利器[107] onnx和tensorRT的bert加速方案记录

心法利器 本栏目主要和大家一起讨论近期自己学习的心得和体会&#xff0c;与大家一起成长。具体介绍&#xff1a;仓颉专项&#xff1a;飞机大炮我都会&#xff0c;利器心法我还有。 2023年新一版的文章合集已经发布&#xff0c;获取方式看这里&#xff1a;又添十万字-CS的陋室2…...

AcWing 122 糖果传递(贪心)

[题目概述] 有 n 个小朋友坐成一圈&#xff0c;每人有 a[i] 个糖果。 每人只能给左右两人传递糖果。 每人每次传递一个糖果代价为 1。 求使所有人获得均等糖果的最小代价。 输入格式 第一行输入一个正整数 n&#xff0c;表示小朋友的个数。 接下来 n 行&#xff0c;每行一个…...

unity的重中之重:组件

检查器&#xff08;Hierarchy&#xff09;面板中的所有东西都是组件。日后多数工作都是和组件打交道&#xff0c;包括调参、自定义脚本组件。 文章目录 12 游戏的灵魂&#xff0c;脚本组件13 玩转脚本组件14 尽职的一生&#xff0c;了解组件的生命周期15 不能插队&#xff01;…...

Linux释放内存

free -m是Linux上查看内存的指令&#xff0c;其中-m是以兆&#xff08;MB&#xff09;为单位&#xff0c;如果不加则以KB为单位。 如下图表示&#xff0c;&#xff08;total&#xff09;总物理内存是809MB&#xff0c;&#xff08;used&#xff09;已使用167MB&#xff0c;&…...

Python算法题集_翻转二叉树

Python算法题集_翻转二叉树 题226&#xff1a;翻转二叉树1. 示例说明2. 题目解析- 题意分解- 优化思路- 测量工具 3. 代码展开1) 标准求解【DFS递归】2) 改进版一【BFS迭代&#xff0c;节点循环】3) 改进版二【BFS迭代&#xff0c;列表循环】 4. 最优算法 本文为Python算法题集…...

Git快速掌握,通俗易懂

Git分布式版本控制工具 介绍 Git是一个开源的分布式版本控制系统&#xff0c;用于敏捷高效地处理任何或小或大的项目。Git是由Linus Torvalds为了帮助管理Linux内核开发而开发的一个开放源码的版本控制软件。Git可以帮助开发者们管理代码的版本&#xff0c;避免代码冲突&#…...

PHP毕业设计图片分享网站76t17

图片分享网站主要是为了提高工作人员的工作效率和更方便快捷的满足用户&#xff0c;更好存储所有数据信息及快速方便的检索功能&#xff0c;对系统的各个模块是通过许多今天的发达系统做出合理的分析来确定考虑用户的可操作性&#xff0c;遵循开发的系统优化的原则&#xff0c;…...

代码随想录 Leetcode45. 跳跃游戏 II

题目&#xff1a; 代码(首刷看解析 2024年2月15日&#xff09;&#xff1a; class Solution { public:int jump(vector<int>& nums) {if (nums.size() 1) return 0;int res 0;int curDistance 0;int nextDistance 0;for (int i 0; i < nums.size(); i) {nex…...

【C语言】socketpair 的系统调用

一、 Linux 内核 4.19socketpair 的系统调用 SYSCALL_DEFINE4(socketpair, int, family, int, type, int, protocol,int __user *, usockvec) {return __sys_socketpair(family, type, protocol, usockvec); } 这段代码定义了一个名为 socketpair 的系统调用。系统调用是操作…...

零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?

一、核心优势&#xff1a;专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发&#xff0c;是一款收费低廉但功能全面的Windows NAS工具&#xff0c;主打“无学习成本部署” 。与其他NAS软件相比&#xff0c;其优势在于&#xff1a; 无需硬件改造&#xff1a;将任意W…...

MFC内存泄露

1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...

基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容

基于 ​UniApp + WebSocket​实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配​微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...

《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》

在注意力分散、内容高度同质化的时代&#xff0c;情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现&#xff0c;消费者对内容的“有感”程度&#xff0c;正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中&#xff0…...

在四层代理中还原真实客户端ngx_stream_realip_module

一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡&#xff08;如 HAProxy、AWS NLB、阿里 SLB&#xff09;发起上游连接时&#xff0c;将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后&#xff0c;ngx_stream_realip_module 从中提取原始信息…...

Robots.txt 文件

什么是robots.txt&#xff1f; robots.txt 是一个位于网站根目录下的文本文件&#xff08;如&#xff1a;https://example.com/robots.txt&#xff09;&#xff0c;它用于指导网络爬虫&#xff08;如搜索引擎的蜘蛛程序&#xff09;如何抓取该网站的内容。这个文件遵循 Robots…...

蓝桥杯3498 01串的熵

问题描述 对于一个长度为 23333333的 01 串, 如果其信息熵为 11625907.5798&#xff0c; 且 0 出现次数比 1 少, 那么这个 01 串中 0 出现了多少次? #include<iostream> #include<cmath> using namespace std;int n 23333333;int main() {//枚举 0 出现的次数//因…...

rnn判断string中第一次出现a的下标

# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...

Java数值运算常见陷阱与规避方法

整数除法中的舍入问题 问题现象 当开发者预期进行浮点除法却误用整数除法时,会出现小数部分被截断的情况。典型错误模式如下: void process(int value) {double half = value / 2; // 整数除法导致截断// 使用half变量 }此时...

搭建DNS域名解析服务器(正向解析资源文件)

正向解析资源文件 1&#xff09;准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2&#xff09;服务端安装软件&#xff1a;bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...