uart基本结构
2输出移位寄存器,它接收从输出缓冲器送来的并行数据,以发送时钟的速率把数据逐位移出,即将并行数据转换为串行数据输出。
3输入移位寄存器,它以接收时钟的速率把出现在串行数据输入线上的数据逐位移入,当数据装满后,并行送往输入缓冲寄存器,即将串行数据转换成并行数据。
4输入缓冲寄存器,它从输入移位寄存器中接收并行数据,然后由CPU取走。
5控制寄存器,它接收CPU送来的控制字,由控制字的内容,决定通信时的传输方式以及数据格式等。例如采用异步方式还是同步方式,数据字符的位数,有无奇偶校验,是奇校验还是偶校验,停止位的位数等参数。
6状态寄存器。状态寄存器中存放着接口的各种状态信息,例如输出缓冲区是否空,输入字符是否准备好等。在通信过程中,当符合某种状态时,接口中的状态检测逻辑将状态寄存器的相应位置“1”,以便让CPU查询。
uart串口的调试
用
FPGA设计了数据接收和发送模块,FIFO模块,此处FIFO调用的是Show-ahead模式,在下一篇博客中将会分析这个问题。
用串口调试工具发送数据,数据接收模块将接收到的串行数据转换为并行数据(串转并),并存入FIFO中,当FIFO中的数据个数大于某个值的时候,读出数据,通过发送模块将并行数据转换为串行数据(并转串),然后就可以在串口调试工具上看到接收到的数据。
注意的点:
1、接收数据时,接收的数据因为不确定什么时候会来,所以有可能出现亚稳态,因此要进行同步处理,打两拍。
2、不论是接收还是发送数据都是从低位开始的。
3、采数据的时侯要在数据中间取值,原因下文有讲。
基本概念:
波特率与比特率?
波特率:单位时间内传输码元的个数(码元是携带数据信息的信号单元,有可能是1位的,也有可能是多位)
比特率:单位时间内传输了多少位数据
比特率=波特率*码元的位数
因为UART数据是一位一位传输的,所以波特率与比特率在这里可以认为是等效的,不用过于纠结,我们就直接理解成1s传送了多少位数据就可以了。
这是一个很不专业的总结,但是能很快理解二者关系。
常用的波特率有 9600,19200,38400等,这里用9600进行详细讲解
波特率位9600,则每一位数据的时间为 1s/9600=1000_000_000 ns/9600 =104166.67ns
因为时钟频率是50Mhz,因此需要104166.67ns/20ns=5208个时钟周期。
这里需要注意的问题是我们的时间并不能整除,有误差,因此设计的时候要在数据的中间取值,这样就可以避免数据出错。
UART数据传输格式
数据格式由起始位、数据位(位数可以位7、8等)、奇偶校验位(可有可无)、停止位(接收数据时可以忽略,发送数据时必须要有停止位)
上面已经说过每个数据的时间为5208个时钟周期,因此需要设计一个计数器cnt_5208
接收数据时为 起始位+8位数据位,即9位数,因此需要一个计数器来指示是哪一位数,cnt_bit。
接收数据时怎么检测有数据要来呢?
空闲时刻,数据线处于高电瓶,有数据来时要发送低电平,因此我们可以利用这个特性进行一个边沿检测,检测到下降沿的时候就知道有数据要来了。
接收数据注意的要点有哪些?
1、亚稳态问题:并不能确定数据什么时候来,所以为了避免出现亚稳态,我们需要对到来的数据进行同步化处理,就是简单的打两拍。
2、最好是在数据稳定的时候采集数据,所以有 clk_en =(cnt_5208 ==
tiME_5208/2 -1)? 1‘b1:1’b0,这个使能信号,可以保证在数据中间时刻采值,正确率高。
发送数据时 起始位0 +8位数据位 +停止位1,同样也需要一个计数器来指示是哪一位数。
发送数据模块注意的要点有哪些?
发送数据模块就是把接收到的数据一位一位发出去,这时候就要设计一个rdy信号告诉外面的模块系统是否处于工作模式,这样可以防止数据的丢失,
我们一板将要发送的数据先缓存起来,然后再一位一位发出去,这样也避免了再发送数据的时候受其他因素影响造成信息错误。
还要注意数据传送的时候都是从低位开始。这一点很重要很重要,否则发送的数据和接收到的数据就不一样,我是深深被伤到了,浪费了好多时间,以后要细心,不能再想当然,要遵守协议。。。。。
调试结果:当发送超过60字节的数据时,就会接收到数据,结果如下。
发送了01020304050607,即4位*14=56位数,即一次发送7字节的数据。