Bootstrap

TMS320F28335——SCI

一、SCI?

1、SCI定义

Serial Communication Interface,即串行通信接口,支持同步或异步数据传输。

注:同步:共享一个时钟信号来传输数据,如SPI,I2C,由主设备提供时钟,控制时序。异步:无共享时钟信号,依赖预定义的波特率,如UART(Universal Asynchronous Receiver/Transmitter),双方约定好数据格式。

信号电平标准:

TTL电平:高电平 ≥2.4V(典型5V系统),低电平 ≤0.8V。功耗较高,速度快,适用于短距离板级通信(如芯片间连接)。

CMOS电平:高电平 ≥0.7×Vcc(如5V时为3.5V),低电平 ≤0.3×Vcc。低静态功耗、宽电压范围(3V至15V),抗噪声能力强,适合低功耗场景。

RS-232:负逻辑(±3V至±15V),逻辑“1”为-3V至-15V,逻辑“0”为+3V至+15V。单端信号、点对点全双工,传输距离短(<15米),易受干扰,需电平转换芯片

RS-485:差分信号,逻辑“1”为B线电压高于A线 ≥+0.2V,逻辑“0”为A线电压高于B线 ≥+0.2V。抗干扰强、支持多点通信(最多32节点)、半双工/全双工(四线制),传输距离长(千米级),需终端电阻匹配。

特性TTL/CMOSRS-232RS-485
信号类型单端单端(负逻辑)差分
电平范围TTL: 0-5V;CMOS: 灵活±3V至±15V±2V至±6V(差分电压)
传输距离<1米<15米千米级(1200米@100kbps)
抗干扰能力一般强(共模抑制)
拓扑结构点对点点对点全双工多点(半双工/全双工)
设备数量1对11对1最多32节点(可扩展)
速度与距离关系高速(短距离)低速率(短距离)速率随距离降低
典型应用板级通信设备调试、串口通信工业总线(Modbus)

2、SCI优缺点

优点详细说明缺点详细说明
简单易用硬件接口简单,通常只需少量引脚(如TX、RX),易于实现和调试。传输速率较低相比并行通信,串行通信速率较低,不适合大数据量传输。
低硬件成本无需复杂的外设支持,适合资源有限的嵌入式系统。抗干扰能力有限单端信号(如UART)易受噪声干扰,需额外措施(如差分信号)提高可靠性。
低功耗串行通信功耗较低,适合电池供电设备。点对点通信限制标准UART仅支持点对点通信,多设备通信需额外协议或硬件支持(如RS-485)。
长距离通信能力通过电平转换(如RS-232、RS-485),可实现较长距离的可靠通信。距离与速率矛盾长距离通信时,传输速率需降低以保证信号完整性。
广泛兼容性大多数微控制器和外设都支持SCI接口,易于与其他设备互联。软件开销需编写通信协议和错误处理机制,增加软件开发复杂度。
实时性较好适合低数据量、实时性要求较高的场景(如传感器数据采集)。

二、TMS320F28335的SCI模块

SCI-CPU连接图

SCI结构图

1、SCI信号概况

SCIRXD——SCI异步串行端口——接收数据;

SCITXD——SCI异步串行端口——发送数据;

Baud clock——LSPCLK分频时钟;

TXINT——发送中断;

RXINT——接收中断;

2、多处理器和异步通信模式

SCI有两种多处理器协议(处理器之间通信),即空闲模式和地址位模式。SCI提供通用异步发送/接收(UART)模式与多个常用外设通信。

数据格式:1个bit起始位+1~8个bit数据位+1个bit奇偶校验码(可选)+1~2个停止位。(空闲模式下,如果是地址位模式,需添加1bit作为数据帧和地址帧判别)

空闲模式

地址位模式

3、SCI多处理器通信

在一条总线上,同一时刻只能有一个发送器。一般来说,发送器的第一帧数据当做地址。SCI模块中,SLEEP位置位,当读取到的地址与程序设定一致时,代码中需清零SLEEP位才能使能SCI产生接收中断。

注:SLEEP位置1时,虽然仍能接收器仍运行,但是不会置位RXRDY,RXINT和任意一个接收故障位,除非地址匹配,清零SLEEP或者接收到带有地址位的数据帧(地址位模式下)。SCI不会自动置位/清零SLEEP,由软件决定。

