串行通信接口

2018-08-06补充(百度百科):

异步通信是一种很常用的通信方式。相对于同步通信,异步通信在发送字符时,所发送的字符之间的时隙可以是任意的,当然,接收端必须时刻做好接收的准备(如果接收端主机的电源都没有加上,那么发送端发送字符就没有意义,因为接收端根本无法接收)。发送端可以在任意时刻开始发送字符,因此必须在每一个字符的开始和结束的地方加上标志,即加上开始位和停止位,以便使接收端能够正确地将每一个字符接收下来。

异步通信的好处是通信设备简单、便宜,缺点信道利用率较低(因为开始位和停止位的开销所占比例较大),但随着光网络的发展,这些已不是根本问题。

一、异步串行方式的数据格式

由于UART是串行异步通信方式,因此在UART通信过程中每次只能传输1位(bit),若干位组成一个数据帧(frame),帧是UART通信中最基本单元,它主要包含:开始位,数据位,校验位(如果开启了数据校验,要包含校验位),和停止位,帧结构如下图所示。

 串行通信接口

 

开发者要通过寄存器的设置,来指定帧的格式,帧的封装最终还是由硬件自动完成。

UART在通信之前要在发送端和接收端约定好帧结构,也就是约定好传输数据帧格式。

l  开始位:必须包含在数据帧中,表示一个帧的开始。

l  数据位:可选5,6,7,8位,该位长度可由编程人员指定。

l  校验位:如果在开启了数据校验时,该位必须指定。

l  停止位:可选1,2位,该位长度可由编程人员指定。

通信双方约定好帧格式后,指定同一波特率,以保证双方数据传输的同步。波特率是指单位时间传输二进制数据的位数,其单位为比特每秒(bps或bit/s),表示美秒传多少位。

 

二、Exynos4412异步串行通信

1. 控制器框架如下图所示:

串行通信接口

(1)数据发送

发送的数据帧可编程的,它的一个帧长度是用户指定的,它包括一个开始位,5~8个数据位,一个可选的奇偶校验位和1~2个停止位,数据帧格式可以通过设置ULCONn寄存器来设置。发送器也可以产生一个终止信号,它是由一个全部为0的数据帧组成。在当前发送数据被完全传输完以后,该模块发送一个终止信号。在终止信号发送后,它可以继续通过FIFO(FIFO)或发送保持寄存器(NON-FIFO)发送数据。

(2)数据接收

同样接收端的数据也是可编程的,接收器可以侦测到溢出错误奇偶校验错误,帧错误和终止条件,每个错误都可以设置一个错误标志。

l  溢出错误是指在旧数据被读取到之前,新数据覆盖了旧数据

l  奇偶校验错误是指接收器侦测到了接收数据校验结果失败,接收数据无效

l  帧错误是指接收到的数据没有一个有效的停止位,无法判定数据帧结束

l  终止条件是指RxDn接收到保持逻辑0状态持续长于一个数据帧的传输时间

 

2. 寄存器配置

1)配置管脚

 串行通信接口

 

串行通信接口

2)通过ULCONn寄存器设置帧格式,比如0x3代表8位数据位,1位奇偶校验位,1位停止位。

 串行通信接口

 

3)UCONn 设置串口为中断或轮询方式发送或接收数据

串行通信接口

 

4)UFCONn设置FIFO的长度,我们这里不使用FIFO,认定深度为1

 

5)UMCONn 流量控制寄存器

 

6)UTRSTATn 数据是否发送完毕或者是否接收到数据

串行通信接口

 

7)串口发送寄存器UTXHn 

将数据写入到这个寄存器,UART就会把他保存到缓冲区中,并自动发送

 

8)串口接收寄存器URXHn

uart收到数据的时候,会把数据保存到这个寄存器,直接读取就可以获得数据

 

9)波特率设置寄存器UBRDIVn和UFRACVALn,这两个寄存器如何初始化,按照如下规则:

串行通信接口

 

三、示例代码

 

/**********************************************************************

 * @brief      uart_init, Normal mode, No parity,One stopbit,8 data bits

 *             Buad-reate : 115200, clock srouce100Mhz

 * @param[in]  int (ms)

 * @return     None

 **********************************************************************/

void uart_init(void)

{

 

    /*UART2initialize*/

    GPA1.GPA1CON= (GPA1.GPA1CON & ~0xFF ) | (0x22); //GPA1_0:RX;GPA1_1:TX

 

    UART2.ULCON2= 0x3; //Normal mode, No parity,One stop bit,8 data bits

    UART2.UCON2 =0x5;  //Interrupt request or polling mode

 

 

    /*

     * Baud-rate 115200: src_clock:100Mhz

     * DIV_VAL = (100*10^6 / (115200*16) -1) =(54.3 - 1) = 53.3

     * UBRDIV2 = (Integer part of 53.3) = 53 = 0x35

     * UFRACVAL2 = 0.3*16 = 0x5

     * */

    UART2.UBRDIV2= 0x35;

    UART2.UFRACVAL2= 0x5;

}

 

void putc(const char data)

{

    /*判断发送缓冲区是否为空*/

    while(!(UART2.UTRSTAT2& 0X2));

    UART2.UTXH2 =data;

    /*在linux中换行符为\n,在windows中换行符为\n\r,此句意思是将\n换成\n\r */

    if (data =='\n')

           putc('\r');

}

void puts(const char  *pstr)

{

    while(*pstr!= '\0')

        putc(*pstr++);

}

 

unsigned char getchar()

{

    unsigned charc;

    /*判断接收缓冲区是否为满*/

    while(!(UART2.UTRSTAT2& 0X1));

    c =UART2.URXH2;

    return c;

}