欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

串口 来做 控制台

程序员文章站 2022-07-13 13:34:54
...

串口通讯常识

串口通常扮演着数据传输和搭建控制台的作用。

串口通讯,分为同步通讯异步通讯,我们通常使用的都是异步串口。通讯时,双方先约定好数据帧的格式,即波特率,数据位,停止位,奇偶校验位等。

这里介绍的是 通用异步收发传输器UART (Universal Asynchronous Receiver / Transmitter)

波特率:这是一个衡量通信速度的参数。它表示每秒钟传送的bit的个数。例如300波特表示每秒钟发送300个bit。常用的波特率有38400,115200。

起始位:当线路空闲时候,电平为高。一旦检测到一个下降沿,则视为一个起始位。然后接收方按照约定好的格式,接收这一帧数据。
数据位:一帧中实际有效数据的位数。
停止位:表示这帧数据的结束。
校验位:用于检测数据传输是否正确的位。

硬件引脚:
串口 来做 控制台
上图是我们通常使用的RS232的9帧串口,其中最为重要的是2,3,5三个引脚:
2脚 :RXD:接收数据
3脚 :TXD:发送数据
5 脚:GND:接地

串口程序设计

串口需要初始化:
串口 来做 控制台

代码举例:

#define GPACON     (*((volatile unsigned short *)0x7F008000))
#define ULCON0     (*((volatile unsigned long  *)0x7F005000))
#define UCON0      (*((volatile unsigned long  *)0x7F005004))
#define UTRSTAT0   (*((volatile unsigned long  *)0x7F005010))
#define UBRDIV0    (*((volatile unsigned short *)0x7F005028))
#define UTXH0      (*((volatile unsigned char  *)0x7F005020))
#define URXH0      (*((volatile unsigned char  *)0x7F005024))
#define UDIVSLOT0  (*((volatile unsigned short *)0x7F00502C))

#define PCLK 66500000
#define BAUD 115200

void uart_init()
{
    //1.配置引脚功能
    GPACON &= ~0xff;
    GPACON |= 0x22;

    //2. 设置数据格式
    ULCON0 = 0b11;

    //3. 设置工作模式
    UCON0 = 0b0101; 

    //4. 设置波特率  
    UBRDIV0 =(int)(PCLK/(BAUD*16)-1);  //UBRDIV0保存该公式计算后的整数部分
    UDIVSLOT0 = 0x0;   //UDISLOT0=保存该公式计算后的小数部分*16
}

void putc(unsigned char ch) //发送数据
{
    while (!(UTRSTAT0 & (1<<2)));//检测寄存器
    UTXH0 = ch;  
}

unsigned char getc(void) //接收数据
{
    unsigned char ret;
    while (!(UTRSTAT0 & (1<<0)));
    // 取数据
    ret = URXH0;

    if ((ret == 0x0d) || (ret == 0x0a)) //回显 回车和换行
    {
        putc(0x0d);
        putc(0x0a); 
    }       
    else
        putc(ret);

    return ret;
}

搭建控制台

本处采用的是菜单型控制台。
控制台C语言:

    while(1){
        printf("\n\r***************************************\n\r");
        printf("\n\r*****************GBOOT*****************\n\r");
        printf("1:Download Linux Kernel from TFTP Server!\n\r");
        printf("2:Boot Linux from RAM!\n\r");
        printf("3:Boor Linux from Nand Flash!\n\r");
        printf("\n Plese Select:");

        scanf("%d",&num);

        switch (num)
        {
            case 1:
                //tftp_load();
                break;

            case 2:
                //boot_linux_ram();
                break;

            case 3:
                //boot_linux_nand();
                break;

            default:
                printf("Error: wrong selection!\n\r");
                break;      
        }
    } 

两个makefile文件:
1、
子文件的makefile,包含部分c文件

objs := button.o interrupt.o lightLED.o mmu_init.o nand.o uart.o

all : $(objs)
    arm-linux-ld -r -o dev.o $^

%.o : %.c
    arm-linux-gcc ${CFLAGS} -c $^

%.o : %.S
    arm-linux-gcc ${CFLAGS} -c $^

clean:
    rm -f *.bak *.elf *.bin *.o 

2、
附加了库函数,将部分c文件存在文件夹中

OBJS := start.o main.o mem_init.o dev/dev.o lib/lib.o 

CFLAGS := -fno-builtin -I$(shell pwd)/include
export CFLAGS

gboot.bin : gboot.elf
    arm-linux-objcopy -O binary gboot.elf gboot.bin

gboot.elf : $(OBJS)
    arm-linux-ld -Tgboot.lds -o gboot.elf $^

%.o : %.S
    arm-linux-gcc -g -c $^

%.o : %.c
    arm-linux-gcc -g -fno-builtin -c $^

lib/lib.o :
    make -C lib all

dev/dev.o :
    make -C dev all 

.PHONY: clean
clean:
    rm -f *.bak *.elf *.bin *.o
    make -C lib clean
    make -C dev clean