4、识别地址字节

处理器根据选择的模式对字节进行判断。

在空闲模式下,在发送地址字节前会留出与上一帧数据一定的时间间隔。对于处理10个字节以上的数据,该模式效率较高,常用于非多处理器通信。

注:数据块由数据帧组成,帧与帧之间由时间间隔,所以如果要区分地址还是数据,则上面所述的时间间隔的大小应大于帧与帧之间的时间间隔,同时也是用来区分上一个数据块与下一个数据块。一般间隔至少发送10个bit(高电平)所需的时间,基于波特率计算。

起始信号的产生由两种方式:

方式1:上一块的最后一帧与下一块的第一帧间隔至少10个bit(低电平)时间。

方式2:在写数据到SCITXBUF寄存器前置位寄存器SCICTL1的TXWAKE位,就会自动产生11bit的空闲时间。

注:在置位TXWAKE时,需将一个随意的数据写到SCITXBUF,但是不会发送出去,是用来产生空闲时间的。等SCISHF寄存器又空闲时,就可以写入有效数据了。

与TXWAKE相关联的wake-up temporary(WUT)位,当SCITXBUF将数据加载到TXSHF时,TXWAKE也会加载到WUT,如何TXWAKE会自动清零。

在地址位模式下,在每帧数据中会由额外的1个bit(1:表示地址帧,0:表示数据帧)来表示该帧是地址字节还是数据字节,因此帧与帧之间不用时间间隔来区分,对于传输数据量较小,如数据块包含至多11个字节时,效率较高。

添加的位其实由TXWAKE位给定。当发送时,SCITXBUF寄存器和TXWAKE分别加载到TXSHE寄存器和WUT位,然后TXWAKE自动清零,WUT位作为当前帧的地址位。换而言之,当TXWAKE置位时,发送地址帧。

5、SCI通信格式

SCI异步通信格式可以使用单路或者双路通信。数据格式由1bit起始位+1~8个数据位+1bit(奇偶校验位,可选)+1~2bit停止位。

当SCIRXD上保持4个连续SCICLK低电平时,则判定起始信号产生,接收器开始接收数据。如果出现非0,则从头开始,继续寻找4个周期低电平。

对于起始信号后bit,通过3个SCICLK来判断高电平还是低电平。分别在第4~6个周期采样,通过少数服从多数的原则,来决定是高电平还是低电平。如两次采样为1,一次采样为0,则该bit为1。因为接收器同步于自身时钟,所以外部发送和接收设备不需要使用同步时钟,两者各自产生时钟。

注:每个bit占8个SCICLK。

6、SCI接收信号时序

以地址位模式,6bit数据长度为例。当起始信号检测到时,数据开始移入寄存器,检测到停止位时,拉高RXRDY,表示接收完成,从SCIBUF寄存器读取后RXRDY自动清零。

注:当RXENA为低电平时,即禁能接收器。虽然数据仍会移入RXSHF寄存器,但是不会加载到RXBUF寄存器。

7、发送信号时序

TXENA拉高使能发送,接着写入数据到TXBUF,此时图中时刻1 TX EMPTY为低表示TXSHF寄存器空,时刻2写数据到TXBUF寄存器,TXRDY拉低,时刻3表示加载到TXSHF寄存器完成,TX EMPTY为低电平表示TXSHF寄存器为非空,TXRDY拉高,可以写入第二个字节了。接着在时刻4数据写入完成,拉低TXRDY。在时刻5第一个字节发送完成,接着第二字节移入TXSHF寄存器,TXRDY拉高表示TXBUF为空,TX EMPTY依旧为低电平,因为TXSHF一直非空。在时刻6禁能发送,但已经正在发送,所以等发送第二个字节后(时刻7),由于TXRDY一直为高,说明没有写入TXBUF,也就没有加载数据到TXSHF寄存器,所以TXSHF为空,拉高TX EMPTY。

8、SCI中断

SCI接收和发送可以通过中断来完成,两者中断独立。当不使能中断时,中断不产生,但相应的中断标志位会置起。对于发送和接收的优先级,当两者同一时刻产生时,接收的优先级高于发送,从而避免接收溢出。

