Fundamentals of Programming and Debugging for DSP28335: Serial Port Programming

Fundamentals of Programming and Debugging for DSP28335: Serial Port Programming

In embedded system development, serial communication is a fundamental and critical technology. The TMS320F28335, as a widely used MCU, has powerful and flexible serial port functions. This article will delve into the serial port application technology of the 28335, including hardware resources, registers and their settings, application programming methods, and verification through experiments.

1. Hardware Resources of 28335 Serial Port

The TMS320F28335 integrates multiple serial communication modules, commonly referred to as SCI (Serial Communication Interface) modules. These modules provide convenient serial communication channels between the chip and external devices for data transmission and interaction.

(1) Overview of SCI Modules

The 28335 typically has multiple SCI modules, such as SCIA, SCIB, etc. Each SCI module has independent transmitters and receivers, enabling full-duplex or half-duplex communication. This feature allows the 28335 to communicate simultaneously with multiple serial devices, greatly expanding its application scenarios. For example, in industrial automation, different SCI modules can communicate with sensors, actuators, and other devices to achieve comprehensive system control.

(2) Pin Configuration

Each SCI module has corresponding pins. Taking SCIA as an example, its main pins include:

SCITXDA (Transmit Data Pin) and SCIRXDA (Receive Data Pin). Before using the serial port function, the corresponding GPIO pins need to be configured as serial port function pins. This process is completed by setting the GPIO control registers to ensure that the pins can correctly send and receive data.

For example, by setting the corresponding bits of the GpioCtrlRegs.GPBMUX1 register, GPIO35 can be configured as the SCITXDA function, and GPIO36 can be configured as the SCIRXDA function.

Fundamentals of Programming and Debugging for DSP28335: Serial Port Programming

2. Registers and Their Settings

The serial communication function of the 28335 is implemented through the configuration of a series of registers, which control various operational parameters and states of the serial port.

(1) Control Registers (SCICTL1, SCICTL2)

1. SCICTL1: Used for basic serial port function control, including software reset (SWRESET), receive enable (RXENA), transmit enable (TXENA), etc. When initializing the serial port, the SWRESET bit is usually cleared first to reset the serial port, and then the RXENA and TXENA bits are set as needed to enable receiving and transmitting functions. For example:

SciaRegs.SCICTL1.bit.SWRESET = 0; // Reset SCI

// Configure other parameters

SciaRegs.SCICTL1.bit.RXENA = 1; // Enable receiving

SciaRegs.SCICTL1.bit.TXENA = 1; // Enable transmitting

SciaRegs.SCICTL1.bit.SWRESET = 1; // Exit reset state

2. SCICTL2: Mainly used for interrupt-related control, such as transmit interrupt enable (TXINTENA), receive interrupt enable (RXBKINTENA), etc.

When using serial port interrupts for data transmission and reception, the corresponding interrupt enable bits need to be set. For example, to enable the receive interrupt:

SciaRegs.SCICTL2.bit.RXBKINTENA= 1; // Enable receive interrupt

(2) Baud Rate Setting Registers (SCIHBAUD, SCILBAUD)

The 28335 sets the baud rate through the SCIHBAUD and SCILBAUD registers.

The calculation formula is:

BRR = LSPCLK / (Baud * 8) – 1, where LSPCLK is the low-speed peripheral clock frequency, and Baud is the desired baud rate.

For example, if LSPCLK is 37.5MHz and the desired baud rate is 9600, the calculated BRR value is:

uint16_t BRR;

BRR = 37500000 / (9600 * 8) – 1;

SciaRegs.SCIHBAUD = BRR >> 8; // Set high 8 bits

SciaRegs.SCILBAUD = BRR & 0x00FF; // Set low 8 bits

(3) Data Format Register (SCICCR)

SCICCR register is used to set the data format of the serial port, including data bit length (SCICHAR), parity bit (PARITYENA), stop bit length (STOPBITS), etc.

The common setting is 8 data bits, no parity bit, and 1 stop bit, configured as follows:

SciaRegs.SCICCR.bit.SCICHAR = 7; // 8 data bits

