赞
踩
UART实现-黑金fpga开发板案例解析
uart 异步串口通讯 无需时钟线,俩根线一跟复制发数据一根负责收数据。
具体的时序如下图1:
可以看到 当数据线由高位变为地位时,即遇到一个下降沿时刻,表示开始这一次数据开始发送/接受,然后的高低电平表示数据位,一般是7-8个数据位,一般为8个,即一个字节,并可以添加校验位与停止位。
波特率介绍,由于uart
通讯,使用单线单独进行数据传输,所有需要保证发送端与接收端能正常通讯,需要对信号进行约束,简单来说,就是对信号的采样频率进行设定。
当设置波特率为 115200 的时候,如果时钟信号时 50Mhz,这里,数据的一个位的高低电平持续时间应该时 50_000_000 / 115200 这么多个时钟,这样就可以约定发送与接收端,相隔一定的时间对信号线进行采样,得到的每位的高低电平表示这位的数据。
包括收和发的设计,使用状态机的思想进行程序设计
整体的设计思路保持在一个always
语句块里,只对一个reg变量进行赋值。
构造状态机的状态常量
localparam S_IDLE = 1;
localparam S_START = 2; //start bit
localparam S_REC_BYTE = 3; //data bits
localparam S_STOP = 4; //stop bit
localparam S_DATA = 5;
构造状态机的状态变量进行状态切换
reg[2:0] state;
reg[2:0] next_state;
always@(posedge clk or negedge rst_n)
begin
if(rst_n == 1'b0)
state <= S_IDLE;
else
state <= next_state;
end
这里,state是当前时钟的变量,next_state是下一时钟的变量
对输入信号获得俩个节拍
reg rx_d0; //delay 1 clock for rx_pin
reg rx_d1; //delay 1 clock for rx_d0
always@(posedge clk or negedge rst_n)
begin
if(rst_n == 1'b0)
begin
rx_d0 <= 1'b0;
rx_d1 <= 1'b0;
end
else
begin
rx_d0 <= rx_pin;
rx_d1 <= rx_d0;
end
end
这样 可以通过比较d0和d1去判断输入信号的上升沿还是下降沿
assign rx_negedge = rx_d1 && ~rx_d0;
状态机的具体实现
S_IDLE
在这里检测下降沿 如果检测到下降沿 则切换到 S_START
状态
S_START
检测波特率计数器是否计数满 如果计数满了 则跳转到S_REC_BYTE
数据接受状态,如果没满,则保持这个状态,等待计数满,其实也就是一个下降沿之后要保持一个bit的低电平时间之后才开始发送数据
S_REC_BYTE
接受数据状态,在这个状态逐个接受数据,并检测是否接受完毕,完毕则跳转下一个S_STOP
状态,没有则保持这个状态
S_STOP
等待半个bit时间,跳转到下一个S_DATA
状态
S_DATA
always@(*) begin case(state) S_IDLE: if(rx_negedge) next_state <= S_START; else next_state <= S_IDLE; S_START: if(cycle_cnt == CYCLE - 1)//one data cycle next_state <= S_REC_BYTE; else next_state <= S_START; S_REC_BYTE: if(cycle_cnt == CYCLE - 1 && bit_cnt == 3'd7) //receive 8bit data next_state <= S_STOP; else next_state <= S_REC_BYTE; S_STOP: if(cycle_cnt == CYCLE/2 - 1)//half bit cycle,to avoid missing the next byte receiver next_state <= S_DATA; else next_state <= S_STOP; S_DATA: if(rx_data_ready) //data receive complete next_state <= S_IDLE; else next_state <= S_DATA; default: next_state <= S_IDLE; endcase end
接受数据状态时进行接受数据
当在结束收据状态,且bit计数器到一半的时候,进行一次采样,也就是在中点进行采样,获取数据的高低电平,共采集八次,将八次的数据保存到rx_bits
中
reg[7:0]
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。