⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sc16c554.c

📁 Philips SC16C554串口使用基本协议
💻 C
字号:
/***********************************************************************************************
MCU780058与SC16C554的硬件接线:

         SC16c554                     MCU(NEC 780058Y)
Pin         RESET               <----------P126     
Pin         CSD~CSA         <----------P47~P44 (4 Pins)
Pin         ADDR2~ADDR0 <----------P43~P41 (3 Pins) 

Pin         DATA0~DATA7  <--------->P30~P37 (8 Pins)

Pin         IOR                   <----------P125
Pin         IOW                  <----------P124

Pin         RXRDY              ----------->P123
Pin         TXRDY              ----------->P122

Pin         INTA~INTD        ---------->P01~P04 (4 Pins: external interrupt)      


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

#define __SC16C554__
#ifdef __SC16C554__
#pragma  SFR
#pragma  DI
#pragma  EI
#pragma  NOP



#include  <System\Stdtype.h>
#include  <System\Sub.h>


#if 0
#include <Lcd\DispSpec.h>
#include <Lcd\Lcddrv.h>
#include <Lcd\Display.h>
#endif

#include <Sc16c554.h>


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

                                      静态函数声明

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





  

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

                                      变量定义

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


/*C554的COM口地址数组*/
#define C554_COM_AMOUNT 4
const Byte acC554Com[C554_COM_AMOUNT] = 
{
  COM_A_ENABLE,
  COM_B_ENABLE,
  COM_C_ENABLE,
  COM_D_ENABLE
};

#if 0

#if(DEBUG !=DEBUG_CB900F)
/*C554的四个COM口的接收缓冲,利用FIFO模式对缓冲进行读写操作*/
#define C554_REC_BUFFER_SIZE 18
Byte acC554RecCnt[C554_COM_AMOUNT];  /*用于计算缓冲里未读取的数据的总量*/
Byte acC554RecTop[C554_COM_AMOUNT];  /*当从缓冲取走一个数据时,Top往下移一位*/
Byte acC554RecBtm[C554_COM_AMOUNT];  /*当写入一个数据到缓冲时,Btm往下移一位*/
Byte acC554RecBuf[C554_COM_AMOUNT][C554_REC_BUFFER_SIZE];  /*Buffer*/
#endif

/*C554的发送缓冲,当cAmount不为0时,表示Buffer中有数据需要发送,每发送一个字节,
  cTop会往下移一位。当往Buffer写数据时,cBtm会往下移*/
#define C554_TRAN_FIFO_SIZE 16
#define C554_TBUF_SIZE  28
struct {    /*SC16c554 transmit FIFO buffer*/
  Byte acBuf[C554_TBUF_SIZE];
  Byte cTop;
  Byte cBtm;
  Byte cAmount;
}sC554TranPack;

#if (DEBUG == DEBUG_CB900F)
#define RESENT_PORT  PORT_C
Byte C554ResentBuf[20];
Byte  C554ResentCnt;
#endif

#endif

/***********************************************************************************************
函数:C554RegInit

作者:Qiang

时间:2005,5

描述:初始化SC16C554四个COM寄存器

使用:
***********************************************************************************************/
public void C554RegInit(void)
{

  Byte i;

  /*清除发送缓冲*/
//  C554TBufRst();
  P5.6 = 1;
  /*初始化寄存器,从COMA到COMD*/
  for(i=PORT_A;i<C554_COM_AMOUNT;i++)
  {
    
    /*写LCR = 0xBF*/ 
    C554ByteWr(acC554Com[i], C554_LCR,C554_LCR_MD2_INIT);

    C554ByteWr(acC554Com[i], C554_EFR,C554_EFR_INIT);

    /*写LCR[7] = 1*/ 
    C554ByteWr(acC554Com[i], C554_LCR,C554_LCR_MD1_INIT);

    C554ByteWr(acC554Com[i], C554_DLL, C554_DLL_INIT);

    C554ByteWr(acC554Com[i], C554_DLM, C554_DLM_INIT);

    /*写LCR[7] = 0*/ 
    C554ByteWr(acC554Com[i], C554_LCR,C554_LCR_MD0_INIT);

    C554ByteWr(acC554Com[i], C554_IER,C554_IER_INIT);

    C554ByteWr(acC554Com[i], C554_FCR,C554_FCR_INIT);

    C554ByteWr(acC554Com[i], C554_MCR,C554_MCR_INIT);

    C554ByteWr(acC554Com[i], C554_SPR,C554_SPR_INIT);

  }
}


