整个串口控制器包含transmitter和receiver两部分,这两部分功能彼此独立,transmitter负责210向外部发送信息,receiver负责从外部接收信息到210。
总线角度来讲,串口控制器是挂载在APB总线上的,对编程有影响的是:将来计算串口控制器的源时钟时是以APB总线来计算的。
transmitter由发送缓冲区和发送移位寄存器构成。我们要发送信息时,首先将信息进行编码(一般用ASCII码)成二进制流,然后将一帧数据(一般是8位)写入发送缓冲区(从这里以后程序就不用管了,剩下的发送部分由硬件自动完成),最后发送移位寄存器会自动从发送缓冲区中读取一帧数据,然后自动移位(移位的目的是将一帧数据的各个位分别拿出来)将其发送到Tx通信线上。
receiver由接收缓冲区和接收移位寄存器构成。当有人通过串口线向我发送信息时,信息通过Rx通信线进入我的接收移位寄存器中,然后接收移位寄存器自动移位并将该二进制位保存入我的接收缓冲区,接收完一帧数据后receiver会产生一个中断给CPU,CPU收到中断后即可知道receiver接收满了一帧数据,就会来读取这帧数据。
总结:
发送缓冲区和接收缓冲区是关键,发送移位寄存器和接收移位寄存器的工作都是自动的,不用编程控制的,所以我们写串口代码就是:首先初始化串口控制器(包括发送控制器和接收控制器),然后要发送信息时直接写入发送缓冲区,要接收信息时直接去接收缓冲区中读取即可。
软件工程师对串口操作的接口就是发送/接收缓冲区(实际就是寄存器,操作方式就是读写内存)。
串口控制器中有一个波特率发生器,其作用是产生串口发送/接收的时钟节拍。波特率发生器其实就是个时钟分频器,它的工作需要源时钟(从APB总线来),然后内部将源时钟进行分频(需要软件设置寄存器来配置)得到目标时钟,然后再用这个目标时钟产生波特率(由硬件自动完成的)。
FIFO模式及其作用
典型的串口设计,发送/接收缓冲区只有1字节,每次发送/接收只能处理1帧数据。这样在单片机中没什么问题,但是到复杂SOC中(一般有操作系统的)就会有问题,会导致效率低下,因为CPU需要不断切换上下文。
解决方案就是想办法扩展串口控制器的发送/接收缓冲区,譬如将发送/接收缓冲区设置为64字节,CPU一次过来直接给发送缓冲区64字节的待发送数据,然后transmitter慢慢发送,发送完再找CPU再要64字节数据。但是串口控制器本来的发送/接收缓冲区是固定的1字节大小的,所有做了个变相的扩展,就是FIFO。CPU先将64字节的数据放到FIFO中,然后启动FIFO模式,FIFO每次会自动往发送缓冲区中添加1字节数据,最后进行移位操作传输数据。
FIFO,就是first in first out,先进先出。FIFO其实是一种数据结构,这里这个大的缓冲区叫FIFO是因为这个缓冲区的工作方式类似于FIFO这种数据结构。
|