鉴于以前对51单片机和STM32单片机串口的编程,对UART的了解仅仅停留在控制寄存器、波特率控制、以及数据缓存区这个层次,直到利用FPGA实现UART之后才对串口的工作流程有了更加深入细致的了解,以发散的思维去学习的话也会对其他通信协议以及数据的采集类FPGA的设计有一定的铺垫意义,接下来就让我们深度解析UART的运行机制。
对于异步串行数据传输协议(UART)我们首先要解决的也要关注的就是串口波特率,波特率——BAUD bps(bit per second)那么对于一个时钟频率为clk的FPGA首先需要进行分频以及确定接收数据的采样点,分频数就为clk/BAUD,那么采样点就应该在clk/BAUD/2为数据持续时间的中间,那么就需要在在这个时钟周期产生一个采样标志,或者称作采样触发,另外我们不能让波特率信号不停的差生,因为是异步串行传输所以只有当有数据需要接收或者需要发送时,按照需要产生波特率信号,这就需要有一个波特率启动标志信号。异步串行的物理接口有两个信号线RXD(数据接收),TXD(数据发送),在没有数据传输时两个信号线都保持高电平,当有数据需要接受时,RXD将被数据的起始位拉低,我们在verilog中用脉冲边沿检测法来检测接口的边沿,就在他的下降沿我们置位波特率启动标志,进而启动波特率发生以接收数据。与此同时只为数据接收标志位用以触发中断或者查询用,并对波特率信号进行计数,因为异步串口传输每一次传输的数据位数都是一定的,当数据位被完全接收完成清空接收标志,同时将数据存入数据接收缓存。
对于数据的发送首先应该有一个触发信号,当有数据需要发送时首先对此信号进行置位,同时置位波特率起始标志位以启动波特率发生。因为这个出发信号决定于外部输入信号的边沿所以最多只能持续一个时钟周期,而我们数据的发送至少要持续10个时钟周期,这就需要我们另外定一个由此触发信号开启由发送计数关闭的发送使能信号。另外也需要对波特率的个数进行计数,当所有的数据位都被发送完成后清除波特率启动标志位关闭波特率发生,并将触发信号清零以标志数据发送完成。
脉冲边沿检测:
对于数据的采集与接收一般都属于时序逻辑,可以利用触发器的时钟延迟来进行检测,
首先定义2个寄存器
Input singnal;
reg edge0;
reg edge1;
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
……………….
Else
Edge0<=signal;
Edge1<=edge1;
end
上面的硬件描述在时钟的上升沿将信号脚的逻辑值赋给edge0,同时将edge0 的值给edge1,那么edge0与edge1刚好相差一个时钟,这样就可以用下面的描述语言检测出信号脚的边沿
Assign edge=edge0^edge1;(上升沿和下降沿都可以检测)
Assign edge=edge0&~edge1;(上升沿可以检测)
Assign edge=edge1&~edge0;(下降沿检测)
文章评论(0条评论)
登录后参与讨论