RS232串口通信(UART的接收部分)

置顶

新人博主,创作不易,波形图手绘,请给个点赞关注吧,非常感谢!

串口简介

​ 串口作为常用的三大低速总线(UART、SPI、IIC)之一,在设计众多通信接口和调试 时占有重要地位。 其中UART是异步通信,通信双方是通过起始位停止位来实现信息同步的。SPI和IIC都是同步通信的,通信双方使用统一的时钟频率,在数据传输过程中时钟伴随着数据一起传输,发送方和接收方使用的时钟都是由主机提供的。

串口的优点

  1. 很多传感器芯片或 CPU 都带有串口功能,目的是在使用一些传感器或 CPU时可以通过串口进行调试,十分方便;
  2. 在较为复杂的高速数据接口和数据链路集合的系统中往往联合调试比较困难,可以先使用串口将数据链路部分验证后,再把串口换成高速数据接口。如在做以太网相关的项目时,可以在调试时先使用串口把整个数据链路调通,然后再把串口换成以太网的接口;
  3. 串口的数据线一共就两根,也没有时钟线,节省了大量的管脚资源。

UART

UAR通信只有两根线,一根是发送数据端口线叫tx(Transmitter),一根是接 收数据端口线叫rx(Receiver)。如图所示,对于 PC 来说它的 tx 要和对于 FPGA 来 说的 rx 连接,同样 PC 的 rx 要和 FPGA 的 tx 连接,所以rx和tx都是对于自身来说的。UART 可以实现全双工,即可以同时进行发送数据和接收数据。

串口的通信协议

  1. rx的位宽1bit,从最低位到最高位依次接收

  2. tx的位宽1bit,从最低位到最高位发送

  3. RS232的最基本的帧结构

  4. 波特率:在信息传输通道中,携带数据信息的信号单元叫码元(因为串口是 1bit 进行传输的,所以其码元就是代表一个二进制数),每秒钟通过信号传输的码元数称为码元的传输速率,简称波特率,常用符号“Baud”表示,其单位为“波特每秒(Bps)

  5. 比特率:每秒钟通信信道传输的信息量称为位传输速率,简称比特率,其单位为“每秒比特数(bps)”

实验目标

​ 如图所示,做一个回环测试来验证设计模块的正确性,即发送端发送什么数据,接收端就收到什么数据。

串口接收模块

信号说明

信号 位宽 类型 功能描述
sys_clk 1bit input 工作频率,系统时钟50Mhz
sys_rst_n 1bit input 系统复位信号
rx 1bit input 串口接收信号
po_data 8bit output 串口接收8位rx,转为8位数据
po_data_flag 1bit output 串口接收后转成的 8bit 数据有效标志信号

接收框图

波形设计

起始下降沿

使用打三拍的方式是为了防止亚稳态的出现而导致数据传输错误。这里对亚稳态不做过多的介绍。

接收模块开始接收的信号是通过rx_reg2和rx_reg3产生的下降沿作为起始信号。具体如下波形图所示。

//插入两级寄存器进行数据同步,用来消除亚稳态
//rx_reg1:第一级寄存器,寄存器空闲状态复位为1
always@(posedge sys_clk or negedge sys_rst_n)
beginif(!sys_rst_n)rx_reg1<=1'd1;elserx_reg1<=rx;
end
always@(posedge sys_clk or negedge sys_rst_n)
beginif(!sys_rst_n)rx_reg2<=1'd1;//复位的是reg=1elserx_reg2<=rx_reg1;
end//rx_reg3:第三级寄存器和第二级寄存器共同构成下降沿检测
always@(posedge sys_clk or negedge sys_rst_n)
beginif(sys_rst_n == 1'b0)rx_reg3 <= 1'b1;elserx_reg3 <= rx_reg2;
end

工作使能信号

​ 我们已经生成了一个开始的下降沿信号,通过这个信号我们可以生成一个工作使能信号,这个信号的作用就是,当数据在传输时为1,否则为0。

//work_en:接收数据工作使能信号
always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)work_en <= 1'b0;else    if(start_nedge == 1'b1)work_en <= 1'b1;else    if((bit_cnt == 4'd8) && (bit_flag == 1'b1))work_en <= 1'b0;

波特率计数信号

​ 我们使用的是 9600bps 的波特率 和 PC 机进行串口通信,PC 机的串口调试助手要将发送数据波特率调整为 9600bps。而 FPGA 内部使用的系统时钟是 50MHz,前面也进行过计算,得出 1bit 需要的时间约为 5208 个(因为一帧只有 10bit,细微的近似计数差别不会产生数据错误,但是如果计数值差的过 大,则会产生接收数据的错误)系统时钟周期,那么我们就需要产生一个能计 5208 个数的 计数器来依次接收 10 个比特的数据,计数器每计 5208 个数就接收一个新比特的数据。

parameter UART_BPS = 'd9600; //串口波特率
parameter CLK_FREQ = 'd50_000_000; //时钟频率
localparam BAUD_CNT_MAX = CLK_FREQ/UART_BPS ;//定义波特率的计数值
//baud_cnt:波特率计数器计数,从0计数到BAUD_CNT_MAX - 1
always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)baud_cnt <= 13'b0;else    if((baud_cnt == BAUD_CNT_MAX - 1) || (work_en == 1'b0))baud_cnt <= 13'b0;else    if(work_en == 1'b1)//当开始传输的时候波特率计数器开始计数baud_cnt <= baud_cnt + 1'b1;

位标志信号

​ band_cnt数据在0和5027这两个点的时候是不太稳定的,所以我采用的是中间的点作为bit_flag的高电平的开始。

//此时拉高一个标志信号表示数据可以被取走
always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)bit_flag <= 1'b0;else    if(baud_cnt == BAUD_CNT_MAX/2 - 1)bit_flag <= 1'b1;elsebit_flag <= 1'b0;

数据bit传输个数

​ 如图数据帧中可以看出,需要传输8bit的数据,所以我们要设置一个信号来记录已经传输了的数据bit数,定义为bit_cnt信号,每次bit_flag信号置高的时候,bit_cnt +1。

​ 对于bit_cnt什么时候清0是我们比较关注的,从上述中可以很轻易的知道其中一个条件是bit_cnt=8的时候,另一个条件是bit_flag为高(这个条件是确保第8位数据已经传输完毕)。

bit_cnt清0相当于数据传输结束,所以此时work_en信号置低。

//work_en:接收数据工作使能信号(work_en置低)
always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)work_en <= 1'b0;else    if(start_nedge == 1'b1)work_en <= 1'b1;else    if((bit_cnt == 4'd8) && (bit_flag == 1'b1))work_en <= 1'b0;
//baud_cnt:波特率计数器计数,从0计数到BAUD_CNT_MAX - 1
always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)baud_cnt <= 13'b0;else    if((baud_cnt == BAUD_CNT_MAX - 1) || (work_en == 1'b0))baud_cnt <= 13'b0;else    if(work_en == 1'b1)//当开始传输的时候波特率计数器开始计数baud_cnt <= baud_cnt + 1'b1;

串转并输出

​ 在这里定义一个rx_flag 信号,当数据传输完毕的时候,这个信号拉高一个电平,并且在下一个时钟输出,即:Po_data_flag=rx_flag ,

并且通过移位的方式加rx输入信号转为并行信号po_data 输出。

//rx_flag:输入数据移位完成时rx_flag拉高一个时钟的高电平
always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)rx_flag <= 1'b0;else    if((bit_cnt == 4'd8) && (bit_flag == 1'b1))rx_flag <= 1'b1;elserx_flag <= 1'b0;
//po_data:输出完整的8位有效数据
always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)po_data <= 8'b0;else    if(rx_flag == 1'b1)po_data <= rx_data;//po_flag:输出数据有效标志(比rx_flag延后一个时钟周期,为了和po_data同步)
always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)po_flag <= 1'b0;elsepo_flag <= rx_flag;

解释一下为什么要定义rx_flag

​ 其实定义这个信号的原因是为了并行数据输出和输出标志信号同步,这里读者自行体会。

整体波形图

总结

若有啥疑问和想要完整的工程文件请私聊我 QQ:330965825 ,谢谢!