#if 0
/***********************************************************************************************
函数:ComDataSent

变量:无

返回:还待传送的字节数量

作者:Qiang

时间:2005,5

描述:发送Buffer数据到CB900F

使用:必需先设定要发送的COM口(eCurrPortID)
***********************************************************************************************/
public Byte ComDataSent(Byte cPort)
{
  register Byte i;
  register Byte cTmp;

  /*当C554的Transmit FIFO为空时,写数据到Transmit FIFO中,进而发送至CB900F中*/
  DI();
  cTmp = C554ByteRd(acC554Com[eCurrPortID],C554_LSR);
  EI();
  if((cTmp&LSR_TRANSMIT_EMPTY)==LSR_TRANSMIT_EMPTY)
  {
    if(sC554TranPack.cAmount>=C554_TRAN_FIFO_SIZE)
    {
      sC554TranPack.cAmount-=C554_TRAN_FIFO_SIZE;
      cTmp = C554_TRAN_FIFO_SIZE;
    }else
    {
      cTmp = sC554TranPack.cAmount;
      sC554TranPack.cAmount = 0;
    }
    DI();	
    for(i=0;i<cTmp;i++)
    {
      C554ByteWr(acC554Com[eCurrPortID],
                C554_THR,sC554TranPack.acBuf[sC554TranPack.cTop]);
#if(DEBUG ==  DEBUG_CB900F)
      C554ByteWr(acC554Com[PORT_C],
                C554_THR,sC554TranPack.acBuf[sC554TranPack.cTop]);
#endif
      if(++sC554TranPack.cTop>=C554_TBUF_SIZE)
      {
        sC554TranPack.cTop = 0;
      }
    }
	
    EI();	
  }
  return sC554TranPack.cAmount;
}


/***********************************************************************************************
函数:ComDataReceive

作者:Qiang

时间:2005,5

描述:SC16C554四个RS232数据接收程序。

使用:用于定时器中断中,每2ms检查SC16C554是否收到CB900F发送过来的数据
***********************************************************************************************/
void ComDataReceive(void)
{
#if 1
  register Byte cTmp;	

  /*读取COM A*/
  while(C554_INTA)
  {
    cTmp = C554ByteRd(COM_A_ENABLE,C554_LSR);
    /*有错误,打上ERROR标志(cC554RecErr)*/
    if((cTmp&LSR_DATA_ERROR)==LSR_DATA_ERROR)
    {
        cC554RecErr |= ERR_PORT_A;
    }
    /*存放数据,更新数据计数器及BUFFER队列指针*/ 
    acC554RecBuf[PORT_A][acC554RecBtm[PORT_A]] = C554ByteRd(COM_A_ENABLE,C554_RHR);

#if(DEBUG == DEBUG_CB900F)
   C554ResentBuf[C554ResentCnt++]= acC554RecBuf[PORT_A][acC554RecBtm[PORT_A]];
#endif

    acC554RecCnt[PORT_A]++;
    if(++acC554RecBtm[PORT_A]>=C554_REC_BUFFER_SIZE)
    {
      acC554RecBtm[PORT_A] = 0;
    }
  }
  /*读取COM B*/
  while(C554_INTB)
  {
    cTmp = C554ByteRd(COM_B_ENABLE,C554_LSR);
    /*有错误,打上ERROR标志(cC554RecErr)*/
    if((cTmp&LSR_DATA_ERROR)==LSR_DATA_ERROR)
    {
        cC554RecErr |= ERR_PORT_B;
    }
    /*存放数据,更新数据计数器及BUFFER队列指针*/ 
    acC554RecBuf[PORT_B][acC554RecBtm[PORT_B]] = C554ByteRd(COM_B_ENABLE,C554_RHR);
#if(DEBUG == DEBUG_CB900F)
   C554ResentBuf[C554ResentCnt++]= acC554RecBuf[PORT_B][acC554RecBtm[PORT_B]];
#endif                          
    acC554RecCnt[PORT_B]++;
    if(++acC554RecBtm[PORT_B]>=C554_REC_BUFFER_SIZE)
    {
      acC554RecBtm[PORT_B] = 0;
    }
  }
  /*读取COM C*/
  while(C554_INTC)
  {
    cTmp = C554ByteRd(COM_C_ENABLE,C554_LSR);
    /*有错误,打上ERROR标志(cC554RecErr)*/
    if((cTmp&LSR_DATA_ERROR)==LSR_DATA_ERROR)
    {
        cC554RecErr |= ERR_PORT_C;
    }
    /*存放数据,更新数据计数器及BUFFER队列指针*/ 
    acC554RecBuf[PORT_C][acC554RecBtm[PORT_C]] = C554ByteRd(COM_C_ENABLE,C554_RHR);

#if(DEBUG == DEBUG_CB900F)
   C554ResentBuf[C554ResentCnt++]= acC554RecBuf[PORT_C][acC554RecBtm[PORT_C]];
#endif                          

    acC554RecCnt[PORT_C]++;
    if(++acC554RecBtm[PORT_C]>=C554_REC_BUFFER_SIZE)
    {
      acC554RecBtm[PORT_C] = 0;
    }
  }
  /*读取COM D*/
  while(C554_INTD)
  {
    cTmp = C554ByteRd(COM_D_ENABLE,C554_LSR);
    /*有错误,打上ERROR标志(cC554RecErr)*/
    if((cTmp&LSR_DATA_ERROR)==LSR_DATA_ERROR)
    {
        cC554RecErr |= ERR_PORT_D;
    }
    /*存放数据,更新数据计数器及BUFFER队列指针*/ 
    acC554RecBuf[PORT_D][acC554RecBtm[PORT_D]] = C554ByteRd(COM_D_ENABLE,C554_RHR);

#if(DEBUG == DEBUG_CB900F)
   C554ResentBuf[C554ResentCnt++]= acC554RecBuf[PORT_D][acC554RecBtm[PORT_D]];
#endif                          

    acC554RecCnt[PORT_D]++;
    if(++acC554RecBtm[PORT_D]>=C554_REC_BUFFER_SIZE)
    {
      acC554RecBtm[PORT_D] = 0;
    }
  }

#if(DEBUG == DEBUG_CB900F)
   for(cTmp=0;cTmp<C554ResentCnt;cTmp++) 
   {
      C554ByteWr(acC554Com[RESENT_PORT],
                C554_THR,C554ResentBuf[cTmp]);   
   }
   C554ResentCnt = 0;
#endif
#endif
}

