VPM642采用TL16C752B通用异步收发器UART,其上包含两路相互独立的异步收发器,接受和发送各带64字节FIFO,并且各自带有Modem接口信号,最高传输速率为1.5Mbps
        在VPM642中,TL16C752B(以下简称752B)与EMIFA之CE1相连。
        752B每个通道包含18个寄存器,通过地址A2~A0以及寄存器位对他们进行寻址。A,B两通道分别由片选信号选通。
 
A,B两通道所占地址范围如下:
  • UART A        0x 9008 0000 ~ 0x 9008 0007
  • UART B         0x 9008 0008 ~ 0x 9008 000F
此外752B还提供两个中断请求信号INTA,INTB分别用于通道A,B申请DM642中断,在VPM642中,INTA与INTB相与,复用DM642之 INT5
 
752B寄存器:
VPM642学习之串口通信_第1张图片
VPM642学习之串口通信_第2张图片
黑色部分为2次寻址。
 
下面在程序中定义这些寄存器:
#define SEEDDM642_UART_RBR                         0x00     // Read
#define SEEDDM642_UART_THR                         0x00     // Write
#define SEEDDM642_UART_IER                         0x01
#define SEEDDM642_UART_IIR                         0x02     // Read
#define SEEDDM642_UART_FCR                         0x02     // Write
#define SEEDDM642_UART_LCR                         0x03
#define SEEDDM642_UART_MCR                         0x04
#define SEEDDM642_UART_LSR                         0x05
#define SEEDDM642_UART_SCR                         0x07

#define SEEDDM642_UART_DLL                         0x08
#define SEEDDM642_UART_DLH                         0x09
#define SEEDDM642_UART_EFR                         0x0A
#define SEEDDM642_UART_XON1                        0x0C
#define SEEDDM642_UART_XON2                        0x0D
#define SEEDDM642_UART_XOFF1                     0x0E
#define SEEDDM642_UART_XOFF2                     0x0F

#define SEEDDM642_UART_TCR                         0x16
#define SEEDDM642_UART_TLR                         0x17
 
上述寄存器中比较重要的是:
  • 中断使能寄存器IER  
              VPM642学习之串口通信_第3张图片
 
 
  •    FIFO控制寄存器  FCR
VPM642学习之串口通信_第4张图片
 
  • 线路控制寄存器LCR
VPM642学习之串口通信_第5张图片
   
  • Modem控制寄存器 MCR
VPM642学习之串口通信_第6张图片
 
下面是初始化过程:
SEEDDM642_UART_Config UartConfig ={
        0x00, /*寄存器IER*/
        0x57, /*寄存器FCR*/
        0x03, /*寄存器LCR*/
        0x01, /*寄存器MCR*/
};
 
定义串口A句柄
SEEDDM642_UART_Handle SEEDuartHandleA;
 
打开串口
/* Open UART */
        SEEDuartHandleA = SEEDDM642_UART_open(SEEDDM642_UARTA,    
                             SEEDDM642_UART_BAUD9600,    
                             &UartConfig);
 
打开串口函数实现
SEEDDM642_UART_Handle SEEDDM642_UART_open(Int16 devid,    
                    Int16 baudrate,    
                    SEEDDM642_UART_Config *config)
{
        SEEDDM642_UART_Handle hUart;
        Int16 dl;
         /* Assign handle */
        hUart = devid;
        
         /* Set registers based on config structure */

         /*设置MCR*/
        SEEDDM642_UART_rset(hUart, SEEDDM642_UART_MCR,config -> regs[3]);

         /*将EFR寄存器的第4位关闭*/     //静止TL16C752B增强功能
        SEEDDM642_UART_rset(hUart, SEEDDM642_UART_EFR, dl);
        
         /*设置串口的MCR*/
        SEEDDM642_UART_rset(hUart, SEEDDM642_UART_MCR, config -> regs[3]);
        
         /*设置串口的IER*/     // 0X9008 0001 处置0    
        SEEDDM642_UART_rset(hUart, SEEDDM642_UART_IER, config -> regs[0]);
         /*设置串口的FCR*/
        SEEDDM642_UART_rset(hUart, SEEDDM642_UART_FCR, config -> regs[1]);    
         /*设置串口的LCR*/
        SEEDDM642_UART_rset(hUart, SEEDDM642_UART_LCR, config -> regs[2]);

         /* Set up baud divisor clock,设置波待率 */
        dl = SEEDDM642_UART_rget(hUart, SEEDDM642_UART_MCR);
         if((dl & 0x80)==0x80)
        {
          baudrate = (baudrate/4);    
        }
        SEEDDM642_UART_rset(hUart, SEEDDM642_UART_DLL, baudrate & 0xff);
        dl = SEEDDM642_UART_rget(hUart, SEEDDM642_UART_DLL);
        SEEDDM642_UART_rset(hUart, SEEDDM642_UART_DLH, (baudrate >> 8) & 0xff);
        dl = SEEDDM642_UART_rget(hUart, SEEDDM642_UART_DLH);
         /* Clear any outstanding receive characters,清空接收寄存器 */
        SEEDDM642_UART_rget(hUart, SEEDDM642_UART_RBR);
        
         return hUart;
}
 
 
串口读取:
Int16 SEEDDM642_UART_getChar(SEEDDM642_UART_Handle hUart)
{
        Int16 status;
        
         while(1)
        {
                status = SEEDDM642_UART_rget(hUart, SEEDDM642_UART_LSR);
                 if ((status & 1) != 0)     // DR
                         break;
        }
        
         return SEEDDM642_UART_rget(hUart, SEEDDM642_UART_RBR);
}
 
