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

📄 scc2692.c

📁 串行通信芯片SCC2692驱动源程序(C51)
💻 C
字号:
// SCC2692.C: DUART module
// Author:	Alex Duan
// Date:	2002-08-12
// Version:	1.0
///////////////////////////

//#include "DrvCom.h"
#include "SCC2692.h"

/*
*********************************************************************
*							CONSTANTS								*
*********************************************************************
*/
#define UBA		0xFFD0				// Uart Base Addr
#define MRA		XBYTE[UBA + 0x0]	// Mode Register A (MR1A, MR2A)
#define SRA		XBYTE[UBA + 0x1]	// Status Register A (SRA)
#define CSRA	XBYTE[UBA + 0x1]	// Clock Select Register A (CSRA)
#define BRG		XBYTE[UBA + 0x2]	// BRG Test 
#define CRA		XBYTE[UBA + 0x2]	// Command Register A (CRA)
#define RHRA	XBYTE[UBA + 0x3]	// Rx Holding Register A (RHRA) 
#define THRA	XBYTE[UBA + 0x3]	// Tx Holding Register A (THRA)
#define IPCR	XBYTE[UBA + 0x4]	// Input Port Change Register (IPCR)
#define ACR		XBYTE[UBA + 0x4]	// Aux. Control Register (ACR)
#define ISR		XBYTE[UBA + 0x5]	// Interrupt Status Register (ISR)(Read Only)
#define IMR		XBYTE[UBA + 0x5]	// Interrupt Mask Register (IMR)  (Write Only)
#define CTU		XBYTE[UBA + 0x6]	// Counter/Timer Upper Value (CTU)
#define CRUA	XBYTE[UBA + 0x6]	// C/T Upper Preset Value (CRUR)
#define CTL		XBYTE[UBA + 0x7]	// Counter/Timer Lower Value (CTL)
#define CTLR	XBYTE[UBA + 0x7]	// C/T Lower Preset Value (CTLR)
#define MRB		XBYTE[UBA + 0x8]	// Mode Register B (MR1B, MR2B)
#define SRB		XBYTE[UBA + 0x9]	// Status Register B (SRB)
#define CSRB	XBYTE[UBA + 0x9]	// Clock Select Register B (CSRB)
#define TEST	XBYTE[UBA + 0xA]	// 1X/16X Test
#define CRB		XBYTE[UBA + 0xA]	// Command Register B (CRB)
#define RHRB	XBYTE[UBA + 0xB]	// Rx Holding Register B (RHRB)
#define THRB	XBYTE[UBA + 0xB]	// Tx Holding Register B (THRB)
#define INPORT	XBYTE[UBA + 0xC]	// Input Ports IP0 to IP6
#define OPCR	XBYTE[UBA + 0xC]	// Output Port Conf. Register (OPCR)
#define STARTC	XBYTE[UBA + 0xE]	// Start Counter Command
#define SETOP	XBYTE[UBA + 0xE]	// Set Output Port Bits Command
#define STOPC	XBYTE[UBA + 0xF]	// Stop Counter Command
#define RESETOP	XBYTE[UBA + 0xF]	// Reset Output Port Bits Command

#define TX_INTA uISR & 0x01			// TxRDYA INT
#define RX_INTA	uISR & 0x02			// RxRDY/FFULLA INT
#define TX_INTB uISR & 0x10			// TxRDYB INT
#define RX_INTB uISR & 0x20			// RxRDY/FFULLB INT

#define RXA_BUF_SIZE	256			// UartA rx buffer size
#define TXA_BUF_SIZE	256			// UartA tx buffer size
#define RXB_BUF_SIZE	256			// UartB rx buffer size
#define TXB_BUF_SIZE	256			// UartB tx buffer size

