DSP

串行通信接口

2019-07-13 18:37发布

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中换行符为 ,在windows中换行符为 ,此句意思是将 换成 */     if (data ==' ')            putc(' '); } void puts(const char  *pstr) {     while(*pstr!= '