ARM: UART serial asynchronous communication driver programming

Publisher:独享留白1028Latest update time:2017-09-21 Source: eefocusKeywords:ARM Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

1. Basic concepts of serial ports
1.1 UART - Universal Asynchronous Receiver/Transmitter
Serial/Parallel (after-class supplement)
Asynchronous/Synchronous: 'The difference between asynchronous/synchronous communication' (supplement)
'Simple/Half-Duplex/Full-Duplex:
Simplex: Data can only be transmitted in one direction at any time
Half-Duplex: Data can be transmitted in two directions, and can only be transmitted in the same direction at any time
Full-Duplex: Data can be transmitted in two directions at the same time
1.2 Serial Port Communication Standard
RS232 (Electronic Industry Agreement EIA) - Currently the most commonly used 'serial interface standard'
specifies 'electrical characteristics':
logic 0, +3 v ~ +15 v, SPACE
logic 1, -3 v ~ -15 v, MARK
specifies 'mechanical characteristics':
transmission distance < 10 m
TTL level, computer internal level (CPU):
logic 0, low level < 0.8 v
logic 1, high level > 2.4 v
Important parameters of serial asynchronous communication:
>> Number of data bits: 5 ~ 8 bit (the development board end is set to 8 bit / frame data)
>> Verification method: odd check, even check, no check
>> Stop bit width: 1~2bit
>> Communication rate: bps (bit per second - bit per second) 'Baud rate unit'

2. Circuit schematic
[base board]
             |---SP3232E level conversion chip---|
PC_TXD1 ---> T2OUT ---> T2IN ---> UARTTXD0 ---> 'GPIOD18
PC_RXD1 ---> R2IN ---> R2OUT ---> UARTRXD0 ---> 'GPIOD14
There are two ways to complete serial communication:
1) One way: The program running on the arm core directly operates the GPIO pins like the LED to form the timing of serial asynchronous data transmission and reception.
2) Another way: The S5P6818 integrates a uart controller, and the method 1) The process of pure software to realize communication can use a combination of software and hardware to realize the communication timing, thereby simplifying software programming.

Question:
What tasks can the UART controller complete, what tasks does the software need to do, and how do the two work together?
Answer: The relevant chapter about UART in the CPU datasheet

3. CPU datasheet
3.1 Pin function selection
---> P 71 - 2.3
GPIOD18 - Function1
GPIOD14 - Function1
---> P 757 - 16.5.1.8
GPIODALTFN0 - 0xc001d020 - [29:28] - 01=ALT Function1
GPIODALTFN1 - 0xc001d020 - [ 5 : 4 ] - 01=ALT Function1
3.2 UART controller
---> P 960 - 25.1
' S5P6818 serial asynchronous receiver and transmitter UART unit features:
1) Provides 6 independent UART controllers
2) Data transmission can use polling, interrupt, and DMA methods
3) The maximum transmission rate is 4 Mbps when using the system clock // A higher rate can be achieved when using an external clock
4) Each UART channel has two 64 bytes FIFO is used to send and receive data to provide higher efficiency5
) Programmable baud rate, infrared sending and receiving, 1~2 stop bits, 5~8 bit data width, parity checkQuestion

:
Which uart controller inside the CPU does COM1 correspond to?
Answer:
According to the fact that COM1 uses GPIOD14 and GPIOD18 on the CPU, it is inferred that it corresponds to 'UART0' inside the CPU.

Knowledge point:
'There are usually three ways for the CPU to perceive changes in external hardware:
1> Polling; 
// Regularly ask various devices in turn whether there are any processing requirements, process them if there are any requirements, and return to the CPU's daily work after processing. - Suitable for situations where hardware changes frequently2
> Interrupt; 
// When there is a hardware device processing requirement, the CPU starts the input and output device to archive and prepare data, the I/O completes the interrupt signal, receives the interrupt processing data, and then continues to work at a certain time. - Suitable for situations where hardware changes are not particularly frequent3
> DMA;
// Direct memory access, direct memory access, data is directly transferred in blocks between memory and I/O devices.

'【Important parameters of UART controller】
non-FIFO - 115200 - 8 - None - 1 - Polling mode

ULCON0 - 0xc00a1000 - R/W
- [ 1 : 0 ] - 11 , 8 bit - Data width word lenth
- [ 2 ] - 0 , 1 bit - Stop bit number of stop bit
- [ 5 : 3 ] - 000 - No check
- [ 6 ] - 0 - Infrared normal mode

UCON0 - 0xc00a1004 - R/W
- [ 1 : 0 ] - 01 - Polling receive Receive Mode (Polling mode)
- [ 3 :2 ] - 01 - Transmit Mode (Polling mode)
- [ 5 ] - 01 - Setting Loop-back mode

UFCON0 - 0xc00a1008 - R/W
- [ 0 ] - 0 - Disable FIFO (non-FIFO) FIFO Disables

UTRSTAT0 - 0xc00a1010 - R
- [ 0 ] - 1 - Buffer has a received data
- [ 1 ] - 0 / 1 - 0 represents transmit buffer is not empty, 1 represents empty

UTXH0 - 0xc00a1020 - W
- [ 7 : 0 ] - Write the data to be sent Transmit Data for UART0

URXH0 - 0xc00a1024 - R
- [ 7 : 0 ] - Read the received data Receive Data for UART0

---> P 313 - 5.3.2.1.13 UARTCLKENB - 'Clock source configuration, address number corresponds to UARTUARTCLKENB
- 0xc00a9000 - R/W
- [ 2 ] - 1 - Enable UART0 clock Enable

 UARTCLKGEN0L - 0xc00a9004 - R/W
- [ 4 : 2 ] - 1 - Clock source frequency selection PLL[1]==800MHz (adjust to this frequency in uboot)
- [12: 5 ] - 1111 1111 - Frequency division coefficient, providing UART0 clock signal 50 MHz
// 1M==1 million, 800M==800 million, 1111==0x0f, 800MHz(0x0f+1)=50MHz

--->P 986 - 25.4.1.11/25.4.1.12 - 'Used for frequency division, divide the input 50MHz into a clock signal suitable for sending 115200 bits per second
UBRDIV0 - 0xc00a1028 - R/W - The calculated value is 26
UFRACVAL0 - 0xc00a102c - R/W - The calculated value is 2

---> P 969 - For example // Setting method example


  1. /* The calculation method is specified in the manual. No need to ask why. Just apply the formula. 

  2. DIV_VAL = (40000000/(115200 x 16))  –  1 

  3. = 21.7 – 1 

  4. = 20.7 

  5. UBRDIVn = 20 (integer part of DIV_VAL) 

  6. UFRACVALn/16 = 0.7  

  7. So, UFRACVALn = 11 

  8. */  

50000000 / (115200 * 16) - 1 = 27.13 - 1 = 26.13 = 26 【==UBRDIV0】
0.13 * 16 = 2.08 = 2 【==UFRACVAL0】

【Summary】S5P6818UART related registers
1) UART line controller ULCONn - set data format
2) UART mode control register UCONn - used to select clock source, send/receive data optional polling
3) UART FIFO control register UFCONn
4) UART MODEM control register UMCONn
5) Transmit register UTXH, receive register URXH
6) Baud rate division register UBRDIV, UFRACVAL
7) GPIO related registers
8) Interrupt related registers
9) Clock, power control register