串口写入:
void SEEDDM642_UART_putChar(SEEDDM642_UART_Handle hUart, Uint16 data)
{
        Int16 status;
        
         while(1)
     {
                status = SEEDDM642_UART_rget(hUart, SEEDDM642_UART_LSR);
                 if ((status & 0x20) != 0)     // THRE
                         break;
        }
//        SEEDDM642_waitusec(3);        
        SEEDDM642_UART_rset(hUart, SEEDDM642_UART_THR, data);

}
 
设置752B寄存器:
void SEEDDM642_UART_rset(SEEDDM642_UART_Handle hUart,    
            Int16 regnum,    
            Int16 regval)
{
        Int16 regindex, lcr;
        
         /* Register index is determined by lower 3 bits and the target UART */
        
        regindex = regnum & 0x7;
         if (hUart == 1)
                regindex += 8;
         /*是否为高位的寄存器*/
         /* If regnum between 0x08 and 0x0F, set bit 7 of LCR to access register */
         if ((regnum & 0x18) == 0x8)
        {
                lcr = SEEDDM642_UART_rget(hUart, SEEDDM642_UART_LCR);
                SEEDDM642_waitusec(1);

     //将线路控制寄存器LCR最高位DLAB设置成1,表示访问大于 0x07的寄存器
                SEEDDM642_UART_rset(hUart, SEEDDM642_UART_LCR, lcr | 0x80);
                SEEDDM642_waitusec(1);

     //设置寄存器值
                SEEDDM642_rset(regindex, regval);
                SEEDDM642_waitusec(1);
                SEEDDM642_UART_rset(hUart, SEEDDM642_UART_LCR, lcr);
                SEEDDM642_waitusec(1);
        }
         else
        {
                
                SEEDDM642_rset(regindex, regval);
                SEEDDM642_waitusec(1);
        }
}
 
获得752B寄存器值:
Int16 SEEDDM642_UART_rget(SEEDDM642_UART_Handle hUart,    
             Int16 regnum)
{
        Int16 regindex, returnval, lcr;
        
         /* Register index is determined by lower 3 bits and the target UART */
        regindex = regnum & 0x7;
         if (hUart == 1)
                regindex += 8;
        
         /* If regnum between 0x08 and 0x0F, set bit 7 of LCR to access register */
         if ((regnum & 0x18) == 0x8)
        {
                lcr = SEEDDM642_UART_rget(hUart, SEEDDM642_UART_LCR);
                SEEDDM642_UART_rset(hUart, SEEDDM642_UART_LCR, lcr | 0x80);
                returnval = SEEDDM642_rget(regindex);
                SEEDDM642_UART_rset(hUart, SEEDDM642_UART_LCR, lcr);
        }
         else
        {
                returnval = SEEDDM642_rget(regindex);
        }
        
         return returnval;
}
 
 
DM642读写EMIFA
#define EVMDM642_FPGASDRAM_BASE    0x80000000

/* Read an 8-bit value from a CPLD register */
Uint8 SEEDDM642_rget(Int16 regnum)
{
        Uint8 *pdata;
        
         /* Return lower 8 bits of register */
        pdata = (Uint8 *)(SEEDDM642_CPLD_BASE + regnum);
         return (*pdata & 0xff);
}

/* Write an 8-bit value to a CPLD register */
void SEEDDM642_rset(Int16 regnum, Uint8 regval)
{
        Uint8 *pdata;
        
         /* Write lower 8 bits of register */
        pdata = (Uint8 *)(SEEDDM642_CPLD_BASE + regnum);
        *pdata = (regval & 0xff);
}