📄 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 + -