ARM之S5pv210串口通信初始化

一、串口通信的基础

    1、串口通信(UART)的全称是:Universal Asynchronous Receiver /Transmitter(通用异步接收和发送)

    2、异步通信和同步通信:

        (1)、异步通信:

                        发送方和接收方是工作在两个不同的时钟频率上的,也就是接收方有自己工作时的时钟频率,发

                        送方也有自己的工作的时钟频率。

                        在发送数据的时候,所发送的字符的时间间隔是可以任意的。因为它是按照字符为单位进行发送

                        的,每一个字符都有一个起始位,结束时有一个结束标志位。因此,接收方就知道什么时候开始

                        接收信息,什么时候接收完信息了。

         (2)、同步通信:

                        通信双方必须工作在同一个时钟频率上。所以发送方在通信前就要发送一个时钟信号给接收方,让

                        接收方调整自己的时钟频率,来让双方通信频率一致。

                        通信数据必须连续发送,中间不能有间隔。如果中间没有信息发送,就用空字符来填充。这样就可

                        以快速地发送多个数据。

    3、电平信号

            TTL:用在UART和一些单片机上+5v表示1,0v表示0。

            RS232:用在电脑上+15v到-3v表示1,3v到15v表示0。

            差分信号:有两根信号线,两个信号线上的信号振幅相同,相位相反。抗干扰性强:噪声信号在两条线上的

            差值为零。

    4、串行接口和并行接口

            串行接口:一条数据线加一条地线(或者两条数据线加一条地线:一条接收,一条发送),数据在数据线上

            是一位一位的传输过去的,这就是串行传输。

            并行接口:8条数据线,数据在每一条数据线也是一位一位传输的,8条数据线和一条地线,一次就可以传8

            位。

     5、全双工通信

            全双工通信:可以同时接收和发送数据

            半双工通信:可以接收或者发送数据,但是同一时间内只能接收或者发送

            单工通信:只能接收或者只能发送数据

    6、波特率和起始位,数据位,奇偶校验位和停止位

            我们的一个通信单元就是:起始位+数据位+奇偶校验位+停止位

            起始位:告诉对方开始通信。

            数据位:要传输的数据(5-8位可选)。

            奇偶校验位:查看数据是否出错。

            停止位:告诉对方一个通信单元接收。

二、S5pv210串口通信的具体介绍

  1、  我们可以看到S5pv210中有四个UART接口:ch0,ch1,ch2,ch3.四个接口都支持红外接收和DMA或者中断控制

        ch0有256个字节的FIFO,ch1有64个字节,ch2和ch3有16个字节。

        还支持自动流控,和握手发送或者接收功能。

   2、 S5pv210的串口工作流程简介

        

        发送数据:

                在FIFO模式下,把我们的要发送的数据放在发送缓存寄存器上,发送缓存寄存器就会自动把一个字节

            的数据复制到发送移位器上,开始发送的时候,发送移位寄存器就会自动把一位数据放到发送数据线上,

            当发送完之后发送缓存寄存器再给一字节数据给发送移位器,直到发送缓存寄存器的数据发送完了,这时

            候我们只需要发送缓存寄存器放数据,它就又开始工作了。

        接收数据:

                在FIFO模式下,开始接收的时候,接收移位器就会自动地从接收数据线上一位一位数据地接收,当接收

            移位寄存器接满了一个字节的时候,接收缓存寄存器就会复制这一字节的数据到接收缓存寄存器上,然后接

            收移位器继续接收数据,直到装满了整个接受缓存寄存器,这时候我们只需要取走接收缓存寄存器内的数据

            它就又开始工作了。

        总结:发送数据只需要向发送缓存寄存器上丢数据就可以了,接收数据,就读取接收缓存寄存器就可以了。

                  FIFO和NON-FIFO模式的区别:FIFO模式下整个缓存寄存器都可以使用。

                  NON-FIFO模式:只可以使用缓存寄存器的一个字节,这时候cpu必须时刻看着缓存寄存器才不会遗漏数据。      

    3、S5pv210的串口中断,DMA模式和红外线模式简介

        (1)、串口中断模式,也就是什么情况下会触发中断

     

        FIFO模式下:

            接收数据:Rx FIFO内的数据多于你设置的那个水平的时候(可以不是满的,也就是设置快满的时候)

                            超时(超过发三个字符的时间就算超时,不过你也可以自己设置超时的时间)

            发送数据:Tx FIFO内的数据少于你设置的那个水平的时候(可以不是全空,也就是快空的时候)

                             错误:有4种

        NON-FIFO模式:

            接收数据:满的时候;

            发送数据:空的时候(因为它只有一个字节)

        DMA模式:

            DMA(直接内存存储)其实就是一大块内存,和FIFO的功能一样,不过FIFO的内存空间大很多。你把数据

            放在DMA上,它就可以代替CPU,当FIFO空的时候,就向FIFO放数据。

        红外线模式:

             开启红外线模式,我们只需要向串口写数据,这些数据就会以红外线的方式传输信息给对方。

    4、S5pv210的串口时钟简介

      

    时钟来源是PCLK_PSYS:66.7MHZ,也可以在clock controller那里设置为SCLK_UART。然后经过UBDIV和UDIVSLOT

    分频,得到最终的UCLK时钟。

              

    计算方式:这里我们设置波特率为115200

            DIV_VAL=(66.7MHZ/(115200*16))- 1 = 36.08-1=35.19

    然后:UBRDIVn = 35  x/16 = 0.19 得 x = 3.04

       

    然后查询上表可知UDIVSLOTn = 0x0888;

    5、查询原理图,看串口接在哪个GPIO上

     

    上图可知:我们的串口接在了GPA0_0和GPA0_1处(我们的代码只是设置了UART0)

    6、设置GPIO为UART模式

    

    只要往GPA0CON[0]和GPA0CON[1]写0x2就可以了,选择0010

    7、UCON0:选择DMA模式,中断模式/轮询模式,红外线模式;选择时钟源。我们设置的值是0x5,选择

        中断或者轮询模式

        (1)、ULCON0:设置数据位长度,停止位,奇偶校验位,正常模式/红外模式。我们设置的值是0x3

            

            (2)、选择DMA模式,中断模式/轮询模式,红外线模式;选择时钟源。我们设置的值是0x5,选择

                中断或者轮询模式。

            

        (3)、UFCON:选择FIFO模式的,我们设置的值是0,不使用FIFO模式

        (4)、UMCON:选择中断模式,自动流控,FIFO中断水平这些的,我们设置为0,不使用中断,使用轮询方式。

        (5)、UTRSTAT0:通过查看这个寄存器,我们可以知道接收是否接收完和发送是否发送完的,如果第一位是1表

                示已经接收完,第二位是1表示已经发送完。

        (6)、UTXH0:发送缓存寄存器,要发送什么数据,就往这个寄存器写值就可以了。

        (7)、URXH0:接收缓存寄存器,读取这个寄存器,就可以接收到别人通过串口发过来的信息了。

三、完整代码

#define    GPA0CON        0xE0200000
#define ULCON0         0xE2900000
#define UCON0         0xE2900004
#define UFCON0         0xE2900008
#define UMCON0         0xE290000C
#define UBRDIV0     0xE2900028
#define UDIVSLOT0    0xE290002C
#define UTRSTAT0    0xE2900010
#define UTXH0        0xE2900020
#define URXH0        0xE2900024

#define rGPAOCON        (*(volatile unsigned int *)GPA0CON)
#define rULCON0            (*(volatile unsigned int *)ULCON0)
#define rUCON0            (*(volatile unsigned int *)UCON0)
#define rUFCON0            (*(volatile unsigned int *)UFCON0)
#define rUMCON0            (*(volatile unsigned int *)UMCON0)
#define rUBRDIV0        (*(volatile unsigned int *)UBRDIV0)
#define rUDIVSLOT0        (*(volatile unsigned int *)UDIVSLOT0)
#define rUTRSTAT0        (*(volatile unsigned int *)UTRSTAT0)
#define rUTXH0            (*(volatile unsigned int *)UTXH0)
#define rURXH0            (*(volatile unsigned int *)URXH0)

void uart_init(void)
{
    //第一步:首先就是设置GPA0,设置这里是为了打开端口,只有打开端口,信息才会发送出去嘛
    //写上左移还是比较好的,虽然这次只是第一位开始:0~7
    //位操作就是先把那几位清零,然后赋值就ok了
    rGPAOCON &= (~(0xff<<0));            //这里少了一个分号,导致了30行出了错误
    rGPAOCON |= 0x00000022;            //这里不可以写成这样:0b00100010bit[3:0] = 0b0010 bit[7:4] = 0b0010
    
    //第二步:设置关键的寄存器,这些都是在数据手册中看的,在笔记中有。
    //这里是初始化UART控制器
    rULCON0 = 0x3;
    rUCON0 = 0x5;
    rUFCON0 = 0;
    rUMCON0 = 0;
    
    //第三步:设置波特率,计算波特率
    //这里的那个频率可以取66.7MHz,也是可以取66MHz
    //DIV_VAL = (PCLK / (bps x 16)) ?1
    //DIV_VAL = (66000000 / (115200 x 16)) - 1            算出来是34,余数是0.80729
    //rUBRDIV0 = 34;
    //(num of 1's in UDIVSLOTn)/16 = 0.7            0.8 可以算出是12.8
    //rUDIVSLOT0 = 0xdfdd;
    //当是66700000时候,算出来就是35.1870            0.2算出来是3,之后在下面查表,就看到相应的值了
    //这样就初始化串口了
    rUBRDIV0 = 34;
    rUDIVSLOT0 = 0xdfdd;    
}

//发送一个字节
void uart_putc(char c)
{
    //发送字符的时候,要注意CPU比发送缓存区的速度要快很多的,所以我们要看发送缓存区是否已经发送完数据了
    //之后再给数据它
    //我们这里0就是非空,1就是空了,所以要等1的时候才跳出循环,而要跳出循环需要是0的时候才可以,所以
    //加上了!
    while(!(rUTRSTAT0 & (1<<1)));            //!是逻辑运算符,如果是真(非0)就变为假(0)
    rUTXH0 = c;
    
}

//接收一个字节
char uart_getc(void)
{
    //只是接收一个字节
    while(!(rUTRSTAT0 & (1<<0)));
    
    return (rURXH0 & 0xff);        //接收寄存器中只有八位是有效的,其他的都是无效的,所以在这里位与清零
                                    
}
欢迎各位指出不足之处







猜你喜欢

转载自blog.csdn.net/qq_41003024/article/details/80312780