Using the serial port, we can send and receive the most basic data of the development board, interact with the development board, control the running of the program, and print out some information for debugging during the program running. In fact, the console of the bootloader and kernel (nfs mode) are both implemented through uart. From this we can see that uart is very important in actual development.
1. s3c2410 serial port basics
For detailed specifications of S3C2410A UART, please refer to the s3c2410 datasheet.
1) The default system clock used by the S3c2410 UART is PCLK.
This has to do with calculating the baud rate of the uart.
2) UART functional modules and data transmission process
Each uart consists of a baudrate generator, a transmitter, a receiver and a control unit.
The baud rate generator uses the PCLK (default) or UEXTCLK clock (mainly to achieve higher baud rates, the default PCLK is up to 230.4k bps). The transmitter and receiver each include a 16-byte FIFO and a data shifter. Data is sent and received through the transmit pin (TxDn) and the receive pin (RxDn).
When sending data, the CPU writes the data to be sent into the Transmit Buffer through the internal bus, which means that the programmer writes the data into the Transmit Holding Register (if the FIFO Mode is used, this register is also written, and the hardware will automatically determine it). Then the Transmitter moves the data in the Transmit Buffer into the Transmit Shifter according to the baud rate generated by the Buad-rate Generator, and finally sends it out through the TXDn pin.
When receiving data, the receiving pin (RxDn) receives data through the UART interface module at a certain baud rate, stores it in the Receive Shifter, and then moves it into the Receive Buffer. For programmers, the received data is read through the Receive Holding Register (similar to sending, whether or not FIFO Mode is used, the received data is obtained by reading this register).
Both the Transmit Holding Register and the Receive Holding Register are 8-bit registers, which means they can read and write one byte of data at a time.
3) Calculation of baud rate
The baud rate clock is mainly used to provide the clock signal required for sending and receiving serial port data.
The calculation method is the source clock (PCLK by default) divided by 16 and a 16-bit divisor. The divisor value is stored in the baudrate divisor register (UBRDIVn) and is specified by the user.
Usually we calculate the baud rate by calculating the divisor in reverse according to the desired baud rate, and then write the value into the Divisor Register (UBRDIVn). The formula is as follows:
UBRDIVn = (int) (PCLK/(bps x 16) ) -1
Bps is the baud rate we need to set, such as 115200.
2. s3c2410 serial port experiment
The experimental code is very simple and very suitable for getting started with serial port programming.
The content is: Print a line of information through the serial port to prompt the user to enter a character. If the user enters 'e', the program will exit. If another character is entered, the program will try again.
The following is a detailed analysis: (Part of the content is quoted from "S3C2410 Complete Development Process", and I would like to thank the author for his contribution)
UART has 11x3 registers (3 UARTs). We choose the simplest method to conduct this experiment, and 8 registers are used. However, 5 registers are used for initialization, and the remaining 3 are used to receive and send data. In this way, operating UART is not complicated. This board uses UART0:
1) Initialization:
a. Define the used pins GPH2 and GPH3 as TXD0 and RXD0:
GPHCON |= 0xa0; //GPH2,GPH3 set as TXD0,RXD0
GPHUP = 0x0c; //GPH2, GPH3 internal pull-up
b.ULCON0 (UART channel 0 line control register): set to 0x03
This value means: 8 data bits, 1 stop bit, no parity, normal operation mode.
c.UCON0 (UART channel 0 control register): set to 0x05
Except for bit [3:0], all other bits use the default value. Bit [3:0] = 0b0101 means: both sending and receiving use "interrupt or query mode" - this experiment uses the query mode.
d.UFCON0 (UART channel 0 FIFO control register): set to 0x00
Each UART has a 16-byte transmit FIFO and receive FIFO, but this experiment does not use the FIFO and sets it to the default value of 0.
e.UMCON0 (UART channel 0 Modem control register): set to 0x00
This experiment does not use flow control, set the default value to 0
f.UBRDIV0 (R/W Baud rate divisor register 0): set to 27
UBRDIV0 = 27; //Baud rate is 115200
This experiment uses PLL, PCLK=50MHz, and sets the baud rate to 115200. The formula is:
UBRDIVn = (int) (PCLK / (bps x 16) ) -1
It can be calculated that UBRDIV0 = 27. Please use the error formula on page 314 of the S3C2410 data sheet to check whether this baud rate is within the tolerable error range. If not, you need to change to another baud rate (the 115200 used in this experiment is in compliance). [page]
2) Sending data:
a.UTRSTAT0 (UART channel 0 Tx/Rx status register):
Bit [2]: When there is no data to send, it is automatically set to 1. When we want to use the serial port to send data, we first read this bit to determine whether there is data occupying the sending port.
Bit [1]: Whether the transmit FIFO is empty. This bit is not used in this experiment.
Bit [0]: Whether there is data in the receive buffer. If so, this bit is set to 1. In this experiment, it is necessary to continuously query this bit to determine whether any data has been received.
b.UTXH0 (UART channel 0 transmit buffer register):
Write the data to be sent into this register.
3) Receiving data:
a.UTRSTAT0: As described above, we use [0]
b.URXH0 (UART channel 0 receive buffer register):
When the UTRSTAT0 bit [0] = 1 is queried, read this register to obtain the data received by the serial port.
4) Experimental source code
/* main.c */
#include "uart.h"
#include "clock.h"
#include "watchdog.h"
int Main(void)
{
char key = \' \';
clock_init(); //Initialize the clock
uart_init(); //Initialize the serial port
close_watchdog();
uart_send("uart communication success! ");
while(1)
{
uart_send("If you want to quit ,please pess \'e\' ");
key = uart_get();
if (key == \'e\')
{
uart_send ("you pressed \'e\' and you\'ll quit! ");
break;
}
else
{
uart_send("you pressed ");
uart_send(&key);
uart_send(",retry! ");
}
}
uart_send("the program exited by user! ");
return 0;
}
The following is the source code of the serial port related part:
void uart_init(void)
{
ULCON0 = 0x03; //8N1
UCON0 = 0x005; //Interrupt or query mode
UFCON0 = 0x00; //Do not use FIFO
UMCON0 = 0x00; //Do not use flow control
UBRDIV0 = 27; //Baud rate is 115200
GPHCON |= 0xa0; //GPH2,GPH3 set as TXD0,RXD0
GPHUP = 0x0c; //GPH2, GPH3 internal pull-up
}
void uart_send(char *c)
{
for (; *c != \'\\0\'; c++)
{
while (! (UTRSTAT0 & TXD0READY)); //Continue to query until data can be sent
UTXH0 = *c; //Send data
}
}
unsigned char uart_get(void)
{
while (! (UTRSTAT0 & RXD0READY)); //Continue to query until data is received
return URXH0; //Return received data
Previous article:Seismic acceleration signal processing system based on ARM and DSP
Next article:Design and implementation of motion controller based on ARM+FPGA
Recommended ReadingLatest update time:2024-11-16 15:53
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- Innolux's intelligent steer-by-wire solution makes cars smarter and safer
- 8051 MCU - Parity Check
- How to efficiently balance the sensitivity of tactile sensing interfaces
- What should I do if the servo motor shakes? What causes the servo motor to shake quickly?
- 【Brushless Motor】Analysis of three-phase BLDC motor and sharing of two popular development boards
- Midea Industrial Technology's subsidiaries Clou Electronics and Hekang New Energy jointly appeared at the Munich Battery Energy Storage Exhibition and Solar Energy Exhibition
- Guoxin Sichen | Application of ferroelectric memory PB85RS2MC in power battery management, with a capacity of 2M
- Analysis of common faults of frequency converter
- In a head-on competition with Qualcomm, what kind of cockpit products has Intel come up with?
- Dalian Rongke's all-vanadium liquid flow battery energy storage equipment industrialization project has entered the sprint stage before production
- Allegro MicroSystems Introduces Advanced Magnetic and Inductive Position Sensing Solutions at Electronica 2024
- Car key in the left hand, liveness detection radar in the right hand, UWB is imperative for cars!
- After a decade of rapid development, domestic CIS has entered the market
- Aegis Dagger Battery + Thor EM-i Super Hybrid, Geely New Energy has thrown out two "king bombs"
- A brief discussion on functional safety - fault, error, and failure
- In the smart car 2.0 cycle, these core industry chains are facing major opportunities!
- The United States and Japan are developing new batteries. CATL faces challenges? How should China's new energy battery industry respond?
- Murata launches high-precision 6-axis inertial sensor for automobiles
- Ford patents pre-charge alarm to help save costs and respond to emergencies
- New real-time microcontroller system from Texas Instruments enables smarter processing in automotive and industrial applications
- Reasons why the automatic function of a digital oscilloscope cannot be triggered when measuring low-frequency signals
- Running helloworld-porting on iTOP-4418 development board
- Capacitor selection and installation considerations
- Millimeter wave sensor technology for detecting passengers in moving vehicles
- How to detect whether a POE switch is a single-chip microcomputer
- DSP assembly feels difficult to start
- TMS320C6678 external memory DDR3 hardware design and software debugging
- Questions about using an oscilloscope differential probe to measure the voltage across a resistor and calculate the current
- LPS33HW Waterproof Package Pressure Sensor
- IoT platform architecture design