TI 28335 UART接受异常

TI的28335使用UART接受数据无法正常接收。 数据由 XCOM V2.6发送,内容为ASCII的“Q1234”,接收到的数据每次都不一样。


//###########################################################################
//
// FILE:    lab12-SCIB_RS485_PC
//
//
//
//
//       $Boot_Table:
//
//         GPIO87   GPIO86     GPIO85   GPIO84
//          XA15     XA14       XA13     XA12
 //           PU       PU         PU       PU
//        ==========================================
//            1        1          1        1    Jump to Flash
//            1        1          1        0    SCI-A boot
//            1        1          0        1    SPI-A boot
//            1        1          0        0    I2C-A boot
//            1        0          1        1    eCAN-A boot
//            1        0          1        0    McBSP-A boot
//            1        0          0        1    Jump to XINTF x16
//            1        0          0        0    Jump to XINTF x32
//            0        1          1        1    Jump to OTP
//            0        1          1        0    Parallel GPIO I/O boot
//            0        1          0        1    Parallel XINTF boot
//            0        1          0        0    Jump to SARAM        <- "boot to SARAM"
//            0        0          1        1    Branch to check boot mode
//            0        0          1        0    Boot to flash, bypass ADC cal
//            0        0          0        1    Boot to SARAM, bypass ADC cal
//            0        0          0        0    Boot to SCI-A, bypass ADC cal
//                                              Boot_Table_End$
//
//
//
//###########################################################################

//###########################################################################
#include "DSP2833x_Device.h"     // DSP2833x
#include "DSP2833x_Examples.h"   // DSP2833x
#include "stdlib.h"

/*
Transmission Protocol by Tao Ran and Li Yu;
Date: 2023.05.23;
sysState (1 bit) -> Start = 1 / Stop = 0;
CtrlMode (3 bit) -> Voltage = 000, Current = 001, Ikp = 010, Iki = 011, Icmd = 100, Xcmd = 101, Xkpi = 110, Xkd = 111;
Channel (4 bit) -> 1 = 0001, 2 = 0010, 3 = 0011, 4 = 0100, 5 = 0101, 6 = 0110, 7 = 0111, 8 = 1000, 9 = 1001, 10 = 1010;
Value -> 4 byte float;
Transmit 6 byte a time: message = sysState + CtrlMode + Channel + Value;
*/

// A -> 0 100 0001 -> stop + Icmd + channel 1;

typedef struct DataPacket {
    unsigned sysState : 1; // 1 bit
    unsigned CtrlMode : 3; // 3 bits
    unsigned Channel : 4;   // 4 bits
    float Value;           // 4 bytes
} DataPacket;

float duty1cmd, duty2cmd, duty3cmd, duty4cmd, duty5cmd, duty6cmd, duty7cmd, duty8cmd, duty9cmd, duty10cmd; // Voltage
float I1Cmd, I2Cmd, I3Cmd, I4Cmd, I5Cmd, I6Cmd, I7Cmd, I8Cmd, I9Cmd, I10Cmd; // Current
float I1kpi [2], I2kpi [2], I3kpi [2], I4kpi [2], I5kpi [2], I6kpi [2], I7kpi [2], I8kpi [2], I9kpi [2], I10kpi [2]; // Ikpi
float IpCmdX, InCmdX, IpCmdY, InCmdY, IpCmdZ, InCmdZ; // Icmd
float Xcmd[5]; //Xcmd
float X1kpid[3], X2kpid[3], Y1kpid[3], Y2kpid[3], Zkpid[3]; // Xkpid

int data0 = 0, data1 = 0, data2 = 0, data3 = 0, data4 = 0;

/**********************************************************************************************/
void scib_echoback_init(void);
void scib_xmit(unsigned char byte);
void scib_msg(char *msg);
void scib_fifo_init(void);
void Update(void);
void processCtrlMode(DataPacket receivedPacket);
void setDuty (DataPacket receivedPacket);
void setCurrent (DataPacket receivedPacket);
void setIkp (DataPacket receivedPacket);
void setIki (DataPacket receivedPacket);
void setIcmd (DataPacket receivedPacket);
void setXcmd (DataPacket receivedPacket);
void setXkpi (DataPacket receivedPacket);
void setXkd (DataPacket receivedPacket);
unsigned char scib_rxmit ();
/**********************************************************************************************/

/**********************************************************************************************/
#define InitDIR()                                          \
                     EALLOW;                               \
                     GpioCtrlRegs.GPBPUD.bit.GPIO49 = 0;   \
                     GpioCtrlRegs.GPBDIR.bit.GPIO49 = 1;   \
                     GpioDataRegs.GPBCLEAR.bit.GPIO49 = 1; \
                     EDIS;
#define RX_EN       GpioDataRegs.GPBCLEAR.bit.GPIO49 = 1;
#define TX_EN       GpioDataRegs.GPBSET.bit.GPIO49 = 1;
/**********************************************************************************************/
enum MODE  Mode;
enum CTRLMODE CtrlMode;
enum SYSSTATE sysState;
enum DATA Data;
enum DATA {
    position,
    Current
};
enum SYSSTATE {
    start,
    stop
};
enum CTRLMODE {
    voltage,
    current,
    pid,
    VibCtrl_CTM,
    PosTuning
};
enum MODE {
    debugging,
    operat
};

/********************************************************************************************************/
void main(void)
{
   InitSysCtrl();

   InitScibGpio();

   InitDIR();

   DINT;

   InitPieCtrl();

   IER = 0x0000;
   IFR = 0x0000;
   InitPieVectTable();

    scib_echoback_init();

    sysState = stop;
    CtrlMode = voltage;
    Data = position;
    Mode = debugging;

    while(1){ // No need for for-loop, just go while(1). Updated 2023.05.24 by Tao Ran
        // Update function now handles the receive and processing of a data packet
        Update();
    }
}


void scib_echoback_init()
{
    // Note: Clocks were turned on to the SCIA peripheral
    // in the InitSysCtrl() function
    ScibRegs.SCICTL1.bit.SWRESET =0;
     ScibRegs.SCICCR.all =0x0007;   // 1 stop bit,  No loopback
                                   // No parity,8 char bits,
                                   // async mode, idle-line protocol
    ScibRegs.SCICTL1.all =0x0003;  // enable TX, RX, internal SCICLK,
                                   // Disable RX ERR, SLEEP, TXWAKE

    #if (CPU_FRQ_150MHZ)
          ScibRegs.SCIHBAUD    =0x0001;  // 9600 baud @LSPCLK = 37.5MHz.
          ScibRegs.SCILBAUD    =0x00E7;
    #endif
    #if (CPU_FRQ_100MHZ)
          ScibRegs.SCIHBAUD    =0x0001;  // 9600 baud @LSPCLK = 20MHz.
          ScibRegs.SCILBAUD    =0x0044;
    #endif
    ScibRegs.SCICTL1.all =0x0023;  // Relinquish SCI from Reset
}


// Transmit a character from the SCI
void scib_xmit(unsigned char byte){ // May required adjustment. Updated 2023.05.24 by Tao Ran
    while (ScibRegs.SCICTL2.bit.TXRDY == 0) {}
    ScibRegs.SCIRXBUF.all = byte;
}

void scib_msg(char * msg)
{
    int i = 0;
    TX_EN;
    while(msg[i] != '\0')
    {
        scib_xmit(msg[i]);
        i++;
    }
    scib_xmit(0x0D);
    scib_xmit(0x0A);
    scib_xmit(0x0D);
    scib_xmit(0x0A);
    RX_EN;
}

// Initialize the SCI FIFO
void scib_fifo_init()
{
    ScibRegs.SCIFFTX.all=0xE040;
    ScibRegs.SCIFFRX.all=0x2044;
    ScibRegs.SCIFFCT.all=0x0;
}

void Update(){  //Updated 2023.05.25 by Tao Ran
    DataPacket receivedPacket;
    unsigned char *byte_ptr = (unsigned char*) &receivedPacket;
    // Read the 5 bytes into our struct
    int i = 0;
    for(i = 0; i < sizeof(DataPacket); i++){
        int temp;
        temp = scib_rxmit();
        byte_ptr[i] = temp;
        //byte_ptr[i] = scib_rxmit(); // assuming this is the function to receive a byte
        switch(i){
        case 0:
            data0 = temp;
            break;
        case 1:
            data1 = temp;
            break;
        case 2:
            data1 = temp;
            break;
        case 3:
            data3 = temp;
            break;
        case 4:
            data4 = temp;
            break;
        default:
            break;
        }

    }
    // Now handle the data from the packet
    // If no data need to be transmitted -> channel == 0

    // sysState processing
    if (receivedPacket.sysState == 0b0) {
        // Stop
        sysState = stop;
    } else{
        // Start
        sysState = start;
    }

    // Channel processing
    processCtrlMode(receivedPacket);
}

//CtrlMode (3 bit) -> Voltage = 000, Current = 001, Ikp = 010, Iki = 011, Icmd = 100, Xcmd = 101, Xkpi = 110, Xkd = 111;
void processCtrlMode(DataPacket receivedPacket) {  //Updated 2023.05.24 by Tao Ran
    // Do something with CtrlMode and pass value to execute.
    int Channel = receivedPacket.Channel;

    if (Channel == 0b0 || Channel > 0b1010) {
        // No data to be transmitted
        return;
    }
    switch(receivedPacket.CtrlMode) {
        case 0b000:
            // Voltage
            CtrlMode = voltage;
            setDuty(receivedPacket);
            break;
        case 0b001:
            // Current
            CtrlMode = current;
            setCurrent(receivedPacket);
            break;
        case 0b010:
            // Ikp
            CtrlMode = current;
            setIkp(receivedPacket);
            break;
        case 0b011:
            // Iki
            CtrlMode = current;
            setIki(receivedPacket);
            break;
        case 0b100:
            // Icmd
            CtrlMode = PosTuning;
            setIcmd(receivedPacket);
            break;
        case 0b101:
            // Xcmd
            CtrlMode = pid;
            setXcmd(receivedPacket);
            break;
        case 0b110:
            // Xkpi
            CtrlMode = pid;
            setXkpi(receivedPacket);
            break;
        case 0b111:
            // Xkd
            CtrlMode = pid;
            setXkd(receivedPacket);
            break;
        default:
            // Error
            break;
    }
}

void setDuty (DataPacket receivedPacket){
    switch (receivedPacket.Channel){
        case 0b0001:
            duty1cmd = receivedPacket.Value;
            break;
        case 0b0010:
            duty2cmd = receivedPacket.Value;
            break;
        case 0b0011:
            duty3cmd = receivedPacket.Value;
            break;
        case 0b0100:
            duty4cmd = receivedPacket.Value;
            break;
        case 0b0101:
            duty5cmd = receivedPacket.Value;
            break;
        case 0b0110:
            duty6cmd = receivedPacket.Value;
            break;
        case 0b0111:
            duty7cmd = receivedPacket.Value;
            break;
        case 0b1000:
            duty8cmd = receivedPacket.Value;
            break;
        case 0b1001:
            duty9cmd = receivedPacket.Value;
            break;
        case 0b1010:
            duty10cmd = receivedPacket.Value;
            break;
        default:
            // Error
            break;
    }
}

void setCurrent (DataPacket receivedPacket){
    switch (receivedPacket.Channel){
        case 0b0001:
            I1Cmd = receivedPacket.Value;
            break;
        case 0b0010:
            I2Cmd = receivedPacket.Value;
            break;
        case 0b0011:
            I3Cmd = receivedPacket.Value;
            break;
        case 0b0100:
            I4Cmd = receivedPacket.Value;
            break;
        case 0b0101:
            I5Cmd = receivedPacket.Value;
            break;
        case 0b0110:
            I6Cmd = receivedPacket.Value;
            break;
        case 0b0111:
            I7Cmd = receivedPacket.Value;
            break;
        case 0b1000:
            I8Cmd = receivedPacket.Value;
            break;
        case 0b1001:
            I9Cmd = receivedPacket.Value;
            break;
        case 0b1010:
            I10Cmd = receivedPacket.Value;
            break;
        default:
            // Error
            break;
    }
}

