手册上对S5P4418串口的概述
- UART0 ~ 4,五个串口
- 可编程FIOF
- UART0,1,2支持DMA
- IrDA(红外数据组织)SIR ENDEC
- …
UART配置基本流程
- TX引脚配置为输出模式,RX引脚配置为输入模式
- 配置UART时钟
- 配置波特率,数据位,停止位,校验位等
- 使能
UART0为例,GPIO配置
- TX GPIOD18 AD19 Function1
- RX GPIOD14 AE19 Function1
时钟
- UART时钟要求:
相关寄存器:
UARTCLKENB
时钟生成使能UARTCLKGEN0L
反转输出,PLL选择,分频设置,时钟输出使能
这里使用PLL0来生成UART时钟,PLL0默认是550MHz,分频系数设置(55 - 1),生成的UART时钟为10MHz。
波特率
波特率配置规则
分整数部分BRDI,小数部分BRDF
UARTCLK / (16 * BaudRate) = BRDI + BRDF相关寄存器:
UARTIBRD[15:0] = BRDI
UARTFBRD[5:0] = int(BRDF * 2n + 0.5)
n等于UARTFBRD寄存器位数,即32- 115200的波特率,UARTIBRD[15:0] = int(10MHz / (16 * 115200)) = 5; UARTFBRD[5:0] = int(0.4253472 * 2 * 32 + 0.5) = 27;
数据位,停止位,校验位
UARTLCR_H[6:5] - WLEN
数据位长度UARTLCR_H[4] - FEN
FIFO使能位UARTLCR_H[3] - STP2
停止位,0表示1位,1表示2位停止位UARTLCR_H[1] - PWN
校验位使能
使能
UARTCR[0] - UARTEN
串口总使能UARTCR[8] - TXE
发送使能UARTCR[9] - RXE
接收使能
标志位
UARTFR[3] - BUSY
当窗口正在发送数据时置位TXFF TXFE
发送FIFO满,空RXFF RXFE
接收FIFO满,空- 轮询模式下,通过读取这几位来判断是否有数据要接收,是否能发送数据;
数据寄存器
+ 发送数据时写UARTDR[7:0]
+ 接收数据时读UARTDR[7:0]
代码
// uart.c
/*
* UART0
* TX GPIOD18 AD19 function1
* RX GPIOD14 AE19 function1
*/
#include "../gpio.h"
#include "uart.h"
void uart0_init(int baud){
GPIODALTFN0 &= ~((3 << 28));
GPIODALTFN1 &= ~((3 << 4));
GPIODOUTENB &= ~((1 << 18) | (1 << 14));
GPIODALTFN0 |= ((1 << 28));
GPIODALTFN1 |= ((1 << 4));
GPIODOUTENB |= ((1 << 18));
// 设置UART0时钟
UARTCLKENB |= (1 << 2);
UARTCLKGEN0L &= ~((3 << 2) | (0xFF << 5));
UARTCLKGEN0L |= ((55 - 1) << 5);
// UARTCLKGEN0L |= ((200 - 1) << 5);
// 配置波特率 115200
UARTIBRD &= ~0xFFFF;
UARTIBRD |= 5;
UARTFBRD &= ~0x3F;
UARTFBRD |= 27;
// 8N1
UARTLCR_H &= ~((3 << 5) | (0x1F << 0));
UARTLCR_H |= ((3 << 5));
// UART TX RX使能
UARTCR |= ((1 << 0) | (1 << 8) | (1 << 9));
}
char getc(){
// if((UARTFR >> 6) & 1){
// rec = UARTDR & 0xFF;
// }
while((UARTFR & (1 << 6)) == 0);
return UARTDR;
}
void putc(char c){
while(UARTFR & (1 << 3));
UARTDR = c;
}
//main.c
while(1){
ch = getc();
if(ch == '\n'){
putc('\r');
}
putc(ch);
}
时钟问题:
PLLSETREG0 0x100D1302 -> PMS = 3 275 2 = 550MHz