Chinaunix首页 | 论坛 | 博客
  • 博客访问: 449193
  • 博文数量: 362
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 10
  • 用 户 组: 普通用户
  • 注册时间: 2015-07-26 17:08
文章分类

全部博文(362)

文章存档

2015年(362)

我的朋友

分类: 嵌入式

2015-12-11 11:13:39

 摘自:《嵌入式Linux应用开发完全手册》——韦东山

一、UART原理及UART部件使用方法

1、UART原理

通用异步收发器UART,用来传输串行数据:

        发送数据时,CPU将并行数据写入UART,UART按照一定格式在TxD线上串行发出;

        接收数据时,UART检测到RxD线上的信号,将串行收集放到缓冲区中,CPU即可读取UART获得的这些数据。

UART最精简的连线只有3根电线,TxD用于发送,RxD用于接收,Gnd用于提供参考电平。TxD和RxD数据线以“位”为最小传输单位。

帧由具有完整意义的若干位组成,它包含开始位、数据位、校验位和停止位;发送数据之前,UART之间要约定好数据传输速率(波特率的倒数)、数据的传输格式(多少个数据位、是否使用校验位、奇校验还是偶校验、多少个停止位)。

 

数据传输流程如下:

1)通常数据线处于空闲状态(1状态)

2)当要发送数据时,UART改变TxD数据线的状态(0状态)并维持1位的时间,接收方检测到开始位后,再等待1.5位的时间开始一位一位地检测数据线的状态得到所传输的数据。

3)UART一帧中可能有5-8位的数据,发送方一位一位地改变数据线的状态将它们发出去,首先发送最低位

4)如果使用校验功能,UART发送完数据后,还要发送1个校验位。使用奇校验或者偶校验,即统计数据位连同校验位中,1的总数是奇数还是偶数

5)最后,发送停止位,数据线恢复到空闲状态(1状态),停止位长度有3种,1位、1.5位、2位

 

2、S3C2440 UART的特性

S3C2440的UART有3个独立通道,每个通道可以工作于中断模式或DMA模式,UART由波特率发生器、发送器、接收器、控制逻辑组成。

S3C2440 UART的FIFO深度为64,发送数据时,CPU先将数据写入发送FIFO中,然后UART会自动将FIFO中的数据复制到“发送移位器”中,发送移位器将数据一位一位发送到TxDn数据线上。接收数据时,“接收移位器”将RxDn数据线上的数据一位一位地接收进来,然后复制到接收FIFO中,CPU即可从中读取数据。

3、S3C2440 UART的使用

        对于S3C2440,使用UART之前,需要设置波特率、传输格式(多少个数据位、是否使用校验位、奇校验或偶校验、多少个停止位、是否使用流量控制)、选择所涉及的管脚为UART功能、选择UART通道的工作模式为中断模式或DMA模式。设置好之后,往相关寄存器写入数据即可发送,读取相关寄存器即可接收到数据。通过查询状态寄存器或设置中断来获知数据是否发送完毕、是否接收到数据。

1)UART通道管脚设为UART功能

        UART通道0中,GPH2、GPH3分别用于TxD0、RxD0,使用UART通道0时,先设置GPHCON寄存器将GPH2、GPH3引脚的功能设为TxD0、RxD0。

2)UBRDIVn寄存器:设置波特率

S3C2440 UART的时钟源有两种选择:PCLK、UEXTCLK、FCLK/n,其中n的值通过UCON0-UCON2联合设置

UBRDIVn = (int)(UART clock)/(buad rate × 16)) - 1

3)ULCONn寄存器:设置传输格式

4)UCONn寄存器

        它用于选择UART时钟源、设置UART中断方式

5)UFCONn寄存器、UFSTATn寄存器

        UFCONn寄存器用于设置是否使用FIFO,设置各FIFO的触发阙值,即发送FIFO中有多少个数据时产生中断、接收FIFO中有多少个数据时产生中断。并可以通过设置UFCONn寄存器来复位各个FIFO。

        读取UFSTATn寄存器可以知道各个FIFO是否已经满,其中有多少个数据。

6)UMCONn寄存器、UMSTATn寄存器

这两类寄存器用于流量控制,具体看数据手册

7)UTRSTATn寄存器

它用来表明数据是否已经发送完毕、是否已经接收到数据

8)UERSTATn寄存器

        用来表示各种错误是否发生

9)UTXHn寄存器

CPU将数据写入这个寄存器,UART即会将它保存到缓冲区中,并自动发送出去

10)URXHn寄存器

当UART接收到数据时,CPU读取这个寄存器,即可获得数据。

 

二、UART操作实例

本实例实现,在串口输入一个字符,开发板接收到后,从串口输出。

初始化代码和前一章类似,不在重复,在main函数中调用uart0_init()对串口进行初始化

 

//main.c

#include "serial.h"

int main()
{
    unsigned char c;
    uart0_init();  
// 波特率115200,8N1(8个数据位,无校验位,1个停止位)

    while(1)
    {
        // 从串口接收数据后,判断其是否数字或字母,若是则输出
        c = getc();
        putc(c);
    }

    return 0;
}

 

//serial.c

#include "s3c24xx.h"
#include "serial.h"

#define TXD0READY   (1<<2)
#define RXD0READY   (1)

#define PCLK            50000000    // init.c中的clock_init函数设置PCLK为50MHz
#define UART_CLK        PCLK        //  UART0的时钟源设为PCLK
#define UART_BAUD_RATE  115200      // 波特率
#define UART_BRD        ((UART_CLK  / (UART_BAUD_RATE * 16)) - 1)

/*
 * 初始化UART0
 * 115200,8N1,无流控
 */

void uart0_init(void)
{
    GPHCON  |= 0xa0;    // GPH2,GPH3用作TXD0,RXD0
    GPHUP   = 0x0c;    
// GPH2,GPH3内部上拉

    ULCON0  = 0x03;     // 8N1(8个数据位,无较验,1个停止位)
    UCON0   = 0x05;     // 查询方式,UART时钟源为PCLK
    UFCON0  = 0x00;     // 不使用FIFO
    UMCON0  = 0x00;     // 不使用流控
    UBRDIV0 = UART_BRD; // 波特率为115200
}

/*
 * 发送一个字符
 */

void putc(unsigned char c)
{
    /* 等待,直到发送缓冲区中的数据已经全部发送出去 */
    while (!(UTRSTAT0 & TXD0READY));
    
    /* 向UTXH0寄存器中写入数据,UART即自动将它发送出去 */
    UTXH0 = c;
}

/*
 * 接收字符
 */

unsigned char getc(void)
{
    /* 等待,直到接收缓冲区中的有数据 */
    while (!(UTRSTAT0 & RXD0READY));
    
    /* 直接读取URXH0寄存器,即可获得接收到的数据 */

    return URXH0;
}

 

阅读(821) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~