void setIkp (DataPacket receivedPacket){
    switch (receivedPacket.Channel){
        case 0b0001:
            I1kpi[0] = receivedPacket.Value;
            break;
        case 0b0010:
            I2kpi[0] = receivedPacket.Value;
            break;
        case 0b0011:
            I3kpi[0] = receivedPacket.Value;
            break;
        case 0b0100:
            I4kpi[0] = receivedPacket.Value;
            break;
        case 0b0101:
            I5kpi[0] = receivedPacket.Value;
            break;
        case 0b0110:
            I6kpi[0] = receivedPacket.Value;
            break;
        case 0b0111:
            I7kpi[0] = receivedPacket.Value;
            break;
        case 0b1000:
            I8kpi[0] = receivedPacket.Value;
            break;
        case 0b1001:
            I9kpi[0] = receivedPacket.Value;
            break;
        case 0b1010:
            I10kpi[0] = receivedPacket.Value;
            break;
        default:
            // Error
            break;
    }
}

void setIki (DataPacket receivedPacket){
    switch (receivedPacket.Channel){
        case 0b0001:
            I1kpi[1] = receivedPacket.Value;
            break;
        case 0b0010:
            I2kpi[1] = receivedPacket.Value;
            break;
        case 0b0011:
            I3kpi[1] = receivedPacket.Value;
            break;
        case 0b0100:
            I4kpi[1] = receivedPacket.Value;
            break;
        case 0b0101:
            I5kpi[1] = receivedPacket.Value;
            break;
        case 0b0110:
            I6kpi[1] = receivedPacket.Value;
            break;
        case 0b0111:
            I7kpi[1] = receivedPacket.Value;
            break;
        case 0b1000:
            I8kpi[1] = receivedPacket.Value;
            break;
        case 0b1001:
            I9kpi[1] = receivedPacket.Value;
            break;
        case 0b1010:
            I10kpi[1] = receivedPacket.Value;
            break;
        default:
            // Error
            break;
    }
}

void setIcmd (DataPacket receivedPacket){
    switch (receivedPacket.Channel){
        case 0b0001:
            IpCmdX = receivedPacket.Value;
            break;
        case 0b0010:
            InCmdX = receivedPacket.Value;
            break;
        case 0b0011:
            IpCmdY = receivedPacket.Value;
            break;
        case 0b0100:
            InCmdY = receivedPacket.Value;
            break;
        case 0b0101:
            IpCmdZ = receivedPacket.Value;
            break;
        case 0b0110:
            InCmdZ = receivedPacket.Value;
            break;
        default:
            // Error
            break;
    }
}

void setXcmd (DataPacket receivedPacket){
    switch (receivedPacket.Channel){
        case 0b0001:
            Xcmd[0] = receivedPacket.Value;
            break;
        case 0b0010:
            Xcmd[1] = receivedPacket.Value;
            break;
        case 0b0011:
            Xcmd[2] = receivedPacket.Value;
            break;
        case 0b0100:
            Xcmd[3] = receivedPacket.Value;
            break;
        case 0b0101:
            Xcmd[4] = receivedPacket.Value;
            break;
        default:
            // Error
            break;
    }
}

