X210串口配置与stdio移植

串口控制器初始化关键步骤
  (1)初始化串口的Tx和Rx引脚所对应的GPIO(查原理图可知Rx和Rx分别对应GPA0_1和GPA0_0)
  (2)GPA0CON(0xE0200000),bit[3:0] = 0b0010 bit[7:4] = 0b0010
  (3)初始化这几个关键寄存器UCON0 ULCON0 UMCON0 UFCON0 UBRDIV0 UDIVSLOT0
主要的几个寄存器
  (1)ULCON0 = 0x3 // 0校验位、8数据位、1停止位
  (2)UCON = 0x5 // 发送和接收都是polling mode
  (3)UMCON0 = 0x0 // 禁止modem、afc
  (4)UFCON0 = 0x0 // 禁止FIFO模式
  (5)UBRDIV0和UDIVSLOT0和波特率有关,要根据公式去算的

波特率的计算和设置
  (1)第一步,用PCLK_PSYS和目标波特率去计算DIV_VAL: DIV_VAL = (PCLK / (bps x 16)) ?1
  (2)第二步,UBRDIV0寄存器中写入DIV_VAL的整数部分
  (3)第三步,用小数部分*16得到1个个数,查表得uBDIVSLOT0寄存器的设置值

#define GPA0CON        0xE0200000
#define UCON0         0xE2900004
#define ULCON0         0xE2900000
#define UMCON0         0xE290000C
#define UFCON0         0xE2900008
#define UBRDIV0     0xE2900028
#define UDIVSLOT0    0xE290002C

#define UTRSTAT0    0xE2900010
#define UTXH0        0xE2900020    
#define URXH0        0xE2900024    

#define rGPA0CON    (*(volatile unsigned int *)GPA0CON)
#define rUCON0        (*(volatile unsigned int *)UCON0)
#define rULCON0        (*(volatile unsigned int *)ULCON0)
#define rUMCON0        (*(volatile unsigned int *)UMCON0)
#define rUFCON0        (*(volatile unsigned int *)UFCON0)
#define rUBRDIV0    (*(volatile unsigned int *)UBRDIV0)
#define rUDIVSLOT0    (*(volatile unsigned int *)UDIVSLOT0)
#define rUTRSTAT0    (*(volatile unsigned int *)UTRSTAT0)
#define rUTXH0        (*(volatile unsigned int *)UTXH0)
#define rURXH0        (*(volatile unsigned int *)URXH0)
//串口初始化
void uart_init()
{    //初始化rx tx对应GPIO引脚
    rGPA0CON&=~(0xff<<0);//将 bit0~7清零
    rGPA0CON|=0x22;        //设置 _0 _1引脚为RX TX
    //串口相关寄存器
    rULCON0=0x3;
    rUCON0=0x5;
    rUMCON0=0;
    rUFCON0=0;
    //波特率计算相关
    
/*     //9600
    rUBRDIV0=433;
    rUDIVSLOT0=0x2222;
     */
    //用66.7MHZ算  
    //115200
    //66700000/(115200*16)-1
    rUBRDIV0=35;
    // rUBRDIV0余数*16 然后查表
    rUDIVSLOT0=0x0888;
}
//串口发送一字节
void uart_putc(char c)
{    
    while(!(rUTRSTAT0&(1<<1)));//等待发送结束
    rUTXH0=c;
}
char uart_getc()
{
        while(!(rUTRSTAT0&(1<<0)));//等待发送结束
        return rURXH0;
}

2.移植stdio(部分代码展示)

int printf(const char *fmt, ...)
{
    int i;
    int len;
    va_list args;

    va_start(args, fmt);
    len = vsprintf(g_pcOutBuf,fmt,args);
    va_end(args);
    for (i = 0; i < strlen(g_pcOutBuf); i++)
    {
        putc(g_pcOutBuf[i]);
    }
    return len;
}



int scanf(const char * fmt, ...)
{
    int i = 0;
    unsigned char c;
    va_list args;
    
    while(1)
    {
        c = getc();
        putc(c);
        if((c == 0x0d) || (c == 0x0a))
        {
            g_pcInBuf[i] = '';
            break;
        }
        else
        {
            g_pcInBuf[i++] = c;
        }
    }
    
    va_start(args,fmt);
    i = vsscanf(g_pcInBuf,fmt,args);
    va_end(args);

    return i;
}

 Makefile

CC        = arm-linux-gcc
LD         = arm-linux-ld
OBJCOPY    = arm-linux-objcopy
OBJDUMP    = arm-linux-objdump
AR        = arm-linux-ar

INCDIR    := $(shell pwd)
# C预处理器的flag,flag就是编译器可选的选项
CPPFLAGS    := -nostdlib -nostdinc -I$(INCDIR)/include
# C编译器的flag
CFLAGS        := -Wall -O2 -fno-builtin

#导出这些变量到全局,其实就是给子文件夹下面的Makefile使用
export CC LD OBJCOPY OBJDUMP AR CPPFLAGS CFLAGS


objs := start.o led.o clock.o uart.o main.o
objs += lib/libc.a

uart.bin: $(objs)
    $(LD) -Tlink.lds -o uart.elf $^
    $(OBJCOPY) -O binary uart.elf uart.bin
    $(OBJDUMP) -D uart.elf > uart_elf.dis
    gcc mkv210_image.c -o mkx210
    ./mkx210 uart.bin 210.bin

lib/libc.a:
    cd lib;    make;    cd ..
    
%.o : %.S
    $(CC) $(CPPFLAGS) $(CFLAGS) -o $@ $< -c

%.o : %.c
    $(CC) $(CPPFLAGS) $(CFLAGS) -o $@ $< -c

clean:
    rm *.o *.elf *.bin *.dis mkx210 -f
    cd lib; make clean; cd ..

    
    
原文地址:https://www.cnblogs.com/PengfeiSong/p/6352816.html