以接收中断为例,当置位SCICTL2对应的接收使能位RX/BK INT ENA时,如果SCI接收到一帧数据并加载到SCIRXBUF,则会置起RXRDY标志并产生中断请求。或者检测到接收错误(在接收不到停止位后的9.625 bit 周期),就对置起BRKDT标志并产生中断请求。

当TX INT ENA置起,不论何时SCITXBUF的数据加载到TXSHF,都会产生发送中断,TXRDY被置起,表示现在可以写入新数据了。

9、波特率

SCI时钟由低速外设时钟LSPCLK和16bit波特率选择器决定。

注:最小波特率 = LSPCLK/16。

10、SCI FIFO模式

上电复位,SCI默认工作在标准模式下。FIFO模式的发送寄存器为8bit长度,接收寄存器为10bit长度。FIFO发送寄存器将数据加载到标志模式下的发送寄存器TXBUF,TXBUF再将数据加载到TXSHF寄存器。注意只有在TXSHF将最后一个bit移出后,TXBUF才加载FIFOTXBUF的数据。另外,如果使能FIFO模式,则可以配置发送延时,即延时将数据加载到TXSHF寄存器,但不同经过TXBUF。

对于延时发送,通过SCIFFCT寄存器的FFTXDLY0~FFTXDLY7配置,延时时间基于SCI波特率时钟周期计算。

FIFO中断逻辑图

中断标志位一览图

注:FIFO模式下,在延时后TXSHF直接接收数据,不经过TXBUF。

RXERR可以通过BRKDT/FE/OE/PE标志置起。在FIFO模式下,BRKDT中断只能通过RXERR标志位。

11、波特率检测

在SCIFFCT寄存器中,CDC位为1,如果ABD位被置起(硬件置起),则会产生FIFO发送中断。在中断服务结束后软件清零CDC位。如果中断服务后CDC仍位1,也不会重复产生中断。

配置步骤:置位CDC从而使能波特率检测模式,并写1到ABDCLR位清零ABD位;配置波特率为1或者不超过500Kbps。

让主机发送字符“A”或者“a”给SCI接收,则硬件波特率检测电路会测出传输的波特率大小并置位ADB位。硬件波特率检测电路会将测出的值更新到波特率寄存器,接着产生中断。

中断中清零ADB位和CDC位从而禁能波特率检索。从接收寄存器中读取“A”或“a”来清空状态寄存器位。

注:在超过100Kbps的波特率检测,测出的结果准确率会降低。

三、代码示例

标准+空闲+中断模式

目的:上位机发送数据,SCI返回接收数据给上位机。

SCI初始化

#define  SCI_LSPCLK     ((Uint32)(60000000)/4)
#define  BAUD_RATE      ((Uint32)(9600))
void InitSci(void)
{
    Uint16 scibaud = 0;
    EALLOW;
    GpioCtrlRegs.GPBPUD.bit.GPIO36 = 0;  // Enable pull-up for GPIO28 (SCIRXDA)
    GpioCtrlRegs.GPBPUD.bit.GPIO35 = 0;  // Enable pull-up for GPIO29 (SCITXDA)
    GpioCtrlRegs.GPBDIR.bit.GPIO36 = 0;  // Enable pull-up for GPIO28 (SCIRXDA)
    GpioCtrlRegs.GPBDIR.bit.GPIO35 = 1;  // Enable pull-up for GPIO29 (SCITXDA)
    GpioCtrlRegs.GPBQSEL1.bit.GPIO36 = 3;  // Asynch input GPIO28 (SCIRXDA)
    GpioCtrlRegs.GPBMUX1.bit.GPIO36 = 1;   // Configure GPIO28 to SCIRXDA
    GpioCtrlRegs.GPBMUX1.bit.GPIO35 = 1;   // Configure GPIO29 to SCITXDA
    EDIS;

       scibaud = SCI_LSPCLK/(BAUD_RATE*(8)) - 1;
       //波特率
       //SCI Asynchronous Baud = LSPCLK / ((BRR + 1) *8)
       //BRR = (SCIHBAUD << 8) + (SCILBAUD)
       SciaRegs.SCIHBAUD = scibaud>>8;
       SciaRegs.SCILBAUD = scibaud&0x00FF;

       SciaRegs.SCICCR.bit.STOPBITS = 0;//停止位数目1
       SciaRegs.SCICCR.bit.PARITY = 0;//奇校验
       SciaRegs.SCICCR.bit.PARITYENA = 1;//使能校验
       //SciaRegs.SCICCR.bit.LOOPBKENA = ;//loop back test mode,自发自收
       SciaRegs.SCICCR.bit.ADDRIDLE_MODE = 0;
       SciaRegs.SCICCR.bit.SCICHAR = 7;//8位字符长度
       SciaRegs.SCICTL1.bit.RXERRINTENA = 1;//使能SCI接收错误中断

       SciaRegs.SCICTL1.bit.TXWAKE = 1;
     
       SciaRegs.SCICTL1.bit.SLEEP = 0;
       SciaRegs.SCICTL1.bit.TXENA = 1;
       SciaRegs.SCICTL1.bit.RXENA = 1;

       SciaRegs.SCICTL2.bit.RXBKINTENA = 1;//使能接收/break中断  采用FIFO需关闭
       SciaRegs.SCICTL2.bit.TXINTENA = 1;//采用FIFO需关闭

       SciaRegs.SCICTL1.bit.SWRESET = 1;//软件复位写0---->配置完后必须写1


}	

