(本节笔记的具体实验代码,在这里:https://github.com/elvinsys/arm_tq2440/tree/master/1_uboot/1-14.serial)

一、  基本概念

1.  作用:作为数据传输的途径,或者作为控制台来提供用户对设备的控制方式

2.  通讯格式的几个概念

2.1  波特率:每秒传输bit的个数,常用的波特率有38400/115200

2.2  常用的参数:

起始位:当线路空闲时,电平为高,一旦检测到一个下降沿,则视为一个起始位

数据位:一帧中实际有效的数据的位数

校验位:用于检测数据传输的正确性

停止位:表示这帧数据的结束

3.  引脚:

RS232——9针引脚串口

2 : RXD : 接收脚

3 : TXD  : 发送脚

5 : GND : 接地脚

二、  串口驱动程序设计

1.  串口初始化——    void uart_init()

(先touch uart.c,把uart.o加入到Makefile中)

查看底板原理图和核心板原理图可得知:

TXD0 : TXD0 / GPH2

RXD0: RXD0 / GPH3

1.1  配置引脚功能:GPHCON  0x5600 0070

GPH2    [5:4]    10    :    TXD[0]

GPH3    [7:6]    10    :    RXD[0]

1.2  设置串口数据格式:ULCON0  0x5000 0000

Word Length [1:0] 11 设定为8bit
Number of stop [2] 0 one stop bit 1位停止位
Parity Mode [5:3] 0XX No Parity 无校验

1.3  设置串口工作模式:UCON0  0x5000 0004

(若在操作系统的支持下,可选择使用中断或DMA模式,但在bootloader中,一般采用轮询的工作模式)

Receive Mode [3:2] 01 polling mode
Transmit Mode [1:0] 01 polling mode

1.4  设置UART波特率(UART BAUD RATE DIVISOR REGISTER)

公式是:UBRDIVn = (int)(UART clock / (buad rate x 16) -1)

UBRDIV0  R/W  0x5000 0028

UART clock = PCLK = 50MHZ

(#define PCLK 500 0000)

(#define BAUD 115200)

UBRDIV0 = (int)(PCLK / (BAUD X 16)-1);

2.  发送数据——void putc (unsigned char ch)

2.1  检查UTRSTAT0  R  0x5000 0010

Transmitter empty [2] 0 Not empty  等待
同上 同上 1 empty  发送

2.2  发送到UTXH0  W  0x5000 0020                 (UART TRANSMIT BUFFER REGISTER)

UTXH0 = ch;

3.  接收数据——unsigned char getc(void)

3.1  检查UTRSTAT0  R  0x5000 0010

Receive buffer data ready [0] 0 Empty   等待
    1 has data  接收

3.2  从URXH0  R  0x5000 0024    (UART RECEIVE BUFF REGISTER)

return URXH0;

4.  把uart_init()加入到main.c中,并加入如下代码进行测试:

/*  加入回车换行符的ASCII码  */

putc(0x0d);

putc(0x0a);
        /*  加入输出一个大写字母“H”  */

putc('H');

5.  添加控制台回显功能

5.1  在main.c中删除以上三行测试代码,在while(1)中加入getc(),让程序不断检测自PC断输入的字符。

5.2  修改usrt.c中的接受收据的函数,代码如下:

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;
}

6.  发送一个字符串的函数,在uart.c中加入如下代码:

void uart_send_string(char * str)

{

while(*str)

{

putc(&str++);

}

putc(0x0d);

putc(0x0a);

}

7.  整个uart.c的实验代码如下:

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

#define PCLK 50000000
#define BUAD 115200

void uart_init(void)    /*  初始化串口  */
{
//配置GPIO口,查表得TXD0=GPH2,RXD0=GPH3
    GPHCON &= ~((0x3<<4)|(0x3<<6));
    GPHCON |= ((0x2<<4)|(0x2<<6));

//配置ULCON0
    ULCON0 = 0x03;

//配置UCON0
    UCON0 = 0x09;   /*  这里必须设置为0x09,也就是0b1001,否则后面DMA实验会出错  */

//设置波特率
    UBRDIV0 = (int)(PCLK/(BUAD*16)-1);
}

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;
}

void uart_send_string(char * str)  /*  发送一个字符串用作测试  */

{

while(*str)

{

putc(&str++);

}

putc(0x0d);

putc(0x0a);

}

三、  建立S3C2440开发板基于串口的控制台

1.  大建控制台框架,在main.c中加入如下while(1)代码:

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

scanf("%d", &num);

switch (num)
{
case 1:
printf("selected 1 !\n\r");
break;
case 2:
printf("selected 2 !\n\r");
break;
case 3:
printf("selected 3 !\n\r");
break;
default:
printf("Error : This is a wrong slection !\n\r");
break;
}
}

