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和自己的思路:
在初始化SCIB的时候,注意SCIRXBUF的区域在发送完成后需要先读后清零,否则可能导致读到的数据不准确。
部分寄存器的配置可能会导致接收异常,这里有一个配置推荐参考:
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();
}