通讯就是利用电讯设备传送消息或音讯。在DSP控制器间、DSP控制器与其他设备常常需要通讯。与DSP相关的通讯模块有:并行通讯、SCI、CAN、I2C。本文介绍SCI。重点介绍了SCI,叙述了SCI的原理和过程,给出了底层的代码,并通过测试验证了原理正确性和过程可行性及代码正确性。
通讯包含两大类:串行通讯和并行通讯。其中,串行通讯是将信息逐位在数据线上传输,并行通讯是将信息同时在多位数据线上依次传输。因此串行通讯硬件开销小、传输成本低、传输速度慢、适合远距离传输,而并行通讯传输速度快、传输线路多、硬件开销大、不适合远距离传输。
串行通讯分为两大类:同步通讯和异步通讯。其中,同步通讯常常使用同一时钟,而异步通讯使用各自的时钟。
串行通讯的方式有三种,单工,全双工和半双工。其中,单工只有一根数据线,要么发送,要么接收,且发送和接受是固定的;全双工有两根数据线,发送和接收可以同时进行;半双工有一根数据线,既可以发送也可以接收,但是发送和接收不同时进行。
SCI模块属于异步串口通讯,可配置位全双工,也可配置位半双工。
SCI(Serial Communication Interface)即串口通讯接口。
SCI模块里面有接收和发送的子模块,模块框图如下所示:
发送器(TX)及相关寄存器
SCITXBUF:数据发送缓存寄存器,用于存放要发送的数据(由CPU装载)。
TXSHF:发送移位寄存器,从SCITXBUF寄存器接收收据,并将数据移位到SCITXD引脚上,每次移一位数据。
接收器(RX)及相关寄存器
**RXSHF:**接收移位寄存器,从接收的数据移位到SCIRXBUF寄存器,每次移一位数据。
**SCIRXBUF:**数据接收缓存寄存器,从RXSHF寄存器接收数据,CPU就是从SCIRXBUF寄存器读取数据。
一个可编程的波特率产生器
数据储存器映射的控制和状态寄存器。
SCI的发送和接收均具有自己的格式。SCI的接收和发送均采用不归零码格式(NRZ),数据帧格式具体包括:
SCI接收过程描述如下:
当RXENA标志位为1时,使能SCI的接收模块。
当RXENA标志位为0时,禁止SCI的接收模块。数据会到RXSHF,但是不会被移位到SCIRXBUF寄存器。
SCI发送过程描述如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-g52TxD6P-1591196101285)(C:\Users\zhimo\AppData\Roaming\Typora\typora-user-images\image-20200601230513939.png#pic_center)]
当TXENA标志位为1时,使能SCI的发送模块。
当TXENA标志位为0时,禁止SCI的发送模块。
发送和接收还具有2个16级FIFO(先入先出)。发送FIFO寄存器是八位宽,接收FIFO是十位宽。
在标准SCI模式下(未使用FIFO功能?)的一个字的发送缓存器作为发送FIFO和移位寄存器间的发送缓冲器。这里,只有当移位寄存器的最后一位被移除后,一个字的发送缓冲才从发送FIFO装载。使能FIFO后,经过一个可选择的延迟,TXSHF被直接装载而不再使用TXBUF。
在DSP上电复位后,SCI工作在标准SCI模式,禁止FIFO功能。FIFO的相关寄存器都被禁止。
在使用FIFO功能时,发送和接收FIFO都有状态位,这些位显示当前FIFO内数据的个数。当状态位为0时,发送FIFO复位位TXFIFO和接收复位位RXFIFO会被置高,会将FIFO指针复位为0,FIFO重新开始运行。
在进行收发时,均需按照约定的波特率进行发送。
波特率表示每秒钟传送的位数,是衡量数据传送速率的指标。
SCI是由系统的低速时钟提供时钟的,因此波特率是由系统低速外设时钟LSPCLK频率和波特率选择寄存器决定的。
SCI波特率计算公式如下:
S C I 波 特 率 = L S P C L K ( B R R + 1 ) ∗ 8 SCI波特率 = \frac{LSPCLK}{(BRR+1)*8} SCI波特率=(BRR+1)∗8LSPCLK
因此,
B R R = L S P C L K S C I 波 特 率 ∗ 8 − 1 BRR = \frac{LSPCLK}{SCI波特率*8}-1 BRR=SCI波特率∗8LSPCLK−1
F28335还支持硬件自动波特率检测逻辑。增加自动波特率检测功能的SCI通讯接口除了能够满足正常通讯自动检测系统的通讯速率外,还支持采用SCI接口上电引导装载程序,这对于通过上位机采用SCI接口实时更新系统软件非常重要。
SCI作为主从式通讯,DSP常常作为从机实现功能。这里以SCI作为从机为例进行说明。
SCI相关的功能实现包括四部分,
EALLOW;
GpioCtrlRegs.GPBPUD.bit.GPIO62 = 0; // Enable pull-up for GPIO62 (SCIRXDC)
GpioCtrlRegs.GPBPUD.bit.GPIO63 = 0; // Enable pull-up for GPIO63 (SCITXDC)
GpioCtrlRegs.GPBQSEL2.bit.GPIO62 = 3; // Asynch input GPIO62 (SCIRXDC)
GpioCtrlRegs.GPBQSEL2.bit.GPIO63 = 3; // Asynch input GPIO63 (SCITXDC)
GpioCtrlRegs.GPBMUX2.bit.GPIO62 = 1; // Configure GPIO62 for SCIRXDC operation
GpioCtrlRegs.GPBMUX2.bit.GPIO63 = 1; // Configure GPIO63 for SCITXDC operation
EDIS;
ScicRegs.SCICCR.all = 0x0007; //1stop, no parity, 8 char/addrbit(=9bit), idle-line mode
ScicRegs.SCICTL1.all = 0x0003; //bit0, enable RX, bit5, reset SCI, bit1, TXWAKE
ScicRegs.SCICTL2.all = 0x0000; //bit0:TX INT bit1:RX/BK INT all disable
//150MH/4 Band BRR
// 4800 0x03D0
// 9600 0x01E7
// 115200 0x0027
ScicRegs.SCIHBAUD = 0x01;
ScicRegs.SCILBAUD = 0xE7; //对应波特率为9600
ScicRegs.SCIRXST.all = 0x00; //Read access only
ScicRegs.SCIRXEMU = 0x00; //Read access only
ScicRegs.SCIRXBUF.all = 0x00;
ScicRegs.SCICTL1.all = 0x0023; //Relinquish SCI from Reset
在实际应用中,不同设备之间是通过帧格式进行收发的。而根据帧格式的不同,收发机制不同。比如,有的机制下,一边接收,一边解析;而有的机制先完整接收完成一阵后,统一解析处理。关于帧格式,将单独再写一篇文章。
机制不同,选择查询还是中断的方式接收也将不同,是否使用FIFO也不同。这里,使用查询的方式,且不适用FIFO。将以下语句放入定时或者主循环中,就可以接收数据。
if(ScicRegs.SCIRXST.bit.RXRDY)
{
RXBuf = ScicRegs.SCIRXBUF.bit.RXDT;
}
其中,RXBuf为接收字符的变量,这里举例,因此只是使用一个变量,实际中往往使用数组。
由于机制不同,因此没有统一的解析处理方式。这张文章着重叙述底层和SCI模块,将在其他文章中,介绍应用层。
if(ScicRegs.SCICTL2.bit.TXRDY)
{
ScicRegs.SCITXBUF = TXBuf;
}
其中,TXBuf为要发送的数据。
为了验证底层,拟定了一个简单的帧格式。使用DSP作为从机,串口助手作为主机。测试结果如下:
通过测试结果来说,使用该底层配置,可以实现SCI的接收和处理。也说明了介绍的SCI原理的正确性。