2.  printf / scanf 函数的移植和实现

2.1  touch printf.c ,并把printf.o丢到Makefile里

2.1.1  unsigned char outbuf[1024];

2.1.2  man 3 printf,函数原型为 int printf(const char * fmt, ...),讲变参转化为字符串,

va_list args;                                          /*  变参列表  */

va_start(args, fmt);                              /*  把原型中的fmt格式传递给变量列表  */

vsprint( (char *)outbuf, fmt, args );    /*  把变参转化字符串放进outbuf中  */

va_end();

2.1.3  打印字符串到串口

for ( i = 0; i < strlen( (char *) outbuf); i++)

{

putc(outbuf[i]);

}

return i;

2.2  然而,va_start, vsprintf, va_end 在gboot并木有定义,必须先从Lib中移植

2.2.1  修改顶层Makefile

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

2.2.2  编译后,出现错误,ctype.c 符号没定义,分析其原因为:ctype.h 没被预编译时包含,arm-linux-gcc路径应包含本地include文件夹,于是在顶层Makefile中添加如下代码:

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

编译后,报错,va_list'没声明,解决方法为,在printf.c中添加:#include “vsprintf.h”

编译后,报错,main.c中的“puts”没定义,原因为,出现了内联函数(inline funtion),解决办法未,修改顶层Makefile中的CFLAGS

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

......

%.o : %.c
arm-linux-gcc $(CFLAGS) -c $^

2.3  移植scanf

2.3.1  unsigned char inbuf[1024];

2.3.2  man 3 scanf, 原型为:int scanf (const char * fmt, ....);

2.3.3  在printf.c中加入如下代码:

int scanf(const char *fmt, ...)
{
int i = 0;
unsigned char ch;
va_list args;
while(1)
{    /*  获取输入的字符串  */
ch = getc();
if((ch==0x0d) || (ch==0x0a))
{
putc('\n');
break;
}
else
{
inbuf[i++] = ch;
}
} /*  格式转换  */

va_start(args, fmt);
vsscanf((char *)inbuf, fmt, args);  /*  此处和vsprintf不大一样  */
va_end();
return i;
}

3.  程序代码结构优化

3.1  建立dev文件夹,把button.c    interrupt.c    led.c    mmu.c    uart.c  等文件丢进去

3.2  在dev中,复制lib中的makefile进行修改

objs := mmu.o led.o button.o interrupt.o nandflash.o uart.o dma.o

3.3  xiugai dingceng Makefile

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