/*
*********************************************************************
*						STATIC GLOBAL VARIABLES						*
*********************************************************************
*/
static BYTE xdata rxaBuf[RXA_BUF_SIZE]; // UartA rx buffer
static BYTE xdata txaBuf[TXA_BUF_SIZE]; // UartA tx buffer
static BYTE xdata rxbBuf[RXB_BUF_SIZE]; // UartB rx buffer
static BYTE xdata txbBuf[TXB_BUF_SIZE]; // UartB tx buffer
static BYTE rxaStart;					// rxaBuf start index
static BYTE rxaStop;					// rxaBuf stop index
static BYTE txaStart;					// txaBuf start index
static BYTE txaStop;					// txaBuf stop index
static BYTE rxbStart;					// rxbBuf start index
static BYTE rxbStop;					// rxbBuf stop index
static BYTE txbStart;					// txbBuf start index
static BYTE txbStop;					// txbBuf stop index
static BOOL	 bRxaLost;					// Lost one buffer data
static BOOL	 bRxbLost;					// Lost one buffer data
static BYTE rwIMR;						// Use this variable only because the IMR are write only
// variables
static WORD code m_arBaud[]=//ACR.7=0
{
	50,
	110,
	135,
	200,
	300,
	600,
	1200,
	1050,
	2400,
	4800,
	7200,
	9600,
	38400,
	0
};

// Set Baud rate
BOOL uart_SetBaud(BYTE uPort, WORD uBaud)
{
	BYTE i;
	BOOL bRes = FALSE;
	if(uBaud==19200)
	{
		ACR  = 0xC0;
		i	 = 0x0C;
		bRes = TRUE;
	}
	else
	{
		ACR = 0x40;
		for(i=0; m_arBaud[i]!=0; i++)
		{
			if(m_arBaud[i]==uBaud)
			{
				bRes = TRUE;
				break;
			}
		}
	}
	if(bRes)
	{
		if(uPort==0)
			CSRA = i | i<<4;	// make send baud = receive baud
		else 
			CSRB = i | i<<4;
	}
	return bRes;
}

// inialize
void uart_Init()
{
	rxaStart=rxaStop=txaStart=txaStop=0;
	rxbStart=rxbStop=txbStart=txbStop=0;
	bRxaLost=bRxbLost=FALSE;

	CRA	 = 0x10;	// Reset MR pointer.
	CRB	 = 0x10;	// 

	MRA  = 0x13;	// 8 bit data, no parity
	MRB  = 0x13;	//
	MRA  = 0x07;	// normal, 1 stop bit
	MRB  = 0x07; 	//
	CSRA = 0xBB;	// 9600 baud rate
	CSRB = 0xBB;	//
	ACR  = 0x40;	// External timer, reset delta brk
	OPCR = 0x00;	// Output Port normal
	SETOP= 0xFF;	// Output all zeros
	CRA  = 0x2A;	// Reset Rx, disable Tx & Rx
	CRB  = 0x2A;	//
	CRA  = 0x3A;	// Reset Tx, disable Tx & Rx
	CRB  = 0x3A;	//
	CRA	 = 0x05;	// Enable Tx & Rx
	CRB  = 0x05;	//
	IMR	 = 0x22;	// Use TxRDYA/B, RxRDYA/B Interrupt
	rwIMR= 0x22;	// IMR's read/write backup
	IT0	 = 0;		// 
	EX0	 = 1;		// INT0 Enable
}

// set data format
void uart_SetFormat(BYTE uPort, WORD uBaud, BYTE uDataLen, BYTE uParity, BYTE uStopLen)
{
	BYTE uByte;
	// Data bit length
	if(uDataLen>8)uDataLen=8;
	uByte = uDataLen - 5;
	// parity
	switch(uParity)
	{
	case 0:	// no parity
		uByte |= 0x10;
		break;
	case 1:	// odd parity
		uByte |= 0x04;
		break;
	case 2:	// even parity
		break;
	}
	if(uPort==0)// A
	{
		CRA = 0x10;	// reset MR pointer
		MRA = uByte;
		if(uStopLen==1)
			MRA = 0x07;
		else if(uStopLen==2)
			MRA = 0x0F;
		else
			MRA = 0x08;
	}
	else
	{
		CRB = 0x10;	// reset MR pointer
		MRB = uByte;
		if(uStopLen==1)
			MRB = 0x07;
		else if(uStopLen==2)
			MRB = 0x0F;
		else
			MRB = 0x08;
	}
	uart_SetBaud(uPort, uBaud);
}