RS232串口通信(UART的接收部分)相关推荐

  1. 单片机实验八 RS232串口通信实验(接收与发送)

    实验八 RS232串口通信实验(接收与发送) 一.实验目的 1.熟悉实验软件和硬件,进行正确的接线: 2.通过实验了解串口的基本原理及使用,理解并掌握对串口进行初始化: 3.使用串口调试助手做为上位机 ...

  2. 程控电源CANoe上位机面板(CAN\ETH测试、RS232串口通信、编写设计思路)

    程控电源CANoe上位机面板 编写此面板的目的 编写思路 一.通讯方式 1.RS232串口连接 2.CANoe与RS232串口相关的函数 3.帧格式命令字 4.校验码 二.面板设计 1.所需文件说明 ...

  3. linux串口命令UART,STM32串口通信UART使用

    STM32串口通信UART使用 uart使用的过程为: 1. 使能GPIO口和UART对应的总线时钟 2. 配置GPIO口的输出模式 3. 配置uart口相关的基本信息 4. 使能uart口的相关的中 ...

  4. RS232串口通信详解

    RS232串口通信详解http://www.21ic.com/jichuzhishi/datasheet/RS232/jiekou/184659.html 串口是计算机上一种非常通用的设备通信协议. ...

  5. 主板rs232接口测试软件,简洁的RS232串口通信电路与串口通信测试程序

    RS232串口通信电路往往是采用专用的串口传输芯片MAX232(5V)或MAX3232(3.3V),芯片起到驱动.匹配.隔离.保护等作用,这种电路常用于实际系统中的远距离串口通信.多数爱好者搭建串口通 ...

  6. 英飞凌TC264学习(四)串口通信UART

    英飞凌TC264学习(四)串口通信UART 串口部分的函数在LQ_UART.c中 TC264有四路UART中断,需要中断可以来配置中断,与外部中断一样,中断服务函数,中断号,优先级,不需要中断的话就不 ...

  7. 51单片机串口通信发送以及接收代码详解1

    #include <reg51.h> //实验现象:单片接收电脑发送的字符串,并发回给PC端的代码.//函数声明 void uart_init(void); void uart_seng_ ...

  8. 51单片机串口通信发送以及接收代码详解2

    #include <reg51.h> //实验现象:在电脑端没按下发送的时候,单片一直给电脑发送aaa字符串: //实验现象:在电脑端按下发送的时候,结束字符串aaa的发送代码,执行单片接 ...

  9. php接收232通讯接口数据,RS232串口通信的传输格式和接收过程

    串口是计算机上一种非常通用设备通信的协议(不要与通用串行总线Universal Serial Bus或者USB混淆).大多数计算机包含两个基于RS232的串口.串口同时也是仪器仪表设备通用的通信协议: ...

最新文章

  1. iptables 实现地址转换与安全控制
  2. 关于Linux服务器配置java环境遇到的问题
  3. JVM内存GC的骗局——JVM不抛出OOM但内存已经泄露
  4. Altium Designer -- PCB 叠层设计
  5. 是单片机高手还是菜鸟?看看你的程序框架就知道了
  6. Web和HTTP基本术语和概念
  7. erl_0015 《硝烟中的erlang》 读书笔记002 “为过载做计划”
  8. python 输入密码不显示_Python开发实例:隐藏输入密码时屏幕回显
  9. zookeeper注册中心安装(单机版)
  10. ASP.NET 验证控件总结
  11. eharts 中国地图添加城市(散点图实现,含获取城市坐标、图片转base64、自定义散点样式)
  12. 通过matlab实现正交表
  13. 开发人员如何规划自己的职业生涯
  14. C# worksheet设置Excel样式(转载)
  15. Vue中使用v-if判断某个元素满足多个条件的简约写法-案例
  16. IT售前如何写解决方案分析
  17. JavaWeb(Linux)
  18. 夜天之书 #59 饱和沟通:开源社群的消息传递准则
  19. 上位机与1200组态步骤_西门子1200PLC的S7通讯组态编程
  20. 著名基金经理彼得林奇的选股原则

热门文章

  1. Linux下安装显卡驱动及CUDA程序
  2. 做一款APP需要准备哪些资料?上架需要多久?
  3. vue的渲染函数 - render
  4. php过waf 一句话,(转)一句话木马绕过WAF
  5. macw小教程:教你在Mac上登录iOS端游戏,原神ios电脑版教程
  6. DuDuTalk智慧工牌:AI让销售好卖车,门店生意更好做。
  7. layui 时间范围选择
  8. 电脑进入BOOT MENU 按键总结!!!
  9. 旋转矩阵欧拉角万向锁详解
  10. column分栏布局和等高布局和双飞翼布局和圣杯布局