我们通过RS232来做实验。

exynos4412—UART裸板复习-LMLPHP

通过电平转换芯片,exynos4412—UART裸板复习-LMLPHP

连接至核心板:exynos4412—UART裸板复习-LMLPHP

即:GPA0_0  GPA0_1     配置引脚为串口专用模式:

exynos4412—UART裸板复习-LMLPHP

然后看exynos4412—UART裸板复习-LMLPHP

exynos4412—UART裸板复习-LMLPHP

exynos4412—UART裸板复习-LMLPHP

ULCONn  [31:0]       0x3

设置串口一帧传输数据的一帧对应的数据位为8倍,1位停止位,无奇偶校验位

UCONn  [31:0]     0x5

选择串口收发的模式为polling模式

UFCONn  [31:0]  0x0

选择传输的模式为非FIFO模式

UMCONn [31:0] 0x0

禁用硬件流控

UBRDIVn Specifies baud rate divisor
UFRACVALn Specifies divisor fractional value

用于控制波特率

exynos4412—UART裸板复习-LMLPHP

目前采用的时钟源是100Mhz,一会再来验证。

UBRDIVn  =  (100000000 / 115200 / 16 - 1 ) = 53.253472222222222222222222222222   取整数

UFRACVALn = (53.2534722 - 53 )*16 = 4.05555      取整数

即配置为波特率为115200

UTRSTATn
从串口接收一个字节的数据:
exynos4412—UART裸板复习-LMLPHP

读寄存器:

exynos4412—UART裸板复习-LMLPHP

发送一个字节的数据,等待发送缓存寄存器无要发送的数据

exynos4412—UART裸板复习-LMLPHP

写入寄存器:exynos4412—UART裸板复习-LMLPHP

 #ifndef TINY4412_LIB_H_
#define TINY4412_LIB_H_ typedef unsigned int u32;
typedef unsigned short u16;
typedef unsigned char u8; extern u32 read32(u32 reg);
extern u16 read16(u32 reg);
extern u8 read8(u32 reg);
extern void write8(u8 val, u32 reg);
extern void write16(u16 val, u32 reg);
extern void write32(u32 val, u32 reg); #define udelay ((void (*)(int))0x43e26480)
#define printf(...) (((int (*)(const char *, ...))0x43e11a2c)(__VA_ARGS__)) #endif

lib.h

编写uart.c

 #include <uart.h>
#include <stdarg.h> /*串口0的初始化*/
void uart0_init(void)
{
u32 val; /*设置GPA0[0:1]引脚为串口0专用的收发引脚*/
val = read32(GPA0CON);
val &= ~0xff;
val |= 0x22;
write32(val, GPA0CON); /*设置串口传输数据的一帧对应的数据位为
8位,1位停止位,无奇偶校验位*/
write32(0x3, ULCONn); /*选择串口收发的模式为polling模式*/
write32(0x5, UCONn); /*选择传输的模式为非FIFO模式*/
write32(0x0, UFCONn); /*禁用硬件流控*/
write32(0x0, UMCONn); /*设置波特率为115200, 根据手册1399的公式推出*/
write32(, UBRDIVn);
write32(, UFRACVALn); /*时钟源的选择: MPLL_USER_T, MPLL*/
val = read32(CLK_SRC_PERIL0);
val &= ~0xf;
val |= 0x6;
write32(val, CLK_SRC_PERIL0); /*分频*/
val = read32(CLK_DIV_PERIL0);
val &= ~0xf;
val |= 0x7;
write32(val, CLK_DIV_PERIL0);
} void uputchar(int ch)
{
/*等待发送缓存寄存器无要发送的数据*/
while (!(read32(UTRSTATn) & 0x2)) {
;
} write8(ch, UTXHn); if (ch == '\n') {
uputchar('\r');
}
} /*从串口接收一个字节的数据*/
int ugetchar(void)
{
int val; /*等待串口控制器接收到有效数据*/
while (!(read32(UTRSTATn) & 0x1)) {
;
} val = read8(URXHn);
if (val == '\r') {
val = '\n';
} uputchar(val); return val;
} char *ugets(char *buf)
{
int ch; char *tmp = buf; while ((ch = ugetchar()) != '\n') {
*tmp++ = ch;
} *tmp = '\0'; return buf;
} void uputs(const char *buf)
{
while (*buf) {
uputchar(*buf);
buf++;
}
} /*93 --> "5d"*/
void xtoa(int n, char *buf)
{
int i;
if (n < ) {
if (n < ) {
buf[] = '' + n;
} else {
buf[] = n - + 'a';
}
buf[] = '\0'; return;
} xtoa(n/, buf); for (i = ; buf[i] != '\0'; i++); if ((n%) < ) {
buf[i] = (n%) + '';
} else {
buf[i] = (n%) - + 'a';
} buf[i+] = '\0';
} /*93 --> "93" */
void itoa(int n, char *buf)
{
int i; if (n < ) {
buf[] = n + '';
buf[] = '\0';
return;
} itoa(n/, buf); for (i = ; buf[i] != '\0'; i++) {
;
} buf[i] = (n%) + '';
buf[i+] = '\0';
} void uprintf(const char *fmt, ...)
{
int val;
va_list va;
char buf[]; va_start(va, fmt); while (*fmt) {
if (*fmt == '%') {
fmt++;
switch (*fmt) {
case 'c':
uputchar(va_arg(va, int));
break;
case 'd':
val = va_arg(va, int);
if (val < ) {
uputchar('-');
val = - val;
}
itoa(val, buf);
uputs(buf);
break;
case 'x':
val = va_arg(va, int);
xtoa(val, buf);
uputs(buf);
break;
case 's':
uputs(va_arg(va, char *));
break;
default:
break;
}
} else {
uputchar(*fmt);
} fmt++;
}
}

uart.c

测试用例就直接调用uprintf可以测试所有功能。

05-19 23:28