/*
// get status and reset error status
BYTE uart_GetStatus(BYTE uPort)
{
	BYTE uRes;
	if(uPort==0)
	{
		uRes = SRA;
		CRA  = 0x45;	// reset error status
		bTxaLost=bRxaLost=FALSE;
		return uRes;
	}
	else
	{
		uRes = SRB;
		CRB	 = 0x45;	// reset error status
		bTxbLost=bRxbLost=FALSE;
		return uRes;
	}
}
*/

void uart_int(void) interrupt 0
{
	BYTE uISR;
	EX0  = 0;
	uISR = ISR;
	if(RX_INTA)
	{
		rxaBuf[rxaStop++] = RHRA;
		if(rxaStop >= RXA_BUF_SIZE)rxaStop=0;
		if(rxaStop==rxaStart)bRxaLost = TRUE;
	}
	if(TX_INTA)
	{
		if(txaStart!=txaStop)
		{
			THRA = txaBuf[txaStart++];
			if(txaStart >= TXA_BUF_SIZE)txaStart=0;
		}
		else
		{
			rwIMR &= 0xFE;
			IMR = rwIMR;
		}
	}
	if(RX_INTB)
	{
		rxbBuf[rxbStop++] = RHRB;
		if(rxbStop >= RXB_BUF_SIZE)rxbStop=0;
		if(rxbStop==rxbStart)bRxbLost = TRUE;
	}
	if(TX_INTB)
	{
		if(txbStart!=txbStop)
		{
			THRB = txbBuf[txbStart++];
			if(txbStart >= TXB_BUF_SIZE)txbStart=0;
		}
		else
		{
			rwIMR &= 0xEF;
			IMR = rwIMR;
		}
	}
	EX0 = 1;
}

/*
*************************************************
* Description:	Get one byte from uart			*
* Arguments:	uPort: (0: uart A,1: uart B)	*
				pByte: address of returned byte	*
* Returns:		TRUE: Successful, FALSE: Failed	*
*************************************************
*/
BOOL uart_GetByte(BYTE uPort, BYTE *pByte)
{
	BOOL bRes = FALSE;
	if(uPort==0)
	{
		if(rxaStart!=rxaStop)
		{
			*pByte = rxaBuf[rxaStart++];
			if(rxaStart >= RXA_BUF_SIZE)rxaStart=0;
			bRes = TRUE;
		}
	}
	else
	{
		if(rxbStart!=rxbStop)
		{
			*pByte = rxbBuf[rxbStart++];
			if(rxbStart >= RXB_BUF_SIZE)rxbStart=0;
			bRes = TRUE;
		}
	}
	return bRes;
}

/*
*************************************************
* Description:	Send one byte					*
* Arguments:	uPort: (0: uart A,1: uart B)	*
				uByte: Byteto been sent			*
* Returns:		none							*
*************************************************
*/
void uart_SendByte(BYTE uPort, BYTE uByte)
{
	BYTE uTmp;
	if(uPort==0)
	{
		uTmp = txaStop + 1;
		if(uTmp >= TXA_BUF_SIZE)uTmp = 0;
		while(uTmp==txaStart); // waiting...

		txaBuf[txaStop] = uByte;
		txaStop = uTmp;
		if(!(rwIMR & 0x01))
		{
			rwIMR |= 0x01;
			IMR = rwIMR;
		}
	}
	else
	{
		uTmp = txbStop + 1;
		if(uTmp >= TXB_BUF_SIZE)uTmp = 0;
		while(uTmp==txbStart); // waiting...

		txbBuf[txbStop] = uByte;
		txbStop = uTmp;
		if(!(rwIMR & 0x10))
		{
			rwIMR |= 0x10;
			IMR = rwIMR;
		}
	}
}

⌨️ 快捷键说明

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