SCI中断配置

void SCI_INTEN(void)
{
    EALLOW;
    PieVectTable.SCIRXINTA = &SCIARX_IRQn;
    PieVectTable.SCITXINTA = &SCIATX_IRQn;

    EDIS;
    PieCtrlRegs.PIEIER9.bit.INTx1 = 1;//SCIA RX
    PieCtrlRegs.PIEIER9.bit.INTx2 = 1;//SCIA TX

    IER |= M_INT9;


    }

interrupt void SCIARX_IRQn()
{
    if(SciaRegs.SCIRXST.bit.RXRDY)
    {
        data = SciaRegs.SCIRXBUF.bit.RXDT;
    }
    GpioDataRegs.GPCTOGGLE.bit.GPIO66  = 1;
    if(( SciaRegs.SCIRXST.bit.RXERROR)||
       (SciaRegs.SCIRXST.bit.BRKDT)||
       ( SciaRegs.SCIRXST.bit.FE)||
       (SciaRegs.SCIRXST.bit.OE)||
       (SciaRegs.SCIRXST.bit.PE))
    {
        GpioDataRegs.GPCTOGGLE.bit.GPIO68  = 1;
    }

       if((SciaRegs.SCICTL2.bit.TXRDY))
      {
            SciaRegs.SCITXBUF = data;
      }

    PieCtrlRegs.PIEACK.bit.ACK9 = 1;

    }
interrupt void SCIATX_IRQn()
{

    GpioDataRegs.GPCTOGGLE.bit.GPIO64  = 1;
    PieCtrlRegs.PIEACK.bit.ACK9 = 1;

    }

main.c


void  led1_Init()
{
    EALLOW;
    GpioCtrlRegs.GPCMUX1.bit.GPIO66 = 0;
    GpioCtrlRegs.GPCDIR.bit.GPIO66  = 1;
    GpioCtrlRegs.GPCPUD.bit.GPIO66  = 1;

    GpioCtrlRegs.GPCMUX1.bit.GPIO68 = 0;
    GpioCtrlRegs.GPCDIR.bit.GPIO68  = 1;
    GpioCtrlRegs.GPCPUD.bit.GPIO68  = 1;

    GpioCtrlRegs.GPCMUX1.bit.GPIO64 = 0;
    GpioCtrlRegs.GPCDIR.bit.GPIO64  = 1;
    GpioCtrlRegs.GPCPUD.bit.GPIO64  = 1;

    EDIS;

    GpioDataRegs.GPCSET.bit.GPIO66  = 1;
    GpioDataRegs.GPCSET.bit.GPIO68  = 1;
    GpioDataRegs.GPCSET.bit.GPIO64  = 1;

    }
int main(void)
{
    InitSysCtrl();
    InitPieCtrl();
    IER = 0x0000;
    IFR = 0x0000;
    InitPieVectTable();
    led1_Init();
    InitSci();
    Peripheral_INT_ENABLE();
    while(1)
    {


     DELAY_US(1000000);

    }


}

;