void setXkpi (DataPacket receivedPacket){
    switch (receivedPacket.Channel)
    {
    case 0b0001:
        X1kpid[0] = receivedPacket.Value;
        break;
    case 0b0010:
        X2kpid[0] = receivedPacket.Value;
        break;
    case 0b0011:
        Y1kpid[0] = receivedPacket.Value;
        break;
    case 0b0100:
        Y2kpid[0] = receivedPacket.Value;
        break;
    case 0b0101:
        Zkpid[0] = receivedPacket.Value;
        break;
    case 0b0110:
        X1kpid[1] = receivedPacket.Value;
        break;
    case 0b0111:
        X2kpid[1] = receivedPacket.Value;
        break;
    case 0b1000:
        Y1kpid[1] = receivedPacket.Value;
        break;
    case 0b1001:
        Y2kpid[1] = receivedPacket.Value;
        break;
    case 0b1010:
        Zkpid[1] = receivedPacket.Value;
        break;
    default:
        break;
    }
}

void setXkd (DataPacket receivedPacket){
    switch (receivedPacket.Channel)
    {
    case 0b0001:
        X1kpid[2] = receivedPacket.Value;
        break;
    case 0b0010:
        X2kpid[2] = receivedPacket.Value;
        break;
    case 0b0011:
        Y1kpid[2] = receivedPacket.Value;
        break;
    case 0b0100:
        Y2kpid[2] = receivedPacket.Value;
        break;
    case 0b0101:
        Zkpid[2] = receivedPacket.Value;
        break;
    default:
        break;
    }
}

unsigned char scib_rxmit (){
    while(ScibRegs.SCIRXST.bit.RXRDY != 1) { } // wait for XRDY =1 for empty state
    // Get character
    return ScibRegs.SCIRXBUF.all;
}

估计是你设置时钟来设置波特率与pc机上的波特率不匹配导致数据乱了

一般是串口配置问题,比如波特率不匹配,可以先测试一下发送,看电脑能不能收到期望的内容
参考下这个


完成利用FPGA控制DAC的实验中,在对UART发送数据时,显示中断已经打开,但是把数据发送过去时,并没有显示中断,相当于数据知识发送出去,而没有被接收到,经过debug后,发现原来是在硬件中,vivado中的BD中,UART1所在的Bank1中的电压设定为3.3v,而翻阅开发板原理图发现应该设定为1.8v,设置为3.3v导致数据接收不到原因在于。如图,在UART_RX中接收时,由于在FPGA一端给的电压为3.3v,因此可以满足1.8v的电压要求,数据可以正常的发送给UART,但是在UART一端发送数据给FPGA时,由于FPGA给的电压标为3.3v,根据第二个图可以看出,要想为导通状态,即拉高状态,电压最低为2.4v才行,但是给UART1提供的电压只有最高1.8v,这样就会不满足3.3v的电压要求,就会一直为低的状态,数据就不能发送给FPGA端,就无法在串口出现返回的数据

检查一下波特率、波特率、数据格式等设置是否正确,如果设置不对就会导致数据无法正常接收

引用GPT和自己的思路:

  1. 在初始化SCIB的时候,注意SCIRXBUF的区域在发送完成后需要先读后清零,否则可能导致读到的数据不准确。

  2. 部分寄存器的配置可能会导致接收异常,这里有一个配置推荐参考:

void scib_echoback_init()
{
    ScibRegs.SCICCR.all =0x0007;   // 1 stop bit,  No loopback
                                   // No parity,8 char bits,
                                   // async mode, idle-line protocol
    ScibRegs.SCICTL1.all =0x0003;  // enable TX, RX, internal SCICLK,
                                   // Disable RX ERR, SLEEP, TXWAKE
    ScibRegs.SCICTL2.all =0x0000;
    ScibRegs.SCICCR.bit.RESET = 1; // Software reset

    #if (CPU_FRQ_150MHZ)
          ScibRegs.SCIHBAUD    =0x0000;  // 115200 baud @LSPCLK = 37.5MHz.
          ScibRegs.SCILBAUD    =0x000B;
    #endif
    #if (CPU_FRQ_100MHZ)
          ScibRegs.SCIHBAUD    =0x0000;  // 115200 baud @LSPCLK = 20MHz.
          ScibRegs.SCILBAUD    =0x0021;
    #endif
    ScibRegs.SCICCR.bit.RESET = 0; // Enable SCI

    scib_fifo_init();
}