4. Encoding


  1. /** Code Demonstration - main.c **/  

  2. #include "uart.h"  

  3. void main (void) {  

  4.     // 8N1 115200 non-FIFO polling  

  5.     uart_init ( );  

  6.     while (1) {  

  7.         uart_puts ("\n hello,world!");  

  8.     }     

  9. }  


  1. /** Code demonstration - uart.c **/  

  2. #define UART0CLKENB     *((volatile unsigned int*)0xc00a9000)  

  3. #define UART0CLKGEN0L   *((volatile unsigned int*)0xc00a9004)  

  4.   

  5. #define GPIOD_ALTFN0    *((volatile unsigned int*)0xc001d020)  

  6. #define GPIOD_ALTFN1    *((volatile unsigned int*)0xc001d024)  

  7. #define GPIOD_PULLENB   *((volatile unsigned int*)0xc001d060)  

  8.   

  9. #define ULCON0          *((volatile unsigned int*)0xc00a1000)  

  10. #define UCON0           *((volatile unsigned int*)0xc00a1004)  

  11. #define UFCON0          *((volatile unsigned int*)0xc00a1008)  

  12. #define UTRSTAT0        *((volatile unsigned int*)0xc00a1010)  

  13. #define UTXH0           *((volatile unsigned int*)0xc00a1020)  

  14. #define URXH0           *((volatile unsigned int*)0xc00a1024)  

  15. #define UBRDIV0         *((volatile unsigned int*)0xc00a1028)  

  16. #define UFRACVAL0       *((volatile unsigned int*)0xc00a102c)  

  17. void uart_init (void) {  

  18.     /* uart0 clk disable */  

  19.     UART0CLKENB &= ~(1 << 2);  

  20.     // GPIOD18 (Tx receiving pin) GPIOD14 (Rx sending pin) configure function Function1  

  21.     GPIOD_ALTFN0 &= ~(3 << 28); // GPIOD14  

  22.     GPIOD_ALTFN0 |= (1 << 28);  

  23.     GPIOD_ALTFN1 &= ~(3 << 4); // GPIOD18  

  24.     GPIOD_ALTFN1 |= (1 << 4);  

  25.     // Clock configuration: select PLL[1] 800MHz  

  26.     UART0CLKGEN0L &= ~(7 << 2);  

  27.     UART0CLKGEN0L |= (1 << 2);  

  28.     // Frequency division setting 800/(0x0f+1)=50MHz  

  29.     UART0CLKGEN0L &= ~(0xff << 5); // [12:5] 8 bits  

  30.     UART0CLKGEN0L |= (0xf << 5); // [12:5] 4 bits are set to 1111  

  31.     // UART controller settings  

  32.     ULCON0 = 0x03; // 8N1  

  33.     UCON0   = 0x05; // 0101 == 0x05 polling  

  34.     UFCON0 &= ~(1 << 0); // non-FIFO disable  

  35.     OFFENSIVE0 = 26; // 50000000/(115200*16) - 1 == 26.13  

  36.     UFRACVAL0 = 2; // 0.13*16 == 2.08  

  37.     /* uart0 clk enable */  

  38.     UART0CLKENB |= (1 << 2);  

  39. }  

  40. void uart_putc (char c) {  

  41.     // UTRSTAT0 bit[1] == 1, the cache register is empty  

  42.     // Poll if it is empty  

  43.     while (! (UTRSTAT0 & 0x02)); // !(empty) does nothing.  

  44.     UTXH0 = c;  

  45.     if (c == '\n')  

  46.         uart_putc ('\r');  

  47. }  

  48. void uart_puts (char* str) {  

  49.     if (! str)  

  50.         return ;  

  51.   

  52.     while (*str) {  

  53.         uart_putc (*str);  

  54.         str++;  

  55.     }  

  56. }  


  1. /** Code Demonstration - uart.h **/  

  2. #ifndef _UART_H_  

  3. #define _UART_H_  

  4.   

  5. extern void uart_init (void);  

  6. extern void uart_puts (char*);  

  7.   

  8. #endif //_UART_H_  

5. Compile

$:' arm-cortex_a9-linux-gnueabi-gcc -c -nostdlib main.c -o main.o
$:' arm-cortex_a9-linux-gnueabi-gcc -c -nostdlib uart.c -o uart.o
$:' arm-cortex_a9-linux-gnueabi-ld -nostdlib -nostartfiles -Ttext=48000000 -emain main.o uart.o -o uart      // 注意.o文件顺序
$:' arm-cortex_a9-linux-gnueabi-objcopy -O binary uart uart.bin
6. 运行
$:' sudo cp uart.bin /tftpboot/
X6818#:' tftp 48000000 uart.bin
X6818#:' go 48000000


Keywords:ARM Reference address:ARM: UART serial asynchronous communication driver programming

Previous article:STM32: Keil MDK (uVision v4.10) development environment construction
Next article:STM32 Experience (I)

Latest Microcontroller Articles
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号