#endif

/***********************************************************************************************
函数:C554RstEna

作者:Qiang

时间:2005,5

描述:使能SC16C554的Reset信号脚?
使用:用于初初化SC16C554
***********************************************************************************************/
public void C554RstEna(void)
{
  C554_RESET_ENA(); 
}



/***********************************************************************************************
函数:C554RstDis

作者:Qiang

时间:2005,5

描述:停止SC16C554的Reset信号

使用:用于初初化SC16C554
***********************************************************************************************/
public void C554RstDis(void)
{
  C554_RESET_DIS(); 
}



/***********************************************************************************************
函数:C554ByteWr

变量:cCom -> COM口选择;cRegister -> 写入的寄存器;cData -> 写入的数据

返回:无

作者:Qiang

时间:2005,5

描述:MCU向SC16C554发送一字节数据

使用:MCU与CB900F的硬件层通信程序
***********************************************************************************************/
public void C554ByteWr(Byte cCom, Byte cRegister,Byte cData)
{
  DI();
  C554_SELECT_PEND &= 0x01; 
  C554_SELECT_PEND =C554_SELECT_PEND|cCom|cRegister;
  C554_DATA_BUS = cData;
  C554_WRITE_VALID;
  NOP();
  C554_WRITE_INVALID;
  C554_SELECT_PEND &=0x01; 
  EI();
}


/***********************************************************************************************
函数:C554ByteRd

变量:cCom -> COM口选择;cRegister -> 读取的寄存器

返回:cVal -> 寄存器的值

作者:Qiang

时间:2005,5

描述:MCU接收SC16C554送回来的一字节数据

使用:MCU与CB900F的硬件层通信程序
***********************************************************************************************/
public Byte C554ByteRd(Byte cCom,Byte cRegister)
{
  Byte cVal;

  DI();
  C554_INPUT_MODE();
  C554_SELECT_PEND &= 0x01;
  C554_SELECT_PEND =C554_SELECT_PEND|cCom|cRegister;
  C554_READ_VALID;
  cVal = C554_DATA_BUS;
  C554_READ_INVALID;
  C554_SELECT_PEND &=0x01;  // reset
  C554_OUTPUT_MODE();
  EI();
  return cVal;
}


/***********************************************************************************************
函数:SentOneData

作者:Qiang

时间:2005,5

描述:检查接收的数据是否有错。 1: has errors 0: none errors

使用:
***********************************************************************************************/
public void SentOneData(Byte cPort, Byte cData)
{
  C554ByteWr(acC554Com[cPort],C554_THR,cData);
}





/***********************************************************************************************
函数:ReceiveDataErrorCheck

作者:Qiang

时间:2005,5

描述:检查接收的数据是否有错。 1: has errors 0: none errors

使用:
***********************************************************************************************/
public Byte ReceiveDataErrorCheck(Byte cPort)
{
  register Byte cTmp;
  cTmp = C554ByteRd(acC554Com[cPort],C554_LSR);
  /*有错误,打上ERROR标志(cC554RecErr)*/
  if((cTmp&LSR_DATA_ERROR)==LSR_DATA_ERROR)
  {
     return 1;
  }

  return 0;
}


/***********************************************************************************************
函数:TransmitBufferEmptyCheck

作者:Qiang

时间:2005,5

描述:检查接收的数据是否有错。 1: empty 0: no empty

使用:
***********************************************************************************************/
public Byte TransmitBufferEmptyCheck(Byte cPort)
{
  register Byte cTmp;
  
  cTmp = C554ByteRd(acC554Com[cPort],C554_LSR);
  if((cTmp&LSR_TRANSMIT_EMPTY)==LSR_TRANSMIT_EMPTY)
  {
    return 1;
  }

  return 0;
}


#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -