当前位置:首页 > 芯闻号 > 充电吧
[导读]一、串口通讯常识1.串口角色解析2.串口通讯参数串口通讯,分为同步通讯和异步通讯,我们通常使用的都是异步串口。通讯时,双方先约定好数据帧的格式,即波特率,数据位,停止位,奇偶校验位等。波特率:这是一个

一、串口通讯常识
1.串口角色解析

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

波特率:这是一个衡量通信速度的参数。它表示每秒钟传送的bit的个数。例如300波特表示每秒钟发送300个bit。常用的波特率有38400,115200。
起始位:当线路空闲时候,电平为高。一旦检测到一个下降沿,则视为一个起始位。然后接收方按照约定好的格式,接收这一帧数据。
数据位:一帧中实际有效数据的位数。
停止位:表示这帧数据的结束。
校验位:用于检测数据传输是否正确的位。

3.串口硬件引脚
我们通常使用的RS232的9帧串
口,其中最为重要的是2,3,5脚
2 :RXD:接收数据
3 :TXD:发送数据
5 :GND:接地


二、串口驱动程序设计
2.1串口初始化
①引脚设置
②帧格式设置
③工作模式设置
④波特率设置

2.2 导读210串口初始化
void uart_init()
{
    //1.配置引脚用于RX/TX功能
    GPA0CON = 0x22222222;
    GPA1CON = 0X2222;

    //2.设置数据格式等
    UFCON0 = 0X1;
    //无流控
    UMCON0 = 0X0;
    //数据位:0,无校验,停止位:1
    ULCON0 = 0X3;
    //时钟:PCLK,禁止中断,使能UART发送、接收
    UCON0 = 0X5;

    //3. 设置波特率
    UBRDIV0 = UART_UERDIV_VAL;
    UDIVSLOT0 = UART_UDIVSLOT_VAL;
}

//接收一个字符
char getc(void)
{
    //如果RX_FIFO空,等待
    while(!(UTRSTAT0 & (1<<0)));
    //取数据
    return URXH0;
}

//发送一个字符
void getc(char c)
{
    //如果TX_FIFO满,等待
    while(!(UTRSTAT0 & (1<<2)));
    //些数据
    UTXH0 = c;
} 2.3 串口初始化
先看原理图,串口电路中2,3脚是RSTXD0、TSRXD0。对应于底板的原理图,位GPH2、GPH3
              

#define GPHCON *((volatile unsigned long*) 0x56000070)
#define ULCON0 *((volatile unsigned long*) 0x50000000)
#define UCON0 *((volatile unsigned long*) 0x50000004)
#define UBRDIV0 *((volatile unsigned long*) 0x50000028)
#define UTRSTAT0 *((volatile unsigned long*) 0x50000010)
#define UTXH0 *((volatile unsigned long*) 0x50000020)
#define URTH0 *((volatile unsigned long*) 0x50000024)

#define PCLK 50000000
#define BAUD 115200

void uart_init()
{
    //1.配置引脚功能
    GPHCON &= ~(0xf<<4);                                //先清0
    GPHCON |= (0xa<<4);                                 //设置成TX和RX,0b1010

    //2.1设置数据格式
    ULCON0 = 0b11;
    //2.2设置工作模式
    UCON0 = 0b0101;

    //3.设置波特率,这里使用的是PCLK
    UBRDIV0    = (int)(PCLK / (BAUD *16) - 1);
}



void putch(unsigned char ch)
{
    //和210的基本一样
    while(!(UTRSTAT0 & 1<<2));
    UTXH0 = ch;
}

unsigned char getch(void)
{
    unsigned char ret;
    //和210的基本一样
    while(!(UTRSTAT0) & (1<<0));
    ret = URTH0;
    if((ret == 0x0d) ||(ret == 0x0a))
    {
        putch(0x0d);
        putch(0x0a);
    }
    else
        putch(ret);

    return ret;
}
2.4 串口收发
为了测试串口是否可用可以在main.c中增加下列代码。