SciaRegs.SCICCR.bit.PARITYENA = 0; // No parity

SciaRegs.SCICCR.bit.STOPBITS = 0; // 1 stop bit

(4) FIFO Control Registers (SCIFFTX, SCIFFRX, SCIFFCT)

1. SCIFFTX: Used to control the transmit FIFO (First-In-First-Out) queue, including enabling FIFO (SCIFFTX.bit.TXFIFOENA), setting transmit interrupt level (SCIFFTX.bit.TXFFIL), etc. For example, to enable the transmit FIFO and set the transmit interrupt level to 4:

SciaRegs.SCIFFTX.bit.TXFIFOENA = 1; // Enable transmit FIFO

SciaRegs.SCIFFTX.bit.TXFFIL = 4; // Set transmit interrupt level to 4

2. SCIFFRX:

Used to control the receive FIFO queue, including enabling FIFO (SCIFFRX.bit.RXFIFOENA), setting receive interrupt level (SCIFFRX.bit.RXFFIL), etc. For example, to enable the receive FIFO and set the receive interrupt level to 4:

SciaRegs.SCIFFRX.bit.RXFIFOENA = 1; // Enable receive FIFO

SciaRegs.SCIFFRX.bit.RXFFIL = 4; // Set receive interrupt level to 4

3. SCIFFCT: Mainly used to control some characteristics of the FIFO, such as the delay of the transmit FIFO. Generally, the default settings can be maintained, that is:

SciaRegs.SCIFFCT.all = 0x0; // Default settings

3. Application Programming Methods

After understanding the hardware resources and configuring the registers, an application program can be written to implement the serial communication function.

(1) Initialization Function

First, an initialization function for the serial port needs to be written to configure the registers mentioned above to put the serial port in a normal working state. Taking SCIA as an example, the initialization function is as follows:

void InitSciA(void)

{

// Enable SCIA peripheral clock SysCtrlRegs.PCLKCR0.bit.SCIAENCLK = 1;

// Initialize SCIA corresponding GPIO

GpioCtrlRegs.GPBPUD.bit.GPIO36 = 0; // Enable pull-up for GPIO36 (SCIRXDA)

GpioCtrlRegs.GPBPUD.bit.GPIO35 = 0; // Enable pull-up for GPIO35 (SCITXDA)

GpioCtrlRegs.GPBQSEL1.bit.GPIO36 = 3; // Set GPIO36 as asynchronous input (SCIRXDA)

GpioCtrlRegs.GPBMUX1.bit.GPIO36 = 1; // Configure GPIO36 as SCIRXDA function

GpioCtrlRegs.GPBMUX1.bit.GPIO35 = 1; // Configure GPIO35 as SCITXDA function

// Reset SCI

SciaRegs.SCICTL1.bit.SWRESET = 0;

// Configure data format

SciaRegs.SCICCR.bit.SCICHAR = 7; // 8 data bits

SciaRegs.SCICCR.bit.PARITYENA = 0; // No parity

SciaRegs.SCICCR.bit.STOPBITS = 0; // 1 stop bit

// Calculate and set baud rate

uint16_t BRR;

BRR = 37500000 / (9600 * 8) – 1;

SciaRegs.SCIHBAUD = BRR >> 8;

SciaRegs.SCILBAUD = BRR & 0x00FF;

// Enable receiving and transmitting

SciaRegs.SCICTL1.bit.RXENA = 1;

SciaRegs.SCICTL1.bit.TXENA = 1;

// Enable FIFO

SciaRegs.SCIFFTX.bit.TXFIFOENA = 1;

SciaRegs.SCIFFRX.bit.RXFIFOENA = 1;

// Set FIFO interrupt level

SciaRegs.SCIFFTX.bit.TXFFIL = 4;

SciaRegs.SCIFFRX.bit.RXFFIL = 4;

// Exit reset state

SciaRegs.SCICTL1.bit.SWRESET = 1;

}

(2) Data Sending Function

A data sending function can be written to send data through the serial port. Sending can be done using polling or interrupt methods. Below is an example of a sending function using polling:

void SciASendChar(char ch)

{

while (SciaRegs.SCIFFTX.bit.TXFFST == 16); // Wait for an empty position in the transmit FIFO

SciaRegs.SCITXBUF = ch; // Write data to the transmit buffer register

}

void SciASendString(char *str)

{

while (*str)

{

SciASendChar(*str++);

}

}

(3) Data Receiving Function

Similarly, a data receiving function can be written using polling or interrupt methods. For example, using interrupts, the interrupt-related registers need to be configured first, and an interrupt service function needs to be written:

// Receive interrupt service function

interrupt void SciaRxFifoIsr(void)

{

char receivedChar;

while (SciaRegs.SCIFFRX.bit.RXFFST > 0) // Check if there is data in the receive FIFO

{

receivedChar = SciaRegs.SCIRXBUF.all & 0xFF; // Read received data

// Process the received data, e.g., store it in a buffer, etc.

}

SciaRegs.SCIFFRX.bit.RXFFINTCLR = 1; // Clear receive interrupt flag

PieCtrlRegs.PIEACK.all=PIEACK_GROUP9; // Acknowledge PIE interrupt

}

// Configure receive interrupt

void ConfigureSciARxInterrupt(void)

{

EALLOW;

PieCtrlRegs.PIEIER9.bit.INTx1 = 1; // Enable PIE group 9 interrupt 1 (SCIA receive interrupt)

IER |= M_INT9; // Enable CPU interrupt 9

EDIS;

}

4. Experiments

To verify the correctness of the above serial port application technology, the following experiments are conducted.

(1) Hardware Connection

Connect the SCIA serial port of the 28335 development board to the PC where the serial debugging assistant is located via a serial cable, ensuring that TX and RX are cross-connected.

(2) Software Implementation

Create a project in the CCS (Code Composer Studio) development environment, and write the above initialization function, data sending function, data receiving function, etc.

Fundamentals of Programming and Debugging for DSP28335: Serial Port ProgrammingFirst, initialize the system clock, PIE interrupt registers, interrupt vector table, and then initialize the hardware port clocks and IO ports used. Then call the SCI initialization function, set the baud rate to 4800, and call the sending function to send two prompt messages. Finally, enter a while loop, waiting for the reception status to complete, receive the following data, and send it to the PC serial port. The time0 indicator light blinks every 200ms, indicating that the system is running normally. Then enter a while loop, waiting for the reception status to complete, receive the following data, and send it to the PC serial port. The time0 indicator light blinks every 200ms, indicating that the system is running normally.In the receive interrupt service function, the received data is processed (here simply printed to the console).

(3) Test Results

Download the program to the 28335 development board, open the serial debugging assistant, set the baud rate (consistent with the settings in the program, such as 9600), data bits, stop bits, parity bits, and other parameters. Observe the serial debugging assistant, and it should be able to receive the string “Hello, 28335 SCI!” sent by the development board. At the same time, when sending data from the serial debugging assistant, it should also be received correctly.

Fundamentals of Programming and Debugging for DSP28335: Serial Port ProgrammingFundamentals of Programming and Debugging for DSP28335: Serial Port ProgrammingPrevious Recommendations:Building an Efficient and Stable Motor Control DSP Software Framework:Comprehensive Analysis of TMS320F28335’s Three-Level Interrupt Settings and InitializationBasic Experiments on ePWM Configuration of TMS320F28335Most Common 28335 ePWM Configuration Methods for Motor ControlThe Global Craze for the Legendary Chip! How TI C2000 Rewrites Embedded Control History?Unveiling the Bridge Between Analog and Discrete PID Control: Difference EquationsIntelligent Self-Tuning Methods for PID ParametersTrend Curve for Complete Tuning of PID ParametersKey Components of Robots (6) – Stepper MotorsKey Components of Robots (4) – DC Torque MotorsField Effect Transistor Series (9) – Continuation and Drive of H-Bridge CircuitsFundamentals of Programming and Debugging for DSP28335: Serial Port Programming

Leave a Comment