1-14 串口在S3C2440上的原理、配置与驱动实现相关推荐

  1. SPI在linux3.14.78 FS_S5PC100(Cortex A8)和S3C2440上驱动移植(deep dive)

    由于工作的原因,对SPI的理解最为深刻,也和SPI最有感情了,之前工作都是基于OSEK操作系统上进行实现,也在US/OS3上实现过SPI驱动的实现和测试,但是都是基于基本的寄存器操作,没有一个系统软件 ...

  2. SPI在linux3.14.78 FS_S5PC100(Cortex A8)和S3C2440上驱动移植(deep dive)_0

    由于工作的原因,对SPI的理解最为深刻,也和SPI最有感情了,之前工作都是基于OSEK操作系统上进行实现,也在US/OS3上实现过SPI驱动的实现和测试,但是都是基于基本的寄存器操作,没有一个系统软件 ...

  3. S3C2440上LCD驱动 (FrameBuffer)实例开发讲解

    1.S3C2440上LCD驱动 (FrameBuffer)实例开发讲解 其中的代码也可直接参考:drivers/video/s3c2410fb.c 以下为转载文章,文章原地址:http://blog. ...

  4. 转:S3C2440上LCD驱动(FrameBuffer)实例开发详解

    1.S3C2440上LCD驱动 (FrameBuffer)实例开发讲解 其中的代码也可直接参考:drivers/video/s3c2410fb.c 以下为转载文章,文章原地址:http://blog. ...

  5. cubemx stm32 陶晶驰 串口屏 基于YXY通信原理的串口屏驱动代码

    陶晶驰串口屏 资料 陶晶驰串口屏是本质是一个MCU,屏幕是MCU的模块,一般是一块TFT屏幕.在串口屏厂商提供的软件上面编写界面,然后通过串口直接烧到串口屏的MCU上,然后在屏幕上展示出来. 串口屏资 ...

  6. sever串口wifi拓展板_串口Wifi模块的工作原理和详细功能介绍

    在无线网络领域里面,无线wifi是最火的名词.对于串口wifi模块的工作原理是什么呢?串口wifi模块又有什么功能呢?wifi方案设计远嘉科技给大家讲解有关串口wifi模块的工作原理,以及详细功能介绍 ...

  7. S3C2440上MMC/SD卡驱动分析(二)

    下面的文章主要是转载的,先记录下自己的经验. MMC/SD驱动有两种模式:FIFO和DMA.在代码中两种方式都予以了实现,在make menuconfig时候,可以选择是使用fifo方式还是DMA方式 ...

  8. STM32串口接收不定长数据原理与源程序

    **STM32串口接收不定长数据原理与源程序**CSDN上有很多关于STM32串口接收不定长数据的文章,但实际使用后发现照搬他们的代码,程序根本就不能正确接收数据,其中最关键的一句有问题.其余内容完全 ...

  9. 在Ubuntu 14.04.5 64bit上安装git GUI客户端GitKraken

    git的图像化管理工具很多,有两个是比较推荐用的,sourceTree以及GitKraken.个人比较喜欢GitKraken.下面是我在Ubuntu 14.04.5 64bit上的安装过程. 从官网下 ...

最新文章

  1. 2020年人工神经网络第二次作业-参考答案第六题
  2. html隐藏二级导航的制作代码,HTML+CSS实现二级导航
  3. 梦幻西游物价稳定的服务器,梦幻西游:三界功绩对服务器点卡比例的影响,鬼区比例比火区高...
  4. 关于PHP页面显示乱码问题的解决
  5. 更改mysql数据库存储引擎_MySQL更改数据库表的存储引擎
  6. 21世纪IT人才需要具有的5个鲜明特点
  7. windows下载和安装gcc编译器(MinGW)及其环境配置(C语言编译环境配置)
  8. Linux运维04:vmstat命令详解
  9. 百度网盘破解版Pandownload开发者被抓
  10. 安卓手机屏幕投射电脑能同步声音
  11. multiprocessing.Pool(pool.map pool.apply pool.apply_async poo.map_async)
  12. ST-LINKV2仿真器接线、配置、仿真方法
  13. 服务器固态硬盘连接,技术支招:服务器中固态硬盘如何选?
  14. windows服务器ssl证书安装及配置
  15. 天正自定义填充图案怎么添加_天正填充图案 图层管理 文件
  16. Android应用全屏显示
  17. 如何设置windows防火墙的出入规则
  18. 谁偷走了小男孩的初吻?
  19. AI视频插帧 附带『视频插帧』工具
  20. Photoshop中如何把多张图片快速变为PDF文档

热门文章

  1. 20190221 beautiful soup 入门
  2. Android CompressImage图片压缩工具类介绍
  3. 【网络通信协议】OSI七层模型
  4. WiFi、WiMAX、WBMA与3G的比较
  5. 长尾分布之DECOUPLING REPRESENTATION AND CLASSIFIER FOR LONG-TAILED RECOGNITION
  6. 您的企业已经准备好使用专线了吗?——Vecloud
  7. OM | 运筹学在医疗运营管理中的应用
  8. 这个村子并不富裕,每个人都年复一年,日复一日地在田里劳作
  9. win8系统下载 mysql 64位 win8_win8系统64位iso镜像
  10. css中英文自动换行问题