int gboot_main()
{
    unsigned char buf[2048];

#ifdef MMU_ON
    mmu_init();
#endif

    led_init();
    led_on();

    button_init();
    init_irq();

    uart_init();

    while(1)
    {
        getch();
    }

    return 0;
}
三、串口控制台建立
1、控制台框架搭建
1.1 控制台类型:
①菜单型:串口选择序号
②解析型:判断指令是否是所支持的,来搜索运行。
1.2 菜单型控制台搭建
在main.c函数中打印信息,输出菜单,并判断。
int gboot_main()
{
    int num;

#ifdef MMU_ON
    mmu_init();
#endif

    led_init();
    led_on();     button_init();
    init_irq();     uart_init();

    while(1)
    {         printf("n***************************************nr");
        printf("n*************GBOOT*********************nr");
        printf("1.Download Linux kernel from TFTP Server!nr");
        printf("2.Boot Linux from RAM!nr");
        printf("3.Boot Linux from Nand Flash!nr");
        printf("n Plsase 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!nr");
            break;
        }     }     return 0;
}
2、printf/scanf函数实现
2.1 了解printf和scanf函数
#man 3 printf
int printf(const char *format, ...);                    //...是变参 2.2 实现printf函数、scanf函数
int printf(const char* fmt, ...)
{
    int i;
    va_list args;

    //1.将变参转化为字符串
    va_start(args,fmt);                                //设置args指向fmt(第一个参数)
    vsprintf((char*)outbuf, fmt, args);                //将args存放到outbuf中
    va_end();                                          //结束

    //2.打印字符串到串口
    for(i = 0; i< strlen((char *)outbuf); i++)
    {
        putc(outbuf[i]);
    }
    return i;
}
int scanf(const char *fmt, ...) {
    unsigned char c;     int i = 0;     va_list args;
    //1.获取输入字符串     while(1)     {         c = getc();         if((c == 0x0d) || (c == 0x0a))         {             inbuf[i] = 'n';             break;         }         else         {             inbuf[i] = c;             i++;         }     }     
    //2.格式转换     va_start(args, fmt);     vsscanf((char *)inbuf, fmt, args);     va_end(args);     return i; }
然而报错了:

va_start这些宏需要自己来定义,所以要把内核中的文件集成到gboot中来。通过修改Makefile,使用上提供的代码。
lib目录下的Makefile,最后生成lib.o
objs := div64.o lib1funcs.o ctype.o muldi3.o printf.o string.o vsprintf.o

all : $(objs)
    arm-linux-ld -r -o lib.o $^
    
%.o : %.c
    arm-linux-gcc ${CFLAGS} -c $^
    
%.o : %.S
    arm-linux-gcc ${CFLAGS} -c $^

clean:
    rm -f *.o 修改自己的Makefile文件:
OBJS := start.o main.o dev/dev.o lib/lib.o                                          //这里增加了lib/lib.o

CFLAGS := -fno-builtin -I$(shell pwd)/include                                       //编译时所需的选项,-fno-builtin:去掉内联函数选项 -I$(shell pwd)/include 增加头文件寻找路径
export CFLAGS                                                                       //导出,是的lib下的Makefile也能用CFLAGS
    
all : 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 $(CFLAGS) -c $^
    
lib/lib.o :                                                                          //增加依赖/lib/lib.o
    make -C lib all                                                                  //执行make all在lib目录下,
dev/dev.o :
    make -C dev all
    
.PHONY: clean
clean:
    rm -f gboot.elf gboot.bin *.o
    make -C lib clean
    make -C dev clean
                                 

               

 

                   

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

USB摄像头是一种采用USB接口的视频采集设备,其优点在于即插即用、操作简便,无需额外驱动程序,支持笔记本电脑,并且成本较低,可以支持远程网络观看。

关键字: usb摄像头 驱动程序

与两相双极步进电机的驱动电路相比,两相单极步进电机的驱动电路在输入段配置、内部逻辑及控制电路和驱动电路使用双通道方面基本相同,但是输出段的配置不同。

关键字: 四相步进电机 驱动程序 程序电路

本文介绍了如何实现嵌入式MICREL网卡的驱动程序开发和设计。首先,我们介绍了MICREL网卡的概述和工作原理。然后,详细探讨了驱动程序的开发流程,包括硬件和软件的配置以及驱动程序的编写和测试。最后,总结了几点注意事项和...

关键字: 嵌入式 MICREL网卡 驱动程序

在这篇文章中,小编将对OLED的相关内容和情况加以介绍以帮助大家增进对它的了解程度,和小编一起来阅读以下内容吧。

关键字: OLED 驱动程序 无源驱动

近日,英特尔发布了锐炫显卡的新版驱动更新。本次驱动更新涵盖了锐炫A770、A750、A380以及移动端的锐炫GPU,这使得英特尔锐炫整个家族的DX9性能都实现了显著提升。

关键字: 英特尔 显卡 驱动程序

摘 要:从硬件与软件方面介绍了基于PXI技术的1553B总线通讯模块的设计,并对PXI总线接口设计、驱动程序的开发、 SDRAM存储器的控制和1553B总线通信协议实现等关键技术进行了详细的阐述,为航空领域测控系统开发P...

关键字: PXI技术 驱动程序 SDRAM存储器 1553B总线

PnP全称Plug-and-Play,译文为即插即用。PnP的作用是自动配置低层计算机中的板卡和其他设备,然后告诉对应设备都做了什么。PnP的任务是把物理设备和软件设备驱动程序相配合,并操作设备,在每个设备和它的驱动程序...

关键字: PnP 驱动程序 操作设备

作 者:道哥,10年嵌入式开发老兵,专注于:C/C、嵌入式、Linux。关注下方公众号,回复【书籍】,获取Linux、嵌入式领域经典书籍;回复【PDF】,获取所有原创文章(PDF格式)。目录kill命令和信号使用kill...

关键字: 信号 应用程序 驱动程序

驱动程序本质上是软件代码,主要作用是计算机系统与硬件设备之间完成数据传送的功能,只有借助驱动程序,两者才能通信并完成特定的功能。

关键字: 驱动程序 硬件设备 UNIX

驱动程序(Device Driver)全称为“设备驱动程序”,是一种可以使计算机和设备通信的特殊程序,可以说相当于硬件的接口,操作系统只能通过这个接口,才能控制硬件设备的工作,假如某设备的驱动程序未能正确安装,便不能正常...

关键字: 驱动程序 声卡 设备
关闭
关闭