嵌入式系统设计与实践:Linux篇
上QQ阅读APP看书,第一时间看更新

4.4 异步串行口

S3C2410自带3个异步串行口控制器,每个控制器有16个字节的FIFO,最大波特率115.2Kbit/s, UART行控制寄存器ULCONn、控制数寄存器UCONn、读写状态寄存器UTRSTAT、FIFO控制寄存器UFCONn、UART MODEM控制寄存器UMCONn、读写状态寄存器UTRSTATn、FIFO状态寄存器UFSTATn、波特率分频寄存器UBRDIVn。

(1)端口H控制寄存器功能如表4.19所示,端口H控制寄存器共有引脚21个,0~20脚,每2个位控制1个引脚。如果控制位为00时引脚为输入,控制位为01时引脚为输出,控制位为10时引脚为特殊功能,控制位为11时引脚为保留功能。

表4.19 端口H控制寄存器及功能

(2)端口上拉寄存器(GPBUP-GPHUP)

0接上拉电阻,1不接上拉电阻

(3)S3C2410中UART行控制寄存器ULCONn如表4.20所示。

表4.20 UART行控制寄存器VLCONn

(4)S3C2410中FIFO控制寄存器UFCONn如表4.21所示。

表4.21 FIFO控制寄存器UFCONn

(5)S3C2410中UART MODED控制寄存器UMCONn如表4.22所示。

表4.22 UARTMODED控制寄存器UMCONn

S3C2410中每个UART的寄存器有11个之多(共有3个UART),考虑比较简单的情况,用到的寄存器也有8个。不过初始化就用去了5个寄存器,剩下的3个用于接收、发送数据。下面应用实例说明串行通信的应用。

例1:假设在数据传送中设置传送8个数据位,1个停止位,无校验,正常操作模式,发送、接收都使用中断或查询方式,请根据实际需求设置异步通信寄存器,实际操作过程如下:

(1)初始化

① 把使用到的引脚GPH2、GPH3定义为TXD0、RXD0。

      GPHCON |= 0xa0   //10100000
      GPHUP  |= 0x0c   //上拉

② 设置ULCON0

如把ULCON0(UART channel 0 line control register)设定为:8个数据位,1个停止位,无校验,正常操作模式(与之相对的是Infra-Red Mode,此模式表示0、1的方式比较特殊)。则ULCON0值为0x03。

③ 设置UCON0

如把UCON0设定为除了位[3:0],其他位都使用默认值。位[3:0]=0b0101表示:发送、接收都使用“中断或查询方式”,则把UCON0值赋为0x05。

④ 设置UFCON0

如把UFCON0的功能设定为不使用FIFO,则设为默认值0。

⑤ 设置UMCON0

如果把UMCON0设定为不使用流控,则设为默认值0x00。

⑥ 设置UBRDIV0

UBRDIV0未使用PLL,采用PCLK=12MHz,设置波特率为57600Bd,则由公式:

      UBRDIVn = (int)(PCLK / (bps x 16))-1

可以计算得UBRDIV0 = 12,根据S3C2410数据手册的误差公式,验算此波特率是否在可容忍的误差范围之内,如果不在,则需要更换另一个波特率。经验算UBRDIV0可设为12。

(2)发送数据

① 设置UTRSTAT0

如果把UTRSTAT0功能设置如下:

位[2]:无数据发送时,自动设为1。当使用串口发送数据时,先读此位以判断是否有数据正在占用发送口。

位[1]:发送FIFO是否为空。

位[0]:接收缓冲区是否有数据,若有,此位设为1。实验中需要不断查询此位,判断是否有数据已经被接收。

② 给UTXH0寄存器赋值

实验中要把发送的数据写入UTXH0(UART channel 0 transmit buffer register )此寄存器。

(3)接收数据

① 根据位[0],先判断寄存器UTRSTAT0的缓冲区是否有数据。

② 当查询到UTRSTAT0位[0]=1时,读此寄存器获得串口接收到的数据。

串口数据传送的三个函数:init_uart、putc、getc分别表示串口初始化、发送数据与接收数据。

      void init_uart( ) //初始化UART
      {
          GPHCON|= 0xa0;      //GPH2, GPH3 used as TXD0, RXD0
          GPHUP  = 0x0c;      //GPH2, GPH3内部上拉
          ULCON0 = 0x03;      //8N1(8个数据位,无校验位,1个停止位)
          UCON0  = 0x05;      //查询方式
          UFCON0 = 0x00;       //不使用FIFO
          UMCON0 = 0x00;       //不使用流控
          UBRDIV0= 12;      //波特率为57600
      }
      void putc(unsigned char c)
      {
        while( ! (UTRSTAT0 & TXD0READY) ); //不断查询,直到可以发送数据
        UTXH0 = c;                        //发送数据
      }
      unsigned char getc( )
      {
        while( ! (UTRSTAT0 & RXD0READY) ); //不断查询,直到接收到了数据
        return URXH0;                     //返回接收到的数据
      }

4.5 IIC总线接口

IIC中有一条串行数据线(SDA),一条串行时钟线(SCL)。数据传送时,主机先发出开始S信号,然后发出8位数据,这8位数据中的前7位为从机的地址,第8位表示传输的方向(0表示写操作,1表示读操作)。在S3C2410中IIC总线控制寄存器有4个,分别是IICCON、IICSTAT、IICADD、IICDS。SDA线上的数据从IICDS寄存器发出(或传入IICDS); IICADD寄存器中保存S3C2410当作从机时的地址;IICCON、IICSTAT两个寄存器用来控制或标识各种状态,如选择工作模式、发出S或P信号、接收ACK信号、检测是否收到ACK信号。

(1)IICCON寄存器

IICCON寄存器各位功能及描述如表4.23所示。

表4.23 IICCON寄存器各位的功能描述

(2)IICSTAT寄存器

IICSTAT寄存器各位功能及描述如表4.24所示。

表4.24 IICSTAT寄存器各位的功能描述

(3)IICADD寄存器

[7:1]表示从机地址,当IICSTAT[4]为0时才可写入,在任何时间都可以读出。

(4)IICDS寄存器

[7:0]保存的是要发送或已经接收的数据,当IICSTAT[4]为1时,才可以写入,在任何时间都可读出。

例:分析下列函数IIC_init

      void IIC_init(void)
      {
        GPEUP |=0xc000 ;
      GPECON |=0xa0000000 ;

      INTMSK &= ~(BIT_IIC);
        IICCON=( 1<<7) | (0<<6) | (1<<5) |(0xf) ;
      IICADD = 0x10;   //S3C2410 slave address = [7:1]
      IICSTAT =0x10;
      }

分析:语句GPEUP |=0xc000;表示禁止内部上拉,语句GPECON |=0xa0000000;表示选择引脚GPE15到IICSDA, GPE14到IICSCL, Bit[7]=1,使能ACK, bit[6]=0, IICCLK=PCLK/16, bit[5]=1,使能中断,Bit[3:0]=0xf, Tx_clock=IICCLK/16,如PCLK=50MHz, IICCLK=3.125MHz, Tx_clock=0.195MHz, IIC串行输出使能Rx/Tx。